·

What Is GitLab MCP

Learn what GitLab MCP is and how it lets your AI agent manage repositories, merge requests, and CI/CD pipelines.

GitLab MCP is a Model Context Protocol server that exposes GitLab's REST and GraphQL APIs as structured tools an AI agent can call directly. Instead of your agent shelling out to curl against gitlab.com/api/v4/... and parsing raw JSON, it gets typed tool definitions — create_merge_request, list_issues, get_pipeline — that return predictable, agent-friendly payloads. If you've already wired up GitHub MCP for a repo hosted on GitHub, the mental model is identical; the tool names and the underlying API just point at GitLab instead.

There are two implementations worth knowing about. GitLab itself maintains an official MCP server (@gitlab-org/mcp-server on npm, also shipped as a Docker image registry.gitlab.com/gitlab-org/mcp-server), which tracks GitLab's own API surface closely and gets first-party support. There's also a widely used community server, @zereight/mcp-gitlab, which predates the official one and is still in active use because it supports both GitLab.com and self-managed instances with a slightly different tool set (it exposes wiki and snippet tools the official server doesn't, as of GitLab 17.x). Know which one you're installing — the tool names differ between them, and course examples here use the official server's naming convention with notes where the community server diverges.

This topic is the orientation lap: what tools exist, how auth works, how GitLab MCP compares to GitHub MCP if you're coming from that world, and what scopes you should actually grant versus what's tempting to grant out of laziness.

Core GitLab MCP Tools: Projects, Merge Requests, Issues, and CI/CD

The tool surface maps to four GitLab domains. You won't use all of them in every session, but knowing the full inventory saves you from asking the agent to do something it already has a tool for.

Project and repository tools:
- search_projects / get_project — resolve a project by path (group/subgroup/project) or numeric ID
- list_repository_tree — browse files without cloning
- get_file_contents — read a file at a specific ref
- create_or_update_file, push_files — commit changes directly via API (no local git required)
- list_branches, create_branch

Merge request tools:
- create_merge_request, get_merge_request, list_merge_requests
- update_merge_request — change title, description, labels, assignees, reviewers
- merge_merge_request — merge with configurable strategy (merge commit, squash, fast-forward)
- list_merge_request_diffs, get_merge_request_changes — pull the actual diff for review
- create_merge_request_note, create_merge_request_discussion — post comments, including inline diff comments tied to a file/line

Issue tools:
- create_issue, get_issue, list_issues, update_issue
- create_issue_note — comment on an issue
- Filtering by labels, milestone, assignee_id, state (opened/closed) is supported server-side, which matters — filter in the tool call, not by asking the LLM to eyeball a huge list

CI/CD tools:
- list_pipelines, get_pipeline, get_pipeline_jobs
- get_job_logs — pull raw job output, essential for failure triage
- retry_pipeline, cancel_pipeline
- list_pipeline_schedules

One practical note: the official GitLab MCP server groups some of these behind "toolsets" you enable individually (--toolsets=merge_requests,issues,pipelines on the CLI or via env var). This isn't just organizational — fewer active tools means a smaller tool-choice context for the LLM, which measurably improves selection accuracy on models with weaker function-calling. Don't enable every toolset by default; enable what the session needs.

A quick sanity check most people skip: run a raw list call once before wiring up prompts, so you know what the server actually returns for your GitLab edition. Free-tier GitLab.com and self-managed Community Edition don't expose everything Premium/Ultimate does — approval-rule detail and some audit endpoints are gated behind license tier, not just MCP server capability, so a tool that "should" exist per the docs can still 404 or return an empty payload on a CE instance.

npx -y @gitlab-org/mcp-server --list-tools

Use that output as your reference sheet rather than trusting a blog post (including this one) about exact tool names — the official server has renamed a few tools across minor versions, and the community server's names never matched 1:1 to begin with.

Tips
- Run list_pipelines before get_pipeline_jobs — you need the pipeline ID first, and agents sometimes guess an ID from conversation context instead of looking it up.
- If you're on self-managed GitLab, confirm your instance version supports the GraphQL fields the MCP server expects; anything older than GitLab 15.6 has gaps in the merge request API the server relies on.
- Disable toolsets you're not using for the session (--toolsets=merge_requests,pipelines) — it cuts tool-selection noise and token overhead.


GitLab MCP Authentication: Personal Access Token Setup and Required Scopes

GitLab MCP servers authenticate with a Personal Access Token (PAT), not OAuth, for local CLI usage — this is a meaningful difference from GitHub MCP's default OAuth device flow. You generate the token once in GitLab's UI and hand it to the MCP server via environment variable.

Create the token under User Settings → Access Tokens (or https://gitlab.com/-/user_settings/personal_access_tokens directly). Set an expiration date — GitLab enforces a max of 365 days as of GitLab 16.0, and un-expiring tokens are no longer creatable on GitLab.com.

Required scopes depend on what you want the agent to do:

Scope Grants Needed for
read_api Read-only access to the full API Listing MRs, issues, pipelines, reading files
api Full read/write API access Creating/merging MRs, creating issues, retrying pipelines
read_repository Clone/pull via HTTP Reading file contents, repo tree
write_repository Push via HTTP create_or_update_file, push_files

For most agentic workflows you'll want api (it's a superset that includes read), plus write_repository if you want the agent committing files directly rather than just reviewing. Resist the reflex to just grant api + write_repository + sudo for convenience — sudo in particular lets the token impersonate any user and should never be near an AI agent.

Set the token as an environment variable, then reference it in your MCP client config:

export GITLAB_PERSONAL_ACCESS_TOKEN="glpat-xxxxxxxxxxxxxxxxxxxx"
export GITLAB_API_URL="https://gitlab.com/api/v4"

For self-managed GitLab, point GITLAB_API_URL at your instance:

export GITLAB_API_URL="https://gitlab.yourcompany.com/api/v4"

If your instance sits behind a corporate proxy or uses a self-signed cert, you'll also need NODE_TLS_REJECT_UNAUTHORIZED=0 for the community server or the equivalent CA bundle flag for the official one — don't do this for GitLab.com, only for internal instances where you control the cert chain and understand the risk.

Tips
- Name your tokens something greppable, e.g. mcp-agent-readonly-2026, so you can find and revoke them fast from the token list.
- Rotate the token before it expires and update the env var in every client config — a silently expired token makes the agent report vague "authentication failed" errors that look like MCP server bugs.
- Never put the raw token in a checked-in .mcp.json — use ${GITLAB_PERSONAL_ACCESS_TOKEN} interpolation or your client's secrets mechanism instead.


GitLab MCP vs GitHub MCP: Key Differences for AI Agent Workflows

If you did Module 6 on GitHub MCP first, most of your intuition transfers, but a few differences will trip you up if you assume 1:1 parity.

Terminology and structure. GitLab uses "merge requests" (MRs) where GitHub uses "pull requests" (PRs) — trivial naming, but it means your prompts need to say "merge request" or "MR," because some models will happily generate a create_pull_request-shaped call that doesn't exist against a GitLab MCP server. GitLab also nests projects under groups and subgroups (my-group/my-subgroup/my-project), so project resolution needs the full path, not just a repo name — GitHub's simpler owner/repo model doesn't carry over.

CI/CD is native and mandatory in the mental model. GitHub Actions is a separate product you opt into; GitLab CI/CD (.gitlab-ci.yml) is core to the platform and the MCP tool set reflects that — pipeline tools are first-class, not an afterthought. If you're used to asking GitHub MCP "did the workflow pass," you'll get much richer job-level and stage-level detail for free from GitLab MCP.

Auth model. GitHub MCP servers (especially the official remote one) increasingly favor OAuth with fine-grained per-repo tokens. GitLab MCP is still predominantly PAT-based, and GitLab's fine-grained "project access tokens" (bound to one project instead of your whole account) are a separate token type from personal access tokens — worth using for single-repo automation instead of a PAT scoped to everything you can see.

Review model. GitLab's approval rules (required approvers, approval count, code owner enforcement) are a distinct API surface from MR creation, and most MCP servers don't expose a dedicated list_approval_rules tool — you'll often need to fall back to get_project and inspect the raw settings, or just document required approvers in your MR template instead of querying them live.

Self-hosting reality. A much larger share of GitLab usage is self-managed than GitHub usage is self-hosted (GitHub Enterprise Server is comparatively rare). Expect to hit version-skew issues — a GraphQL field the MCP server calls that doesn't exist on your company's GitLab 15.4 instance — far more often with GitLab MCP than with GitHub MCP.

Tips
- When migrating prompt templates from a GitHub MCP setup, do a find-and-replace pass for "pull request" → "merge request" and "repo" → "project" — sloppy carryover language confuses tool selection.
- Check your GitLab instance's version (/help page footer or Admin Area → Overview) before assuming a tool exists; the official MCP server's changelog lists minimum GitLab version per tool.
- If working across both platforms, keep separate MCP client configs per project rather than one config trying to alias both — the tool names collide conceptually and it's easy to fire a GitHub-shaped call at GitLab.


Security and Permission Scopes to Configure for GitLab MCP

The single biggest risk with GitLab MCP isn't a exotic exploit — it's an overscoped PAT sitting in an agent's environment that can merge to main, delete branches, or trigger a deploy pipeline because you granted api scope out of convenience and never revisited it.

Start from least privilege and add scope only when a real workflow needs it:

  • Read-only agents (code review assistants, MR summarizers, pipeline dashboards): read_api only. No write scope at all. This is the right default for any agent you haven't fully trusted yet.
  • MR-authoring agents (draft MRs, update descriptions, add labels): api scope, but consider a project access token scoped to one project rather than a personal token with account-wide visibility.
  • Merge-capable agents: this is the scope to be most conservative with. If you let an agent call merge_merge_request, pair it with GitLab's branch protection rules (Settings → Repository → Protected branches) so main still requires a human-approved MR regardless of what the agent's token can technically do. Token scope is not a substitute for branch protection.

Use project access tokens or group access tokens instead of personal access tokens wherever the automation is scoped to specific projects — this limits blast radius if the token leaks, and it decouples the automation from any individual's GitLab account (so it survives offboarding). Create them under Project Settings → Access Tokens; they support the same scope list as personal tokens plus a role (Guest through Owner) that further caps what the token can do regardless of scope.

For CI-triggered agent workflows, don't reuse your personal PAT in pipeline variables. Create a dedicated project/group access token, store it as a masked and protected CI/CD variable, and rotate it on a schedule — GitLab will warn you in the UI when a token is nearing its expiry, but only if someone's watching for that.

Audit trail matters too: every API call made with a token shows up in GitLab's audit events (Premium/Ultimate) or at minimum in application logs. If an agent starts merging things unexpectedly, you want to be able to trace it back to which token and which session made the call — which is another reason to give each agent/environment its own dedicated token rather than sharing one PAT across five different MCP client configs.

Tips
- Set token expiration to 90 days or less for anything with write scope; force yourself to rotate rather than letting a stale, over-permissioned token linger.
- Combine write_repository/api scope with branch protection on main/release/* — never rely on token scope alone as your only safety net.
- Prefer project or group access tokens over personal access tokens for any automation that isn't tied to a single human's identity.


Tips

Tips
- Install both the official and community GitLab MCP servers in a scratch config once, compare tool names side by side, and pick one per project — don't mix them in the same client config.
- Start every new integration with read_api-only scope, prove the tool calls work end-to-end, then widen scope deliberately.
- Keep .gitlab-ci.yml pipeline names and stage names descriptive — the MCP tools return raw pipeline/job metadata, and a vague stage name like "build" makes agent-generated failure summaries much less useful than "build:docker-image".