GitHub MCP server, the gh CLI, or GitLab MCP

With a shell, gh plus GitHub's agent skill covers most work. The MCP server ships 45 tools on by default.

If your agent has a shell and works inside a GitHub checkout, start with the gh CLI and GitHub’s official gh skill. Pick the GitHub MCP server when your client has no shell, or when you want read-only mode and toolset limits fixed in the server’s config. If your code lives on GitLab, look at zereight’s GitLab MCP, which also runs as a CLI.

Measured by agentmods, live: github-mcp-server, gh, gitlab-mcp
ModTypeStarsLast pushLicenceScanTokensWorks with
github-mcp-servergithub/github-mcp-serverMCP server34kyesterdayMITA—Claude Code, Codex, Cursor, Gemini CLI, OpenCode
ghcli/cliSkill47ktodayMITA32Claude Code, Codex
gitlab-mcpzereight/gitlab-mcpMCP server2.1ktodayMITA—Claude Code, Codex, Cursor, Gemini CLI, OpenCode

Install

npx agentmods add mcp/github/github-mcp-server/github-mcp-server
gh
npx agentmods add skills/cli/cli/gh
gitlab-mcp
npx agentmods add mcp/zereight/gitlab-mcp/gitlab-mcp

Each name opens the mod's page: the scan, the token cost and every other way to install it.

Do you need an MCP server for GitHub at all?

Often you don’t, and most of the GitHub MCP vs gh CLI choice comes down to what gh already does. gh is GitHub on the command line, and the cli/cli repository ships an agent skill “for driving gh from coding agents”. You install it with gh itself: gh skill install cli/cli gh --scope user.

Read as a page of usage patterns, the skill shows what gh already does for an agent. Without a terminal attached, gh skips the pager, strips colour and fails fast with a message instead of waiting at a prompt. --json gives structured output and --jq filters it without a separate jq. The repository comes from the git remotes of the current directory, so the agent doesn’t have to name it on every call. Anything the typed commands don’t expose goes through gh api, including arbitrary GraphQL.

It also names traps an agent would otherwise walk into. List commands stop at a default that “is usually 30” unless you pass -L. --author dependabot matches nothing, because bots author as GitHub Apps.

One MCP server makes the same argument about itself. zereight’s GitLab README calls Skill + CLI “an equal path, not a fallback”, with full payloads in a terminal and no MCP registration. In a terminal agent such as Claude Code or Codex, that makes the MCP server optional, worth adding when you want read-only mode or lockdown.

Hosted at api.githubcopilot.com, or run locally

GitHub hosts a remote server at https://api.githubcopilot.com/mcp/, and the README calls it the easiest way to start. Your client must support remote MCP servers. In Claude Code it is one command with a token: claude mcp add --transport http github https://api.githubcopilot.com/mcp -H "Authorization: Bearer YOUR_GITHUB_PAT". Its README lists a few tools for the remote server only, among them create_pull_request_with_copilot, which hands a task to the Copilot coding agent. For an IDE chat or a web app without a shell, this remote server is the shorter path.

Locally, the server is a Go program. You run it from the Docker image ghcr.io/github/github-mcp-server or build the binary with go build. On github.com it can log you in with OAuth on first use and keep the token in memory only; this applies to the stdio server. A GITHUB_PERSONAL_ACCESS_TOKEN takes precedence over OAuth.

GitHub Enterprise Server gets no remote server, so on GHES the local one, pointed at your host with --gh-host, is the only option. gh supports GitHub.com, Enterprise Cloud and supported Enterprise Server versions directly.

There is also an organisation policy, “MCP servers in Copilot”, that can block the GitHub MCP server, remote and local, in the Copilot editors it covers.

What runs in the background differs too. Telemetry in gh is on by default (the config value is enabled). GH_TELEMETRY (a false value such as 0 turns it off) and DO_NOT_TRACK=1 override the config. The code also switches it off when you seem to use GitHub Enterprise Server. The zereight server runs an update check at startup, which GITLAB_DISABLE_VERSION_CHECK=true disables. We found no comparable statement in the GitHub MCP server’s README.

Default tool lists and what they cost in context

With no toolsets named, the GitHub MCP server enables five toolsets (context, issues, pull_requests, repos and users). The README’s tool reference lists 45 tools under those five, and 93 across all 22 local toolsets. --toolsets all turns everything on. You can go the other way with --tools for single tools and --exclude-tools to drop some. The README says fewer toolsets help the model pick tools and “reduce the context size”.

On GitLab, zereight’s server starts at 40 tools, which are 38 in core plus discover_tools and help. It has 288 in total. Its README publishes its own measurement, dated 2026-11-05 and counted as bytes divided by four: about 11,736 tokens for the default list and 73,477 with GITLAB_TOOLSETS=all. The agent calls discover_tools to switch on a category for the session instead. Replies can shrink too. Pass jmespath on a tool call, or set GITLAB_MCP_COMPACT_RESULTS=true to get a preview plus a CLI command.

With gh there are no tool schemas at all, only the skill. The table above has our measurement for the gh skill; we don’t measure MCP server token use yet, so for the two servers the README figures are all there is.

Read-only, lockdown and GitLab’s permission modes

Start with --read-only on the GitHub MCP server. It wins over --tools, so a write tool you name explicitly is still skipped. On the remote server, /readonly at the end of a toolset URL does the same. With a classic PAT the server reads the token’s scopes at startup and hides tools it can’t use. Fine-grained PATs and GitHub App tokens skip that check and show every tool, and the API enforces the permissions when a call is made.

Lockdown mode targets prompt injection from public repositories. It checks whether the author of each issue, pull request or comment has push access, and refuses or filters the content when they don’t. Content from github-actions[bot] and copilot always passes, so CI output isn’t filtered. The README is clear that lockdown is “not an authorization boundary”. The credential can still read and write what it could before.

For GitLab, the default is GITLAB_PERMISSION_MODE=full. modify allows creates and updates but blocks deletes, so it is the setting to use if you don’t want the agent deleting anything. readonly replaces the deprecated GITLAB_READ_ONLY_MODE. You can lock it to project IDs, deny tool names by regex, require confirmation for named tools, and mask sensitive text in results. gitlab_api_request in the optional api toolset is the exception, since it bypasses the allowlists and other filters, and the README warns that “prompt injection can drive it”. It turns on only when you list api in GITLAB_TOOLSETS, not with all.

We found no such mode in gh, so the agent can do whatever its token allows. The way to narrow that is the token itself, and the login help suggests GH_TOKEN for fine-grained personal access tokens. gh auth login runs a browser flow and stores the token in the system credential store, falling back to a plain text file when no store is found.

zereight’s server and GitLab’s official one

GitLab ships an official MCP server inside GitLab, and zereight’s README points to it. Per that README and its comparison page, which reads GitLab’s docs as of 2026-10-21, the official server answers at https://<gitlab-host>/api/v4/mcp, has been on the Free tier since GitLab 19.2 and became generally available in 19.5. We did not read GitLab’s own code, so treat those details as zereight’s account. On a GitLab release that has the endpoint, and with an owner or admin willing to allow it, the official server is worth trying.

zereight’s package needs nothing switched on in GitLab, only a token. It runs on Node 20 or newer, installs from npm or Homebrew, speaks stdio, SSE and Streamable HTTP, and works with self-hosted instances. It is at version 2.3.22 at this commit, and like the other two projects it is MIT-licensed. For a shared team server there is remote authorization, where each caller sends their own token.

Questions

Does the GitHub MCP server work with GitHub Enterprise Server?

Only the local server. The hosted remote server does not support GitHub Enterprise Server, so you run the Docker image or the Go binary and point it at your host with --gh-host or GITHUB_HOST.

Is there an official GitLab MCP server?

Yes. According to zereight's comparison page (read from GitLab's docs on 2026-10-21), GitLab ships one inside GitLab at /api/v4/mcp, free since GitLab 19.2 and generally available in 19.5. zereight's server is a separate MIT package that needs nothing switched on in GitLab, only a token.

Can the GitHub MCP server protect against prompt injection from issues?

Partly. Lockdown mode hides or refuses public-repository content from authors without push access, but the README says it is a best-effort filter and not an authorization boundary.

Sources

github/github-mcp-server at 99d6d65
README.md · docs/server-configuration.md · docs/remote-server.md · docs/scope-filtering.md · docs/policies-and-governance.md · docs/oauth-login.md · docs/installation-guides/install-claude.md · Dockerfile

cli/cli at 205239f
README.md · skills/gh/SKILL.md · pkg/cmd/auth/login/login.go · internal/config/config.go · internal/telemetry/telemetry.go · internal/ghcmd/cmd.go

zereight/gitlab-mcp at 3db1dc9
README.md · package.json · docs/configuration/environment-variables.md · docs/comparison/official-gitlab-mcp.md