gitlab-mcp-server
The GitLab MCP Server enables AI assistants to interact with GitLab resources via the Model Context Protocol (MCP). Key capabilities include:
Repository Management: Search, create, fork repositories and list group projects
File Operations: Read, create, update, and push multiple files in a single commit
Branch Operations: Create and manage branches
Issue Tracking: Create, list, and filter issues; access comments, notes, and discussions
Merge Request Handling: Create, list, and filter merge requests
Wiki Management: Manage project and group wikis including creating, editing, deleting pages and uploading attachments
Member Management: List and manage project and group members
Project Activity Tracking: Retrieve project events and commit history
Provides tools for interacting with GitLab repositories, including searching, creating, and forking repositories; reading, creating, and updating files; managing branches; handling issues and merge requests; accessing project events and commit history.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@gitlab-mcp-serverlist projects in my team's group"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
GitLab MCP Server
What it is
GitLab MCP Server lets an AI agent (Claude Desktop, Claude Code, Cursor, Zed, VS Code, or any Model Context Protocol client) talk directly to GitLab. It is a typed, paginated, schema-validated bridge to the GitLab REST API, exposed as 86 MCP tools. It is not a wrapper around glab and it does not screen-scrape.
It runs against gitlab.com or any self-hosted GitLab instance, and authenticates with a personal access token, an OAuth Bearer token forwarded by an upstream gateway, or a read-only token for safe demos.
Related MCP server: gitlab mcp
Why it exists
Anthropic released MCP on November 25, 2024. The reference servers covered Google Drive, Slack, GitHub, Git, Postgres, and Puppeteer. There was no GitLab server. The Yoda Digital engineering team runs on self-hosted GitLab, so the official examples did not help us, and the early community ports were not yet trying to cover the GitLab surface area properly.
We wrote one for ourselves. Group projects, activity tracking, the operations our DevOps actually needed. We open-sourced it on March 18, 2025, expecting maybe five people to find it useful.
A year on the project has 86 tools, working stdio / SSE / Streamable HTTP transports, PAT and OAuth modes, a Docker image on ghcr.io, and a Helm chart written almost entirely by an external contributor we had never met. Releases 0.4.0 and 0.5.0 are mostly someone else's code now, which is the best problem an open-source maintainer can have.
Quick start
Local clients (stdio)
For Claude Desktop, Cursor, Zed, and any client that runs MCP servers as a local subprocess. Add this to your client's MCP config (for Claude Desktop, that's claude_desktop_config.json):
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["-y", "@yoda.digital/gitlab-mcp-server"],
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "glpat-…",
"GITLAB_API_URL": "https://gitlab.com/api/v4"
}
}
}
}Self-hosted? Replace GITLAB_API_URL with your instance, e.g. https://gitlab.example.com/api/v4. Want a safe demo with no write access? Add "GITLAB_READ_ONLY_MODE": "true". Per-IDE notes are in docs/CURSOR_INTEGRATION.md.
Remote (Streamable HTTP, OAuth-gated)
For shared deployments and modern remote MCP clients, run the server as an HTTP service. Network-exposed deployments require AUTH_MODE=oauth — the server refuses to start with AUTH_MODE=pat on a non-loopback bind. See SECURITY.md for the threat model.
docker run --rm -p 3000:3000 \
-e HOST=0.0.0.0 \
-e AUTH_MODE=oauth \
-e USE_STREAMABLE_HTTP=true \
ghcr.io/yoda-digital/mcp-gitlab-server:latestThen front the container with a gateway that injects Authorization: Bearer <token> per connection — the server forwards that Bearer to GitLab as the per-connection PAT. Point clients at http://your-gateway/mcp.
Operational details, probe configuration, and troubleshooting are in docs/OPERATIONS.md.
What's in the box
86 tools, grouped by surface:
Repositories: search, create, fork, get and update project metadata.
Files and branches: read, create, update, and delete files; multi-file commits; branches (list, create, delete); repository tree.
Tags and releases: list and create tags; list and create releases.
Issues: create, list, update, notes, threaded discussions.
Merge requests: create, update, merge, rebase; approvals; auto-merge; notes, discussions, changes, commits.
CI/CD: pipelines (list, get, trigger, retry, cancel), jobs (list, get, log, retry, cancel), environments.
Wikis: project and group wikis, including attachments.
Groups and members: groups CRUD, subgroups, project and group members.
Labels and milestones: list, create, update; protected branches: list, protect, unprotect.
Users and meta: current user, list/get user, project events, commit history.
Full tool list in CLAUDE.md. Per-tool docs for selected tools in docs/api/.
Read-only mode (GITLAB_READ_ONLY_MODE=true) filters every mutating tool out at registration time. A misbehaving agent cannot see them, let alone call them.
Transports
Transport | When to use | Flag |
stdio | Local clients (Claude Desktop, Cursor, Zed). The default. | (default) |
SSE | Remote clients still on the legacy SSE spec. |
|
Streamable HTTP | Remote clients on the current MCP Streamable HTTP spec. |
|
Streamable HTTP runs POST /mcp, GET /mcp, and DELETE /mcp, with session management via the MCP-Session-Id header. The /healthz endpoint returns 503 when active sessions exceed HEALTHZ_MAX_SESSIONS, intended for Kubernetes liveness and readiness probes.
Authentication
Two modes. The right one depends on whether the HTTP transport is reachable from the network.
OAuth per connection (AUTH_MODE=oauth, the default for network-exposed deployments). The server holds no static token. Every MCP connection brings its own Authorization: Bearer <token>, which the server forwards to GitLab as the effective PAT for that connection. Run it behind a gateway that handles your IdP. This is how you operate one shared deployment for an entire team. Required whenever bind is non-loopback.
PAT mode (AUTH_MODE=pat, loopback only). The server holds one personal access token in GITLAB_PERSONAL_ACCESS_TOKEN. The HTTP transport runs without authentication in this mode, so the server enforces a loopback-only bind (HOST=127.0.0.1) and refuses to start otherwise. Right choice for stdio clients and single-tenant local dev. Not supported in Helm — see the chart's auth-validation guard.
Configuration
Variable | Default | Purpose |
| — | Required in PAT mode. |
|
| GitLab API base URL. Point at your self-hosted instance if needed. |
|
| Hide all write tools. |
|
|
|
|
| Bind address for HTTP transports. Set to |
|
| Enable legacy SSE transport. |
|
| Enable MCP Streamable HTTP transport. |
|
| HTTP listen port for SSE and Streamable HTTP. |
| (empty) | Comma-separated allowlist. Empty means |
|
|
|
.env.example ships in the repo for local development.
Deployment
Docker
ghcr.io/yoda-digital/mcp-gitlab-server:latestMulti-stage build on node:24-alpine. Runs as non-root (uid 1000) with all capabilities dropped. Compatible with read-only root filesystems and the seccompProfile: RuntimeDefault Kubernetes pod-security setting. Image tags follow semver on releases; latest tracks the most recent tagged release.
Kubernetes (Helm)
helm install gitlab-mcp oci://ghcr.io/yoda-digital/charts/gitlab-mcpThe chart defaults to AUTH_MODE=oauth so a vanilla install is auth-gated. Front the Service with an Ingress or gateway that injects Authorization: Bearer <token> per connection.
The chart ships liveness and readiness probes against /healthz, an optional PodDisruptionBudget, ConfigMap and Secret with rolling-restart annotations, and five fail-loud guards that refuse to render bad configurations:
AUTH_MODE=patwith non-loopbackHOST(CWE-306 — seechart/templates/auth-validation.yaml)empty PAT in PAT mode without
existingSecretboth
existingSecretand inlinesecret.GITLAB_PERSONAL_ACCESS_TOKENset (a silent precedence trap, otherwise)PDB minAvailable >= replicaCount(drain deadlock)both
minAvailableandmaxUnavailableset on the PDB (Kubernetes rejects this combination at admission)
values.yaml is annotated for helm-docs, and chart/README.md is regenerated and drift-checked in CI.
Security
Vulnerabilities go through GitHub's Private Vulnerability Reporting, not public issues. Threat model and scope are in SECURITY.md.
A few things that are true about the supply chain. Every npm publish is signed with Sigstore provenance via OIDC Trusted Publishing. CodeQL runs on every push and PR with the security-extended and security-and-quality query packs. Dependabot is on, grouped, and weekly. npm audit reports zero vulnerabilities at the current release. main requires PRs, status checks, squash or rebase merges, and linear history.
Read-only mode is enforced at tool registration, not at the request boundary. If a regression lets a write tool execute under GITLAB_READ_ONLY_MODE=true, that is a security bug. Please report it.
Where this fits in the ecosystem
There are several ways to combine GitLab and MCP. Pick the one that matches your situation:
GitLab's own built-in MCP server at
https://<your-instance>/api/v4/mcp. 15 tools, requires GitLab Premium or Ultimate, OAuth integrated with your GitLab IdP. The right choice if you have the subscription and 15 tools is enough surface area for your agents.zereight/gitlab-mcp, the largest community implementation. Broader auth surface (PAT, OAuth2 browser flow, OAuth proxy, remote authorization), more tools. A good fit if you want maximum coverage and do not mind a larger project to reason about.mcpland/gitlab-mcp, with a policy-engine focus. OAuth2 PKCE, multi-instance routing, cookie-based auth. Good for tightly controlled enterprise deployments.This server (
@yoda.digital/gitlab-mcp-server). 86 tools, three transports, PAT and OAuth, Sigstore-provenanced npm releases, a non-root multi-stage Docker image, and a Helm chart with fail-loud guards. Good if you want a smaller, security-mature project that lands cleanly into a Kubernetes deployment.
None of these is universally best, and we will not pretend otherwise.
Contributing
PRs welcome. The shape we ask for:
Fork, branch (
feature/*,fix/*,docs/*,refactor/*).Conventional Commits (
feat:,fix:,docs:,chore:, …). They drive the changelog.Add or update vitest tests for behavior changes.
npm testis the gate.Open a PR. CI runs
build-and-test, CodeQL, Dockerfile lint, Helm lint and template smoke test, and a Helm chart README drift check.
Local setup:
git clone https://github.com/yoda-digital/mcp-gitlab-server.git
cd mcp-gitlab-server
npm install
npm test
npm run devFull guidelines are in CONTRIBUTING.md. AI-assisted contribution rules are in ai_code_of_conduct.md. Code of Conduct: CODE_OF_CONDUCT.md. A few good first issue tickets live in the issue tracker.
Contributors
This project has more authors than its origin suggests.
Ion (Nalyk) Calmîș is the original author and maintainer. CTO at Yoda Digital.
Olivier Gintrand (@ecthelion77) wrote the OAuth per-connection authentication path, the MCP Streamable HTTP transport, the multi-stage Dockerfile, and the Helm chart, including the fail-loud guards. Releases 0.4.0 and 0.5.0 are mostly his work, merged via PR #42 and PR #44.
Thomas Léveil (@thomasleveil) and BenSchoweCONPORT sent early PRs.
Dependabot is responsible for most of the chore commits in the changelog and never sleeps.
If you have sent a PR or a security report and you are not on this list, that is a bug. Please open an issue.
License
MIT.
Links
Built with ❤️ by Yoda.Digital
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/yoda-digital/mcp-gitlab-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server