GitHub MCP vs GitLab MCP: setup, tools and how far you can lock each down

Both GitHub and GitLab now run an official MCP server that any plan can use. They differ most in one place: GitHub's has a read-only switch and GitLab's does not.

GitLab made its MCP server generally available in 19.5 on October 15. Until then, a GitLab team that wanted an agent on its repositories ran a community server. Now both vendors ship one, both are free on every plan, and they made different choices about how much an agent can do by default. I build on GitHub, so I read GitLab's docs and tool list closely for this.

Side by side

GitHub's and GitLab's official MCP servers, October 2026
GitHubGitLab
Versionv2.0.2GitLab 19.5 (GA)
PlansAllFree, Premium, Ultimate
Hosted endpointapi.githubcopilot.com/mcp/<your-gitlab>/api/v4/mcp
Self-hosted instancesGHES, local server onlySelf-Managed and Dedicated
Sign-inPAT, OAuth app, GitHub AppOAuth with dynamic registration
Tools46 default, 91 with every toolset56
Choose toolsToolsets, single tools, exclusionsToolsets, single tools
Read-only switchYesNo
Merge toolmerge_pull_requestaccept_merge_request

Connecting each one

GitHub's hosted server takes a personal access token in a header. This is the Claude Code command from GitHub's own install guide:

claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer YOUR_GITHUB_PAT"}}'

You can also run it yourself from the ghcr.io/github/github-mcp-server Docker image, which is the only way to use it with GitHub Enterprise Server. On github.com the image can sign you in through the browser instead of a token.

GitLab's server is part of GitLab itself, so the URL is your instance's. There is no token to paste: the client registers itself over OAuth and a browser window asks you to approve it.

claude mcp add -s user --transport http GitLab https://gitlab.com/api/v4/mcp

On GitLab.com a top-level group owner has to leave "Allow access to the MCP server" on. It is on by default for groups created in 19.5 or later, so older groups may need it switched on first. On Self-Managed it is one setting for the instance.

GitLab's sign-in takes fewer steps. It also gives you less control for now. With a GitHub token you choose the scopes, and a fine-grained token with no write access to code stops a merge whatever the server offers. GitLab's 19.5 docs describe no way to narrow what the OAuth grant can do. Its docs for the next release describe fine-grained tokens with an MCP permission, which should close the gap when it ships.

What the agent gets by default

GitHub turns on five toolsets: context, repos, issues, pull requests and users. That is 46 tools. Our GitHub guide lists every one with whether it reads or writes. 19 of them write, including merge_pull_request, push_files and delete_file.

GitLab turns on core, merge requests, work items, repository and CI, plus its Duo agent tools if your plan has them. The whole server is 56 tools. The ones I would look at first:

  • accept_merge_request merges a merge request or turns on auto-merge. It does require the head commit's SHA, so an agent cannot merge something that changed after it looked.
  • add_commit can delete, move and change permissions on files as well as add them.
  • manage_pipeline can delete a pipeline.
  • start_duo_session starts GitLab's own agents, which then act with your permissions.

Every GitLab tool still checks your project and group permissions, so an agent never gets more than the person who signed in. That is the same ceiling as a GitHub token, and for most developers it includes merging.

Cutting it down

This is where they differ most.

GitHub gives you a --read-only flag, or X-MCP-Readonly and a /readonly path on the hosted server, and it overrides everything else. On top of that you can pick toolsets, add single tools and exclude tools by name. There is also lockdown mode, which hides content on public repositories from people without push access. GitHub's README calls it a best-effort filter, not an authorization boundary, which is fair.

GitLab gives you two headers: X-Gitlab-Enabled-Mcp-Server-Toolsets and X-Gitlab-Enabled-Mcp-Server-Tools. Name the toolsets or tools you want and the rest disappear. I found no read-only mode anywhere in the docs. To keep an agent away from accept_merge_request, list only the tools it should have:

claude mcp add -s user --transport http GitLab https://gitlab.com/api/v4/mcp \
  --header "X-Gitlab-Enabled-Mcp-Server-Toolsets: core,work_items"

GitLab rejects a toolset name it does not recognise with a 400. GitHub silently ignores an unknown toolset name, so a typo in X-MCP-Toolsets gives you the default set without telling you.

Both servers decide tools for whoever configured the connection. Neither knows that the triage bot and the coding agent should get different tools from the same server, unless you run separate connections with separate headers and keep them in step. That is the problem a gateway with per-tool grants solves.

The community GitLab servers

Before 19.5, most GitLab teams ran one of these, and they still go further than the official server in places.

zereight/gitlab-mcp is the most used, at over 2,000 stars. It has 276 tools grouped into toolsets, with a lean core set on by default, and a GITLAB_PERMISSION_MODE of readonly, modify (no deletes) or full. The default is full. Its opt-in api toolset sends any request to the GitLab API and skips every restriction, which the README warns about.

jmrplens/gitlab-mcp-server takes the opposite approach to tool count: two tools, one to find an action and one to run it, in front of 872 actions on GitLab Free. Its docs give 1,026 and 1,092 for Premium and Ultimate. That keeps the model's context small, but it means granting one tool grants all of them, so its GITLAB_MCP_READ_ONLY and confirmation settings matter more.

The old reference GitLab server in the MCP repository is archived and its npm package is deprecated. If a tutorial still tells you to install @modelcontextprotocol/server-gitlab, it is out of date.

Which to use

If you are on GitHub, use GitHub's server, start it read-only, and add back only the write tools the agent's job needs. How to give an agent read-only GitHub access has the steps.

If you are on GitLab 19.5 or later, I would now start with the official server over the community ones, because it is maintained by GitLab and signs in without a long-lived token. Pick toolsets on every connection, leave out merge requests for agents that only read, and wait for fine-grained tokens if you want the credential itself to say read-only. If you need a read-only mode today, zereight's readonly setting is the simplest way to get one.

Questions

Yes. It is built into GitLab at /api/v4/mcp, was generally available from GitLab 19.5 in October 2026, and works on Free, Premium and Ultimate for GitLab.com, Self-Managed and Dedicated.

GitHub says it is available to all users regardless of plan. Tools that hand work to Copilot's cloud agent need a paid Copilot licence.

Not with a switch in 19.5. Limit it to read tools with the X-Gitlab-Enabled-Mcp-Server-Tools header, or use a community server such as zereight/gitlab-mcp with GITLAB_PERMISSION_MODE=readonly.

Yes, but only the local server. Run the Docker image with GITHUB_HOST set to your instance; the hosted endpoint does not reach GHES.

Give each agent its own tools from one server. Per-tool grants on three servers, free.