Skip to content

wanadev/gitlab-mcp

Repository files navigation

@wanadev/mcp-gitlab

A Model Context Protocol (MCP) server that gives project managers and developers full control over GitLab epics, issues, milestones, iterations, merge requests, code review, pipelines, branches, repository content, labels, boards, members, and governance from Claude Desktop, Claude Code, or any MCP-compatible client.

Why this MCP server?

Existing tools like glab are developer-oriented and CLI-only. @wanadev/mcp-gitlab covers both lenses -- planning and code -- through a conversational interface:

  • Epics, milestones & iterations -- create, update, close, reopen, and link issues to epics. Track sprints with iterations (CRUD). Set health status (on track / needs attention / at risk) and view progress via Work Items API. Attach issues under epics via the modern hierarchy widget.
  • Full MR lifecycle -- create, update, merge, rebase, approve, diff, and comment on merge requests.
  • Code review -- create line-positioned discussions on MR diffs and resolve them.
  • CI/CD -- list and inspect pipelines, fetch job logs, retry or cancel runs.
  • Repository content -- list/create branches, browse the tree, read files, list commits, and write files (create / update / delete / atomic multi-file commits).
  • Search -- full-text search across issues, MRs, and code blobs at project or group scope.
  • Members management -- add, update, and remove group/project members with access levels.
  • Governance -- list and manage protected branches and MR approval rules.
  • Uploads -- upload images/binaries to embed in issues, MRs, and epics.
  • Labels & users -- CRUD on labels, search users to assign work.
  • Cross-group visibility -- query multiple GitLab groups in the same conversation (no hardcoded group ID).
  • Time tracking -- see estimated vs. spent time on issues at a glance.
  • Comments (notes) -- read, add, edit, and delete notes on issues, epics, and MRs.
  • Dry-run by default -- every write operation previews what it will do before touching GitLab.

Quick setup

Prerequisites

  • Node.js >= 20
  • A GitLab Personal Access Token (PAT) with the api scope (or read_api for read-only access)
  • GitLab Premium/Ultimate for epics and iterations (issues, milestones, MRs, labels, and boards work with all editions)

1. Generate a GitLab token

  1. Go to GitLab > Settings > Access Tokens
  2. Create a token with the api scope
  3. Copy the token

2. Install

Claude Code (plugin)

/plugin marketplace add wanadev/gitlab-mcp
/plugin install wanadev-gitlab@wanadev-gitlab

Set GITLAB_TOKEN in your environment (.bashrc, .zshrc, or system variable). The plugin will guide you on first launch if it's missing.

Claude Desktop (manual config)

Add the following to your claude_desktop_config.json:

Windows: %APPDATA%\Claude\claude_desktop_config.json macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "gitlab": {
      "command": "npx",
      "args": ["-y", "@wanadev/mcp-gitlab"],
      "env": {
        "GITLAB_TOKEN": "glpat-xxxxxxxxxxxxxxxxxxxx",
        "GITLAB_BASE_URL": "https://gitlab.com",
        "GITLAB_READ_ONLY": "false"
      }
    }
  }
}

3. Restart and test

The MCP server will be available immediately. Test with: "List my GitLab groups"

Environment variables

