GitLab MCP server: 36 tools, no read-only mode
What the native endpoint exposes, why one tool deletes a pipeline when you leave a parameter out, and why teams in GitLab's own feedback issue run a community server instead.
Last verified 25 August 2026 · from docs.gitlab.com, the live endpoint and feedback issue 561564
This page is one of 90 in a directory of monitoring and developer tools. Each page checks what an AI coding agent can get out of the tool through its MCP server, the connector that lets the agent query the tool directly.
Summary
The GitLab MCP server is not a package. It is the GitLab API, reachable at https://<instance>/api/v4/mcp once three settings are on. There is nothing to install and nothing to keep updated separately.
The documentation lists 36 tools. Twenty-four read, and twelve write: they create issues, open merge requests, post review comments, add branches, run and cancel pipelines, update work items and attach security scan profiles.
There is no read-only mode. The client either gets all 34 or none, and GitLab's own docs place the responsibility on you: You are responsible for guarding against prompt injection when you use these tools.
The status is beta, and the tool list has moved during it. gitlab_search became search in 18.8, get_job_log became get_job in 19.3, and manage_pipeline lost four of its actions to two new tools in the same release.
What is the GitLab MCP server?
GitLab holds the repository, the merge requests, the issues, the work items and the CI pipelines. An MCP server over it lets an agent read a diff, look at why a job failed and comment on a review without a browser.
GitLab built the endpoint into the product rather than shipping a package. It arrived as an experiment in 18.3 behind two feature flags. Those flags were removed in 18.6, when it became beta. It gained the 2025-03-26 and 2025-06-18 protocol specifications in 18.7. It moved from Premium to Free in 19.2.
Authentication is OAuth 2.0 Dynamic Client Registration only. The client registers itself, a browser opens, you approve, and a token comes back. Personal access tokens are not accepted, which is the single most requested change in the feedback issue.
GitLab covers code review and CI outright, and reaches agent observability in a way almost no other connector does. It carries no production telemetry and no spend data.
| Part of the work | What GitLab has here | Can an agent reach it |
|---|---|---|
| Code, tests & review | Merge requests, diffs, commits, notes, reviews and code search | Yes. Full. Diffs, discussion threads, diff-line comments and a submit-review call are all reachable |
| CI & release | Pipelines, jobs and job logs | Yes. Full, including running, retrying and cancelling. Job logs come back in windows of bytes rather than being cut off, and the response says where the next window starts |
| Production observability | None | No metrics, logs or traces from running services |
| Agent observability & evals | Duo Agent Platform sessions | Partial, and unusual. list_duo_sessions returns status, goal preview and flow definition for GitLab's own agent runs, not for agents you build |
| AI cost management | None | No spend data of any kind |
For an agent, that means GitLab answers the whole path from a diff to the pipeline that tested it, and nothing about what happened after deploy. list_duo_sessions is a genuine oddity: a connector that can see agent runs, provided the agent is GitLab's own.
What can an AI agent do with GitLab?
36 documented, 24 that read and 12 that write.
- Merge requests6
get_merge_requestlist_merge_requestsget_merge_request_commitsget_merge_request_diffsget_merge_request_pipelinesget_merge_request_notes- Merge request writes3
save_merge_requestsave_notesave_merge_request_review- Work items and issues5
get_issueget_work_itemlist_work_itemsget_workitem_notesget_saved_view_work_items- Work item writes4
create_issuesave_work_itemsave_notelink_work_items- CI and pipelines4
get_pipelinelist_pipelinesget_pipeline_jobsget_job- CI writes2
save_pipelinemanage_pipeline- Repository3
get_repository_fileget_commitlist_wiki_pages- Repository writes1
add_branch- Search3
searchsearch_labelssemantic_code_search- Security1Write
attach_scan_profile- Platform2
get_mcp_server_versionlist_duo_sessions
Counted from the documented tool reference on 25 August 2026. semantic_code_search is the only tool with its own license requirement, needing a GitLab Duo add-on, so a Free instance gets 33 of the 34. add_branch also answers to create_branch, and get_job also answers to get_job_log.
What connecting costs before the first question
A context window is the amount of text a model can hold at once. Thirty-four tools arrive through GitLab's native endpoint at connection, costing 2,750 to 3,301 tokens on Claude. Eleven of them write.
There is no read-only mode, so the whole list loads or none of it does. One decision covers both the context cost and the write exposure.
| Tool set | Tools | Tokens (GPT-5.6, GPT-5.5) | Tokens (GPT-4, GPT-3.5) | Tokens (Claude Haiku 4.5 to Opus 5) | Share of a 200,000-token window |
|---|---|---|---|---|---|
| Every tool documented | 34 | 1,255 to 1,569 | 1,254 to 1,568 | 2,750 to 3,301 | 0.6% to 1.7% |
Encodings: GPT-5.6, GPT-5.5 o200k_base; GPT-4, GPT-3.5 cl100k_base; Claude Haiku 4.5 to Opus 5 count_tokens. Counted from the 34 tool entries in the vendor's own documentation. That documentation is the only public inventory.
The server could not be run for a live tools/list. So no input schemas are available, and these figures cover each tool's name and description only. They are a floor, not the figure.
The Claude columns are measured through the API's count_tokens endpoint with an empty schema per tool. So they cover the same content as the GPT columns. The range there is two tokenizer generations. Haiku 4.5 and Opus 4.6 are at the low end. Opus 5 and Sonnet 5 are at the high end. The gap between them is about a fifth.
Can GitLab watch your own AI agents?
One tool here reads agent activity, and it reads GitLab’s agents rather than yours. Read from GitLab’s MCP documentation on 25 August 2026.
| Signal | Covered | Notes |
|---|---|---|
| Trace and session tracking | Partial | list_duo_sessions returns status, goal preview and flow definition for Duo Agent Platform runs. Agents you build yourself leave no record here |
| Eval scores on recorded traffic | No | No evaluation tool appears among the documented 34 |
| Prompt version tracking | No | Duo’s prompts are GitLab’s own and are not exposed for reading |
| Offline experiments | No | No dataset or experiment tool appears among the documented 34 |
| Token and cost tracking | No | No tool returns a token count or a cost figure for a Duo session |
GitLab MCP server limits: where answers come back incomplete
One tool deletes a pipeline when a parameter is left out. Read that limit before the rest.
One tool deletes a pipeline when you leave a parameter out.
manage_pipeline takes id, pipeline_id and an optional name. The documentation states that if only pipeline_id is set, the call deletes the pipeline and all related data.
The destructive path is therefore the shorter call. A model that omits name, whether by choice or by dropping it, deletes rather than renames.
Guard: Do not expose manage_pipeline to an unattended agent. The disclosure block above names this case explicitly for that reason.
There is no read-only mode, and engineers keep asking for one.
All 36 tools arrive together. Twelve of them write, and their names sit beside the read names in the same list the model chooses from.
In the feedback issue on 21 June 2026, an engineer asked GitLab to expose read-only against mutating, required token scopes and whether an action is safe to retry, as tool-level metadata rather than documentation.
Guard: Approve writes at the client. Several teams instead run a community server that offers separate read-only endpoints.
The agent says: “Let me look at the work items.” It got there, after several wrong tools.
Thirty-four descriptions arrive on every turn, and several read paths overlap. On 15 June 2026 an engineer described the agent trying work item tools, then curl, then the merge request itself, before settling on search.
Guard: Name the tool in the prompt when the task is known. get_merge_request_notes is the direct route to review comments.
The agent says: “I will authenticate with the token in the environment.” The server rejects it.
Only OAuth-granted tokens are accepted. A GitLab engineer confirmed on 22 August 2025 that personal access tokens are not supported, and the endpoint answers a PAT with 403.
Guard: Plan for a browser step. Unattended or machine-to-machine use has no supported path on the native endpoint.
The agent says: “Scan profile attached.” To every project in the group.
attach_scan_profile takes project_ids or group_ids, and the documented example attaches a profile to all projects under one group.
Guard: Never pass group_ids from an agent. Enumerate the projects you meant.
How to configure GitLab MCP for agents
- 1
Turn on three settings, not one
Duo availability must be Always on or On by default, beta and experimental features must be on, and access to the MCP server must be allowed. All three sit at the top-level group on GitLab.com, or the instance elsewhere.
- 2
Choose HTTP transport
GitLab recommends it and it needs no Node.js. The stdio route runs
npx mcp-remoteand requires Node 20 or later. - 3
Prefix the tool names if you run more than one GitLab
The
X-Gitlab-Mcp-Server-Tool-Name-Prefixheader, added in 18.11, renames every tool for that connection. It truncates at 32 characters. - 4
Decide what the OAuth identity may do before connecting
The token carries your own permissions, and there is no per-tool restriction to fall back on.
- 5
Budget for tool descriptions in every request
Thirty-four tool descriptions arrive at connection, and there is no way to send fewer. An engineer in the feedback issue reports the agent trying several wrong tools before finding the right one.
Paste this into your agent’s instructions
Twelve of the 36 tools write, and the write and read names look alike. The block forces the agent to say which side of that line it crossed.
When you answer using GitLab MCP tools, state: - Which tool you called and the project it acted on. - Whether the call was a read or a write. Eleven of the 34 tools write. Never call one without asking first. - That manage_pipeline deletes a pipeline and all related data when pipeline_id is the only parameter set. Never call attach_scan_profile with group_ids. It applies to every project under the group. Never state that data does not exist. State which tool you called and what it returned. Write your answer in ASD-STE100 Simplified Technical English. Use short sentences with one idea in each.
Do you need the MCP server at all?
Not for unattended work. glab, GitLab's own CLI, is the alternative teams actually reach for. On 18 March 2026 an engineer reported more success with it than with the MCP server or third-party wrappers, and fewer tokens spent.
Community servers are the other route, and the feedback issue documents real migrations to them. They trade official support for fine-grained tokens, selectable toolsets and separate read-only endpoints.
The v4 REST API remains the direct path for anything scheduled. The MCP endpoint is that same API with tool descriptions attached.
For the code review itself, SonarQube, Semgrep and CodeRabbit answer questions about the diff that GitLab's own tools do not.
With MCP, one connection reaches the diff, the pipeline that tested it and the discussion about it, with no token to place in a config file.
Use the native endpoint for interactive work. Use glab or the REST API for anything that runs unattended.
GitLab MCP server setup
Nothing is installed. The endpoint is https://<gitlab.example.com>/api/v4/mcp, and on GitLab.com that host is gitlab.com.
No configuration block below holds a credential. Authentication is OAuth 2.0 Dynamic Client Registration: the client registers itself on first connect, a browser opens the authorize page, and you approve it there.
Before any of it works, three settings must be on: Duo availability set to Always on or On by default, beta and experimental features enabled, and access to the MCP server allowed. On GitLab.com they live on the top-level group; on Self-Managed and Dedicated they live on the instance.
Claude Code
GitLab documents the CLI form. After it is added, run /mcp, pick the GitLab server and approve the request in the browser that opens.
claude mcp add --transport http GitLab https://gitlab.com/api/v4/mcp
Cursor
Settings, Cursor Settings, Tools and MCP, then New MCP Server. Saving the file should open the browser authorize page. If it does not, close and restart Cursor.
{"mcpServers":{"GitLab":{"type":"http",
"url":"https://gitlab.com/api/v4/mcp"}}}Codex CLI
Codex reads TOML, so the JSON blocks will not transfer. One engineer in the feedback issue reported the direct remote route failing to initialize after OAuth completed, and fell back to the mcp-remote proxy below.
[features] rmcp_client = true [mcp_servers.GitLab] url = "https://gitlab.com/api/v4/mcp"
Two GitLab instances at once
Tool names collide when two GitLab connections are configured. The prefix header, added in 18.11, renames every tool on that connection and truncates past 32 characters.
{"mcpServers":{"GitLab":{"type":"http",
"url":"https://gitlab.example.com/api/v4/mcp",
"headers":{
"X-Gitlab-Mcp-Server-Tool-Name-Prefix":"gitlab_"}}}}Every other client
Each block below is the configuration for one client, with the file path and the key that client expects.
Claude Desktop
macOS ~/Library/Application Support/Claude/claude_desktop_config.json. Windows %APPDATA%\Claude\claude_desktop_config.json. There is no CLI. Edit through Settings, Developer, Edit Config.
Quit and restart fully for changes to load. Node.js 20 or later must be on the global PATH, because this route proxies through mcp-remote. On first connect a browser opens for the OAuth approval.
{"mcpServers":{"GitLab":{"command":"npx",
"args":["-y","mcp-remote",
"https://gitlab.com/api/v4/mcp"]}}}mcp-remote caches its OAuth state in ~/.mcp-auth. An engineer in the feedback issue clears it on a nightly cron to work around expired grants, and warns that doing so signs you out of every other MCP server using that path.
Gemini CLI
~/.gemini/settings.json globally, or .gemini/settings.json per project. GitLab documents the httpUrl key here rather than url. Run /mcp auth GitLab to open the authorize page.
{"mcpServers":{"GitLab":{
"httpUrl":"https://gitlab.com/api/v4/mcp"}}}VS Code Copilot
.vscode/mcp.json per workspace, or your user profile. GitLab documents the Command Palette route: MCP: Add Server, choose HTTP, enter the URL, then approve in the browser.
{"servers":{"GitLab":{"type":"http",
"url":"https://gitlab.com/api/v4/mcp"}}}The key is `servers`, not `mcpServers`. VS Code is the only client that uses that name, and copying a config from anywhere else fails silently.
Windsurf
~/.codeium/windsurf/mcp_config.json, which is the path Windsurf documents. Key mcpServers, the same shape as Cursor, and the same browser approval on first connect.
{"mcpServers":{"GitLab":{"serverUrl":
"https://gitlab.com/api/v4/mcp"}}}Zed
~/.config/zed/settings.json, under context_servers. OAuth runs in the browser as elsewhere.
{"context_servers":{"GitLab":{
"url":"https://gitlab.com/api/v4/mcp"}}}Google Antigravity
~/.gemini/config/mcp_config.json globally, or .agents/mcp_config.json per project. Key mcpServers. There is no CLI. Use the /mcp overlay. Streamable HTTP is supported directly, so no proxy is needed.
No credentials appear in the block. The browser opens the GitLab authorize page on first connect.
{"mcpServers":{"GitLab":{"type":"http",
"url":"https://gitlab.com/api/v4/mcp"}}}Amp (Sourcegraph)
~/.config/amp/settings.json or .amp/settings.json. The amp mcp CLI covers approve, doctor and oauth. Approval happens in the browser.
{"amp.mcpServers":{"GitLab":{
"url":"https://gitlab.com/api/v4/mcp"}}}Cline
~/.cline/mcp.json per the docs. The source also reads ~/.cline/data/settings/cline_mcp_settings.json. Key mcpServers. Streamable HTTP is supported, so the proxy is optional.
No credentials appear in the block. OAuth runs in the browser on first connect.
{"mcpServers":{"GitLab":{"type":"streamableHttp",
"url":"https://gitlab.com/api/v4/mcp"}}}Goose (Block)
~/.config/goose/config.yaml. The streamable_http type avoids the Node proxy; authorization is still a browser approval.
extensions:
gitlab:
type: streamable_http
uri: https://gitlab.com/api/v4/mcpKiro (AWS)
.kiro/settings/mcp.json per workspace, or ~/.kiro/settings/mcp.json globally. Key mcpServers. Kiro runs stdio servers, so this route proxies through mcp-remote and needs Node 20 or later.
No credentials appear in the block. The proxy opens the browser authorize page on first connect.
{"mcpServers":{"GitLab":{"command":"npx",
"args":["-y","mcp-remote",
"https://gitlab.com/api/v4/mcp"]}}}Warp
~/.warp/.mcp.json or .warp/.mcp.json. Key mcpServers. Also addable through the /agent-add-mcp skill. No credential is stored; approval is in the browser.
{"mcpServers":{"GitLab":{
"url":"https://gitlab.com/api/v4/mcp"}}}JetBrains Junie
.junie/mcp/mcp.json per project, or ~/.junie/mcp/mcp.json. Key mcpServers. Use /mcp in the CLI to manage the browser authorization.
{"mcpServers":{"GitLab":{"type":"http",
"url":"https://gitlab.com/api/v4/mcp"}}}Roo Code
.roo/mcp.json per project. The global file is mcp_settings.json, opened from the Roo Code MCP settings view with Edit Global MCP. Key mcpServers, with OAuth in the browser.
{"mcpServers":{"GitLab":{"type":"streamable-http",
"url":"https://gitlab.com/api/v4/mcp"}}}Continue
.continue/mcpServers/*.yaml, one file per server. No credentials appear in the file; the browser handles authorization.
name: GitLab
version: 0.0.1
schema: v1
mcpServers:
- name: GitLab
type: streamable-http
url: https://gitlab.com/api/v4/mcpTrae
.trae/mcp.json per project, or paste into the UI under Raw Config (JSON). Key mcpServers, standard shape, browser authorization on connect.
{"mcpServers":{"GitLab":{
"url":"https://gitlab.com/api/v4/mcp"}}}Devin
Devin has no config file to edit. Servers are added through a web form in the settings UI, and Devin's documentation states you do not need to write or paste JSON. The block below is the shape those fields describe, shown for reference. Either route completes authorization in the browser.
{"mcpServers":{"GitLab":{"type":"http",
"url":"https://gitlab.com/api/v4/mcp"}}}Self-managed and Dedicated
Replace gitlab.com with your instance host in any block above. The three prerequisite settings live on the instance rather than on a top-level group. Authorization is the same browser OAuth flow, against your own instance.
Air-gapped instances are a known gap. An engineer in the feedback issue reports that GitLab Duo cannot be enabled on an offline license, and the MCP server depends on it.
claude mcp add --transport http GitLab \ https://gitlab.example.com/api/v4/mcp
Read-only access, permissions and security
GitLab puts prompt injection on you, in writing
The documentation repeats, once per client: You are responsible for guarding against prompt injection when you use these tools. Exercise extreme caution or use MCP tools only on GitLab objects you trust. An issue description is untrusted text that reaches the model.
There is no read-only mode
Eleven tools write, and no setting removes them. The comparison teams keep drawing in the feedback issue is GitHub's separate read-only endpoint.
manage_pipelinedeletes by omissionPer the documentation, if
pipeline_idis the only parameter set, the call deletes the pipeline and all related data. Adding anamemakes the same call a rename.attach_scan_profileaccepts group IDsOne call attaches a security scan profile to every project under a group, so a single mistake reaches a whole namespace rather than one repository.
The token is you
OAuth grants the connection your own permissions across every project you can reach, and there is no narrower scope to hand it.
Personal access tokens are refused
That removes a class of leaked-secret risk and rules out machine-to-machine use, which is why several teams in the feedback issue run a community server with fine-grained tokens instead.
Troubleshooting
- 403 when authenticating with a personal access token
- Expected. A GitLab engineer confirmed in the feedback issue that the server supports OAuth-granted tokens only, and that PATs are not supported.
- The server does not appear at all
- Check all three prerequisites, not just one: Duo availability, beta and experimental features, and MCP server access. Missing any leaves the endpoint invisible.
- `InvalidGrantError` or an expired authorization grant
- The
mcp-remoteproxy caches OAuth state in~/.mcp-auth. Clearing it forces a fresh authorization, and also signs out every other MCP server that uses that directory. - `Server's protocol version is not supported`
- Reported against Claude Desktop 0.13.91 in the feedback issue. GitLab added the 2025-03-26 and 2025-06-18 protocol specifications in 18.7, so an older instance will not negotiate with a newer client.
- A tool name from an older guide no longer exists
- Names moved during beta.
gitlab_searchbecamesearchin 18.8,get_job_logbecameget_jobin 19.3 and is kept as an alias, andmanage_pipelinelostlist,create,retryandcanceltolist_pipelinesandsave_pipelinein 19.3. - The job log is cut off
- It is a window, not a truncation.
get_jobreturns at mostbyte_limitbytes, default and maximum 512000, and the response reports the total size and thebyte_offsetfor the next window.
GitLab MCP server: Reference
| Item | Value |
|---|---|
| Endpoint | https://<instance>/api/v4/mcp |
| Live check | HTTP 401 to unauthenticated JSON-RPC on 25 August 2026 |
| Install | None. Upgrading GitLab is the install |
| Status | Beta. Experiment 18.3, beta 18.6, Free tier 19.2 |
| Tiers | Free, Premium and Ultimate |
| Offerings | GitLab.com, Self-Managed and Dedicated |
| Tools | 36 documented · 24 read · 12 write |
| License-gated tool | semantic_code_search needs Duo Core, Pro or Enterprise |
| Auth | OAuth 2.0 Dynamic Client Registration. No personal access tokens |
| Transports | HTTP, recommended · stdio through mcp-remote, needs Node 20+ |
| Tool prefixing | X-Gitlab-Mcp-Server-Tool-Name-Prefix, added 18.11, 32 characters |
| Protocol specs | 2025-03-26 and 2025-06-18, added in 18.7 |
| Job log window | byte_limit default and maximum 512000 |
| Read-only mode | None documented |
| Feedback issue | 561564, open, updated 24 August 2026 |
| Inventory source | Documented tool reference, read 25 August 2026 |
What engineers report
GitLab runs a public feedback issue for this server. It was open with 312 comments and 12 upvotes when read on 25 August 2026, which makes it one of the few connectors in this directory with genuine public discussion.
| What was checked | What it shows |
|---|---|
| Feedback issue | 561564, opened 14 August 2025 |
| Comments | 312 |
| State | Open, updated 24 August 2026 |
| Documented tools | 34 |
| Write tools | 11 |
“Currently the MCP server only supports OAuth-granted tokens. PATs are not supported.”
“I've found that tools like claude code often work better with a CLI. I've experienced a lot more success using the GitLab CLI with claude code than with the MCP (even 3rd party MCPs that wrap the GitLab API). It not only accomplish tasks a lot easier, it also uses less tokens.”
“I talked about the vague / broad permissions here. I've resorted to using a community MCP w/ fine-grained tokens. It also seems more stable, and can just add tools / features as needed easily.”
“When using the community server to get a discussion note (comment on MR), the agent does it straightforward. When using this official MCP, it explores unrelated tools like workitem, then it tries curl. Finally after many tokens burned, it uses search which sounds pretty suboptimal.”
“For each GitLab MCP tool, I would want to see: read-only vs mutating, required token scopes, whether it can affect CI/CD, issues, merge requests, repository content, or settings. This matters because agents often choose tools from names/descriptions, not from full docs.”
Comments were read from the public discussion on issue 561564 on 25 August 2026. Author names and dates are as recorded on each comment. Quotes are trimmed for length and links inside them are described rather than reproduced.
Should you connect an agent to GitLab?
Yes. Best for interactive review and CI triage, with writes approved at the client.
- Strongest fit
- Teams already on GitLab who want an agent reading merge requests and pipeline failures without installing or maintaining anything.
- Main advantage
- There is no package, no token in a config file and no separate update path. Upgrading GitLab is the whole install.
- Main weakness
- No read-only mode, no personal access tokens, and a tool list that renamed and removed tools during beta.
- Operational risk
manage_pipelinedeletes a pipeline and all related data whenpipeline_idis its only parameter.
From Oodle
One platform for agent traces and infrastructure
Agent traces usually sit in a different product from the rest of your telemetry, so when a slow database makes an agent slow the symptom is in one tool and the cause is in another. Oodle keeps both in one query surface, from $10 per million spans.
See agent observabilityFrequently asked questions
Does GitLab have an official MCP server?
Yes, and it is part of GitLab itself. Every instance serves it at /api/v4/mcp once three settings are enabled. It is beta, and available on Free, Premium and Ultimate.
How many tools does it expose?
Thirty-six are documented as of 1 September 2026. Twenty-four read and twelve write. semantic_code_search additionally needs a GitLab Duo add-on.
Can I use a personal access token?
No. A GitLab engineer confirmed in the feedback issue that only OAuth-granted tokens work, and a PAT returns 403. That rules out unattended machine-to-machine use.
Is there a read-only mode?
None is documented. All 36 tools arrive together, and engineers in the feedback issue have asked for read-only against mutating to be visible at the tool level.
Which tool is the most dangerous?
manage_pipeline. The documentation states it deletes the pipeline and all related data when pipeline_id is the only parameter set, so the destructive path is the shorter call.
Why do the tool names in older articles not match?
The surface moved during beta. gitlab_search became search in 18.8, get_job_log became get_job in 19.3, and manage_pipeline lost four actions to list_pipelines and save_pipeline in the same release.