glab-mcp
v1.4.2
Published
GitLab MCP server — create MRs, watch pipelines, ship code without leaving your AI session
Maintainers
Readme
glab-mcp
A Model Context Protocol server that connects AI coding assistants (Claude Code, Claude Desktop, Cursor) to GitLab. Create MRs, watch pipelines, and ship code without ever leaving your AI session.
AI assistant → glab-mcp → GitLab APIQuick Start
npx glab-mcp initThe setup wizard will:
- Ask for your GitLab URL and Personal Access Token
- Validate your credentials against the GitLab API
- Auto-detect your installed AI clients (Claude Code, Claude Desktop, Cursor)
- Write the correct config file for each client
That's it. Restart your AI client and start using GitLab tools.
What it does
| Tool | What it does |
|------|-------------|
| ship_mr | Stage everything, commit, push, open MR — one call |
| watch_pipeline | Poll a pipeline until done; returns error logs on failure |
| create_mr | Create a merge request |
| list_mrs | List / filter MRs by state, author, or label |
| comment_mr | Post a comment on an MR |
| post_review_findings | Post a code-review report as anchored inline MR comments (reconciles on re-run) |
| approve_mr | Approve an MR |
| merge_mr | Merge an MR |
| get_pipeline_status | Get the latest pipeline for a branch |
| get_pipeline_errors | Fetch logs from failed jobs |
| list_pipeline_jobs | List all jobs in a pipeline |
| retry_pipeline | Retry a failed pipeline |
Requirements
- Node.js 18+
- A GitLab Personal Access Token with
apiscope
Manual Setup
If you prefer to configure manually instead of using npx glab-mcp init:
Environment variables
| Variable | Required | Example |
|----------|----------|---------|
| GITLAB_URL | Yes | https://gitlab.com or your self-hosted URL |
| GITLAB_PAT | Yes | glpat-xxxxxxxxxxxxxxxxxxxx |
Creating a PAT
- GitLab → User Settings → Access Tokens
- Scopes: check api
- Copy the token — you only see it once
Claude Code
Add to .mcp.json in your project root:
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["-y", "glab-mcp"],
"env": {
"GITLAB_URL": "https://gitlab.com",
"GITLAB_PAT": "glpat-xxxx"
}
}
}
}Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) and add the same "mcpServers" block above.
Cursor
Add to .cursor/mcp.json in your project root, same "mcpServers" block.
Other MCP clients
Follow your client's MCP server configuration guide and point it at the same command + env vars.
Usage examples
Once configured, ask your AI assistant naturally:
Ship changes and open an MR:
"Commit my changes and open an MR against main titled 'feat: add user auth'"
Watch a pipeline:
"Watch pipeline 12345 in project 99 and tell me if it fails"
Check CI status on a branch:
"What's the pipeline status on feat/my-feature in project 99?"
Read failure logs:
"Get the error logs from the failed pipeline 12345 in project 99"
Review open MRs:
"List all open MRs in project 99 assigned to me"
The AI will call the right tools automatically. You never touch the browser.
Tool reference
All tools accept project_id as either a numeric ID (42) or a URL-encoded path ("mygroup%2Fmyrepo").
ship_mr
Stage all changes, commit, push the current branch, and open an MR.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| project_id | number | string | Yes | — | GitLab project ID or path |
| target_branch | string | Yes | — | Branch to merge into (e.g. main) |
| title | string | Yes | — | MR title (also used as commit message) |
| commit_message | string | No | title | Override the commit message |
| description | string | No | — | MR description / body |
| working_dir | string | No | cwd | Path to the git repo |
Returns { url, iid, pipeline_id }. pipeline_id is null if no pipeline starts within ~10 seconds.
Security: aborts if any staged or unstaged file matches a secret pattern (.env, *.pem, *.key, id_rsa, credentials.json, *.p12).
watch_pipeline
Poll a pipeline until it reaches a terminal state.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| project_id | number | string | Yes | — | GitLab project ID or path |
| pipeline_id | number | Yes | — | Pipeline ID to watch |
| timeout_minutes | number | No | 30 | Stop watching after this many minutes |
Returns:
// success / canceled / skipped
{ status: 'success', pipeline_id: number, url: string }
// failed — includes per-job error logs
{ status: 'failed', pipeline_id: number, url: string, errors: [{ job, stage, log }] }
// timed out
{ status: 'timeout', pipeline_id: number, url: string }
// API unreachable after 3 retries
{ status: 'error', message: string }create_mr
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| project_id | number | string | Yes | |
| source_branch | string | Yes | Branch to merge from |
| target_branch | string | Yes | Branch to merge into |
| title | string | Yes | |
| description | string | No | |
Returns { url, iid }.
list_mrs
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| project_id | number | string | Yes | | |
| state | opened\|closed\|merged\|all | No | opened | |
| author | string | No | | Filter by GitLab username |
| labels | string | No | | Comma-separated label names |
| page | number | No | 1 | |
| per_page | number | No | 20 | Max 100 |
get_pipeline_status
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| project_id | number | string | Yes | |
| ref | string | No | Branch or tag. Omit to use the current branch (requires working_dir) |
| working_dir | string | No | Path to the git repo for auto-detecting the current branch |
Returns the latest pipeline object or null if none found.
post_review_findings
Post a code-review report as inline anchored discussions on a GitLab MR. Each finding becomes one discussion thread on the exact file:line. Re-runs are idempotent: changed bodies update in place, stale findings auto-resolve, unchanged findings are skipped. Off-diff findings fall back to general MR notes — no information is lost.
Designed to consume /ck:code-review output. Pass either structured findings (preferred) or a raw report_markdown string.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| project_id | number | string | Yes | — | GitLab project ID or path |
| mr_iid | number | Yes | — | MR internal ID |
| findings | Finding[] | No* | — | Structured array (see shape below) |
| report_markdown | string | No* | — | Fallback raw markdown; parser extracts ### [SEVERITY] path:line — title headings |
| dedupe | boolean | No | true | Reconcile against existing tool-tagged threads to avoid duplicates |
| auto_resolve_stale | boolean | No | true | Resolve threads from previous runs that are not in the current findings |
| concurrency | number | No | 4 | Max parallel GitLab API requests |
* Either findings or report_markdown should be provided.
Finding shape:
{
file: string, // path matching the MR diff
severity: 'critical' | 'high' | 'medium' | 'low' | 'info',
title: string,
body: string, // markdown
new_line?: number, // for added/context lines
old_line?: number, // for deleted lines
suggestion?: string, // optional Apply-suggestion patch
}Returns:
{
inline: [{ file, line, hash }], // newly posted inline discussions
updated: [{ file, line, hash }], // existing threads whose body changed
unchanged: [{ file, line, hash }], // identical to last run — skipped
fallback: [{ file, line, reason }], // posted as general MR notes
auto_resolved: [{ file, line, hash }], // stale threads marked resolved
failed: [{ file, line, error }],
}Safety: the tool only ever inspects, updates, or resolves threads carrying its own hidden marker (<!-- glab-mcp-finding:HASH -->). Human comments and other bots are never touched. Empty findings is a no-op — auto_resolve_stale only runs when at least one finding is supplied, so a buggy upstream returning [] cannot silently clear prior threads.
v1 scope: single-line anchoring only. Multi-line ranges planned for v1.1.
get_pipeline_errors
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| project_id | number | string | Yes | | |
| pipeline_id | number | Yes | | |
| tail_lines | number | No | 100 | Log lines to return per failed job (max 500) |
Returns an array of { job, stage, log } for each failed job.
Security
- PAT token — stored only in your MCP client config, never logged or transmitted beyond the GitLab API. Accidentally leaked tokens are redacted to
[REDACTED]in all error messages. - Shell injection — all git operations use
execFilewith argv arrays, neverexecwith string interpolation. - Secret file detection —
ship_mrscans the working tree before staging. If it finds a file matching a secret pattern it aborts and lists the offending files. - Auto-gitignore — when
glab-mcp initstores a PAT directly in.mcp.json, it automatically adds the file to.gitignoreto prevent accidental commits. - Local only — the server runs as a local process on your machine. No data is sent anywhere except your configured
GITLAB_URL. - Rate limiting — the HTTP client backs off automatically on
429responses (1 s → 2 s → 4 s, then throws).
Development
git clone https://github.com/datshiro/glab-mcp
cd glab-mcp
npm install
# Run tests
npm test
# Watch mode
npm run test:watch
# Build
npm run build
# Run directly (for local MCP wiring)
GITLAB_URL=https://gitlab.com GITLAB_PAT=glpat-xxx npm run devProject structure
src/
config.ts # Load and validate env vars
gitlab-client.ts # HTTP client (auth, retries, redaction, job trace)
index.ts # MCP server entry point — tool registration + CLI routing
cli/
init.ts # Interactive setup wizard
config-writer.ts # Read/merge/write MCP config files
detect-clients.ts # Auto-detect installed AI clients
validate-gitlab.ts # Validate GitLab credentials against API
tools/
mr.ts # MR tools (create, list, comment, approve, merge)
pipeline.ts # Pipeline tools (status, errors, jobs, retry)
workflow.ts # Workflow combos (ship_mr, watch_pipeline)
test/
config.test.ts
gitlab-client.test.ts
cli/
config-writer.test.ts
detect-clients.test.ts
validate-gitlab.test.ts
tools/
mr.test.ts
pipeline.test.ts
workflow.test.tsPublishing (maintainers)
CI publishes to npm automatically when you push a version tag:
npm version patch # or minor / major
git push --follow-tagsRequires NPM_TOKEN set as a CI/CD variable.
License
MIT