Variable Required Description
GITLAB_TOKEN Yes GitLab Personal Access Token
GITLAB_BASE_URL No GitLab instance URL (default: https://gitlab.com)
GITLAB_READ_ONLY No Set to true to block all write operations

Note: There is no GITLAB_GROUP_ID environment variable. Every group-scoped tool takes a group_id parameter. Use list_groups to discover accessible groups -- the LLM does this automatically.

Dry-run safety

All write tools (create_*, update_*, close_*, set_*, add_*) include a dry_run parameter that defaults to true.

Mode Behavior
dry_run: true (default) Returns a summary of the planned action without executing anything on GitLab.
dry_run: false Executes the action for real, after the user confirms.

This prevents accidental changes: the LLM always shows what it intends to do first and only proceeds after your approval.

All 100 tools

Epics (12 tools -- requires GitLab Premium/Ultimate)

Tool Description Scope Write
list_epics List epics (filter by state, search, labels) group --
get_epic Get epic details by number group --
create_epic Create an epic group dry_run
update_epic Update an epic (title, description, labels, dates) group dry_run
close_epic Close an epic group dry_run
reopen_epic Reopen a closed epic group dry_run
list_epic_issues List issues linked to an epic group --
add_issue_to_epic Link an issue to an epic group dry_run
list_epic_notes List comments on an epic group --
add_epic_note Add a comment to an epic group dry_run
update_epic_note Edit an existing epic comment group dry_run
delete_epic_note Delete an epic comment group dry_run

Work Items (9 tools -- requires GitLab Premium/Ultimate)

Tool Description Scope Write
get_epic_widgets Get epic widgets: health status, progress, milestone, iteration, linked items group --
set_epic_milestone Associate a milestone with an epic group dry_run
set_epic_health_status Set health status on an epic (onTrack / needsAttention / atRisk) group dry_run
set_issue_health_status Set health status on an issue (onTrack / needsAttention / atRisk) project dry_run
set_epic_iteration Associate an iteration (sprint) with an epic group dry_run
add_linked_item Link work items (RELATED / BLOCKS / BLOCKED_BY) group/project dry_run
get_work_item_id Resolve the WorkItem global ID for an epic or issue (required by link/unlink) group/project --
link_work_items Attach children (issues/epics) under a parent epic via hierarchy widget group/project dry_run
unlink_work_items Detach children from their current parent group/project dry_run

Issues (11 tools)

Tool Description Scope Write
list_issues List issues for a group (filter by state, labels, milestone, assignee, iteration) group --
list_project_issues List issues for a single project (with iteration filter) project --
get_issue Get issue details (with time tracking) project --
create_issue Create an issue project dry_run
update_issue Update an issue project dry_run
close_issue Close an issue project dry_run
reopen_issue Reopen a closed issue project dry_run
list_issue_notes List comments on an issue project --
add_issue_note Add a comment to an issue project dry_run
update_issue_note Edit an existing issue comment project dry_run
delete_issue_note Delete an issue comment project dry_run

Milestones (10 tools)

Tool Description Scope Write
list_milestones List milestones for a group group --
get_milestone Get milestone details (group) group --
create_milestone Create a group milestone group dry_run
update_milestone Update a group milestone group dry_run
close_milestone Close a group milestone group dry_run
list_project_milestones List milestones at the project level (the only way on GitLab CE/Free) project --
get_project_milestone Get a project milestone project --
create_project_milestone Create a project milestone project dry_run
update_project_milestone Update a project milestone project dry_run
close_project_milestone Close a project milestone project dry_run

Merge Requests (18 tools)

Tool Description Scope Write
list_merge_requests List merge requests for a group group --
get_merge_request Get merge request details project --
create_merge_request Open a new MR (source/target branch, title, description) project dry_run
update_merge_request Update an MR (title, description, labels, assignees, reviewers) project dry_run
merge_merge_request Merge an MR (optionally squash or delete source branch) project dry_run
approve_merge_request Approve an MR project dry_run
rebase_merge_request Asynchronously rebase the MR's source branch on top of target project dry_run
get_mr_diff Get the diff/changes for an MR (also returns diff_refs for line-positioned comments) project --
list_mr_notes List comments on an MR project --
add_mr_note Add a comment to an MR project dry_run
update_mr_note Edit an existing MR comment project dry_run
delete_mr_note Delete an MR comment project dry_run
create_mr_discussion Code-review comment on a specific diff line (requires diff_refs from get_mr_diff) project dry_run
resolve_mr_discussion Mark an MR discussion as resolved or unresolved project dry_run
list_mr_approval_rules List project-level MR approval rules project --
create_mr_approval_rule Create a project-level approval rule (eligible users/groups, branches) project dry_run
update_mr_approval_rule Update an existing approval rule project dry_run
delete_mr_approval_rule Delete an approval rule project dry_run

CI/CD (5 tools)

Tool Description Scope Write
list_pipelines List pipelines for a project (filter by ref, status, etc.) project --
get_pipeline Get pipeline details and jobs project --
get_job_log Fetch the trace/log of a CI job project --
retry_pipeline Retry a failed pipeline project dry_run
cancel_pipeline Cancel a running pipeline project dry_run

Branches & Repository (12 tools)

Tool Description Scope Write
list_branches List branches in a project project --
create_branch Create a branch from a ref project dry_run
list_repository_tree List the files/folders in a repo path project --
get_file Read a file's contents at a given ref project --
list_commits List commits (filter by ref, author, date) project --
create_file Create a new file via the API (commit included) project dry_run
update_file Update a file (optimistic concurrency via last_commit_id) project dry_run
delete_file Delete a file in a single commit project dry_run
commit_files Atomic multi-file commit (create/update/delete/move/chmod) project dry_run
list_protected_branches List protected branches with their access levels project --
protect_branch Protect a branch with push/merge/unprotect access levels project dry_run
unprotect_branch Remove branch protection project dry_run

Iterations (3 tools -- requires GitLab Premium/Ultimate)

Tool Description Scope Write
list_iterations List iterations/sprints (filter by state: upcoming, current, closed) group --
create_iteration Create an iteration group dry_run
update_iteration Update an iteration (title, dates, state) group dry_run

Utilities (20 tools)

Tool Description Scope Write
list_groups Discover accessible groups -- --
list_projects List projects in a group group --
list_group_members List members of a group group --
add_group_member Add a user to a group with an access level group dry_run
add_project_member Add a user to a project with an access level project dry_run
update_member_access_level Change a member's access level (group or project) group/project dry_run
remove_member Remove a user from a group or project group/project dry_run
list_labels List labels for a group group --
create_label Create a label group dry_run
update_label Update a label (name, color, description) group dry_run
delete_label Delete a label group dry_run
list_boards List issue boards for a group group --
list_workitem_statuses List available work item statuses (for health filtering) group --
get_work_item_type_id Resolve the global ID of a Work Item type (EPIC, ISSUE, TASK, …) for a namespace group/project --
upload_file Upload a file to a project and return the Markdown snippet to embed project dry_run
search_issues Full-text search issues at project or group scope group/project --
search_merge_requests Full-text search MRs at project or group scope group/project --
search_blobs Full-text search code/file content at project or group scope group/project --
search_users Search GitLab users by name or username -- --
get_current_user Check connection (current user info) -- --

A gitlab_setup helper tool is also registered automatically when GITLAB_TOKEN is missing or GITLAB_BASE_URL is invalid — it guides the user through configuration and is not counted in the 100 above.

Example prompts

  • "List my GitLab groups"
  • "Show open epics in group 42"
  • "What's the health status and progress of epic #5?"
  • "Set epic #12 health status to 'needs attention'"
  • "Link epic #3 as blocking issue #45"
  • "List issues labeled bug in the wanadev group"
  • "Create an epic called 'Homepage Redesign' in group 42 with a deadline of April 30"
  • "Which issues are linked to epic #5 in the wanadev group?"
  • "Close issue #15 in project 789"
  • "Who are the members of the wanadev group?"
  • "Show me all open merge requests in group 42"
  • "How much time has been spent on issue #23 in project 456?"
  • "Add a comment on epic #3 in group 42: Specs validated, ready for dev"
  • "What milestones are coming up in the wanadev group?"
  • "List the boards for group 42"
  • "Open an MR from feat/new-login to main in project 789, then request review from @alice"
  • "Show me the diff of MR !42 and summarize the changes"
  • "List the last 5 failed pipelines on main in project 789 and fetch the log of the failing job"
  • "Retry pipeline 12345 in project 789"
  • "Create a release/2026.05 branch from main in project 789"
  • "Read the contents of package.json on branch main in project 789"
  • "Find a user named 'Jean Dupont' and assign them issue #15"
  • "Rebase MR !42 on top of main"
  • "Comment on line 73 of src/auth.ts in MR !42 — this should be wrapped in a try/catch"
  • "Search the wanadev group for issues mentioning 'CVE-2024'"
  • "Show me where processPayment is used across project 789"
  • "Add @alice as Developer (level 30) to the kp1/api project"
  • "Protect main on project 789 — only maintainers can merge, no direct pushes"
  • "Set up a 2-approval rule named 'security' on project 789, applies to all protected branches"
  • "Attach issues #12, #14, and #18 as children of epic #5 in the wanadev group"
  • "Upload screenshot.png to project 789 and embed it in issue #15"

Use cases for project managers

Sprint planning

"List the active milestones in the wanadev group. For each one, show me the open issues and how many are unassigned."

Claude calls list_milestoneslist_issues per milestone → summarizes the gaps. You see at a glance what's on track and what needs attention.

Daily standup prep

"Show me all open MRs in the [project] group that have been waiting for review for more than 3 days. Also list any issues that were closed yesterday."

Claude calls list_merge_requests (state: opened) → list_issues (state: closed, sort: updated_at) → gives you a ready-made standup brief.

Epic progress review

"Give me a status report on epic #12 in group wanadev: how many issues are done vs. open, what's the total time spent, and list the latest comments."

Claude chains get_epiclist_epic_issues → reads time_stats from each issue → list_epic_notes → returns a structured progress report.

Cross-group dashboard

"Compare the open issue count across my three groups: wanadev, [project], and infra. Which group has the most overdue issues?"

Claude calls list_groupslist_issues for each group with due date filtering → builds a comparison table.

Quick issue triage

"In the [project] group, find all issues labeled 'urgent' with no assignee. Assign them to @jean and add a comment saying 'Triaged in weekly review'."

Claude calls list_issues (labels: urgent) → for each unassigned issue, dry-runs update_issue (assignee) + add_issue_note → shows you the plan → you confirm → done.

Milestone closure

"Close milestone 'Sprint 14' in group wanadev. Before that, show me any issues still open in it."

Claude calls list_issues (milestone: Sprint 14, state: opened) → warns you about remaining items → dry-runs close_milestone → you confirm.

Development

git clone https://github.com/wanadev/gitlab-mcp.git
cd gitlab-mcp
npm install
npm run build       # Build ESM (tsc)
npm run typecheck   # TypeScript type checking
npm run dev         # Build in watch mode

Notes

  • issue_id vs issue_iid -- add_issue_to_epic requires the global issue ID (not the #iid displayed in the project). Both list_issues and list_epic_issues return both values.
  • Read-only mode -- With GITLAB_READ_ONLY=true, any create/update/close attempt returns a clear error.
  • 403 on epics -- Epic endpoints require a GitLab Premium or Ultimate license.
  • Multi-group workflow -- You can work across several groups in a single conversation. The LLM will call list_groups to discover them, then pass the right group_id to each tool.
  • GitLab CE / Free support -- The server introspects your GitLab instance at startup and detects whether Issue.weight / Issue.epic are available (Premium/Ultimate-only fields). On Free/CE, those fields are silently omitted from queries and mutations, so all issue tools work — only epic-specific features remain Premium. The detected tier is logged at startup: [..., Premium/Ultimate] or [..., Free/CE].

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors