@wanadev/mcp-gitlab
Provides full control over GitLab epics, issues, milestones, iterations, merge requests, code review, pipelines, branches, repository content, labels, boards, members, and governance.
Click on "Deploy 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., "@@wanadev/mcp-gitlab List my GitLab groups"
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.
@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.
Related MCP server: GitLab MCP Server
Quick setup
Prerequisites
Node.js >= 20
A GitLab Personal Access Token (PAT) with the
apiscope (orread_apifor 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
Go to GitLab > Settings > Access Tokens
Create a token with the
apiscopeCopy the token
2. Install
Claude Code (plugin)
/plugin marketplace add wanadev/gitlab-mcp
/plugin install wanadev-gitlab@wanadev-gitlabSet 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 |
| Yes | GitLab Personal Access Token |
| No | GitLab instance URL (default: |
| No | Set to |
Note: There is no
GITLAB_GROUP_IDenvironment variable. Every group-scoped tool takes agroup_idparameter. Uselist_groupsto 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 |
| Returns a summary of the planned action without executing anything on GitLab. |
| 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 (filter by state, search, labels) | group | -- |
| Get epic details by number | group | -- |
| Create an epic | group | dry_run |
| Update an epic (title, description, labels, dates) | group | dry_run |
| Close an epic | group | dry_run |
| Reopen a closed epic | group | dry_run |
| List issues linked to an epic | group | -- |
| Link an issue to an epic | group | dry_run |
| List comments on an epic | group | -- |
| Add a comment to an epic | group | dry_run |
| Edit an existing epic comment | group | dry_run |
| Delete an epic comment | group | dry_run |
Work Items (9 tools -- requires GitLab Premium/Ultimate)
Tool | Description | Scope | Write |
| Get epic widgets: health status, progress, milestone, iteration, linked items | group | -- |
| Associate a milestone with an epic | group | dry_run |
| Set health status on an epic (onTrack / needsAttention / atRisk) | group | dry_run |
| Set health status on an issue (onTrack / needsAttention / atRisk) | project | dry_run |
| Associate an iteration (sprint) with an epic | group | dry_run |
| Link work items (RELATED / BLOCKS / BLOCKED_BY) | group/project | dry_run |
| Resolve the WorkItem global ID for an epic or issue (required by link/unlink) | group/project | -- |
| Attach children (issues/epics) under a parent epic via hierarchy widget | group/project | dry_run |
| Detach children from their current parent | group/project | dry_run |
Issues (11 tools)
Tool | Description | Scope | Write |
| List issues for a group (filter by state, labels, milestone, assignee, iteration) | group | -- |
| List issues for a single project (with iteration filter) | project | -- |
| Get issue details (with time tracking) | project | -- |
| Create an issue | project | dry_run |
| Update an issue | project | dry_run |
| Close an issue | project | dry_run |
| Reopen a closed issue | project | dry_run |
| List comments on an issue | project | -- |
| Add a comment to an issue | project | dry_run |
| Edit an existing issue comment | project | dry_run |
| Delete an issue comment | project | dry_run |
Milestones (10 tools)
Tool | Description | Scope | Write |
| List milestones for a group | group | -- |
| Get milestone details (group) | group | -- |
| Create a group milestone | group | dry_run |
| Update a group milestone | group | dry_run |
| Close a group milestone | group | dry_run |
| List milestones at the project level (the only way on GitLab CE/Free) | project | -- |
| Get a project milestone | project | -- |
| Create a project milestone | project | dry_run |
| Update a project milestone | project | dry_run |
| Close a project milestone | project | dry_run |
Merge Requests (18 tools)
Tool | Description | Scope | Write |
| List merge requests for a group | group | -- |
| Get merge request details | project | -- |
| Open a new MR (source/target branch, title, description) | project | dry_run |
| Update an MR (title, description, labels, assignees, reviewers) | project | dry_run |
| Merge an MR (optionally squash or delete source branch) | project | dry_run |
| Approve an MR | project | dry_run |
| Asynchronously rebase the MR's source branch on top of target | project | dry_run |
| Get the diff/changes for an MR (also returns diff_refs for line-positioned comments) | project | -- |
| List comments on an MR | project | -- |
| Add a comment to an MR | project | dry_run |
| Edit an existing MR comment | project | dry_run |
| Delete an MR comment | project | dry_run |
| Code-review comment on a specific diff line (requires diff_refs from get_mr_diff) | project | dry_run |
| Mark an MR discussion as resolved or unresolved | project | dry_run |
| List project-level MR approval rules | project | -- |
| Create a project-level approval rule (eligible users/groups, branches) | project | dry_run |
| Update an existing approval rule | project | dry_run |
| Delete an approval rule | project | dry_run |
CI/CD (5 tools)
Tool | Description | Scope | Write |
| List pipelines for a project (filter by ref, status, etc.) | project | -- |
| Get pipeline details and jobs | project | -- |
| Fetch the trace/log of a CI job | project | -- |
| Retry a failed pipeline | project | dry_run |
| Cancel a running pipeline | project | dry_run |
Branches & Repository (12 tools)
Tool | Description | Scope | Write |
| List branches in a project | project | -- |
| Create a branch from a ref | project | dry_run |
| List the files/folders in a repo path | project | -- |
| Read a file's contents at a given ref | project | -- |
| List commits (filter by ref, author, date) | project | -- |
| Create a new file via the API (commit included) | project | dry_run |
| Update a file (optimistic concurrency via last_commit_id) | project | dry_run |
| Delete a file in a single commit | project | dry_run |
| Atomic multi-file commit (create/update/delete/move/chmod) | project | dry_run |
| List protected branches with their access levels | project | -- |
| Protect a branch with push/merge/unprotect access levels | project | dry_run |
| Remove branch protection | project | dry_run |
Iterations (3 tools -- requires GitLab Premium/Ultimate)
Tool | Description | Scope | Write |
| List iterations/sprints (filter by state: upcoming, current, closed) | group | -- |
| Create an iteration | group | dry_run |
| Update an iteration (title, dates, state) | group | dry_run |
Utilities (20 tools)
Tool | Description | Scope | Write |
| Discover accessible groups | -- | -- |
| List projects in a group | group | -- |
| List members of a group | group | -- |
| Add a user to a group with an access level | group | dry_run |
| Add a user to a project with an access level | project | dry_run |
| Change a member's access level (group or project) | group/project | dry_run |
| Remove a user from a group or project | group/project | dry_run |
| List labels for a group | group | -- |
| Create a label | group | dry_run |
| Update a label (name, color, description) | group | dry_run |
| Delete a label | group | dry_run |
| List issue boards for a group | group | -- |
| List available work item statuses (for health filtering) | group | -- |
| Resolve the global ID of a Work Item type (EPIC, ISSUE, TASK, …) for a namespace | group/project | -- |
| Upload a file to a project and return the Markdown snippet to embed | project | dry_run |
| Full-text search issues at project or group scope | group/project | -- |
| Full-text search MRs at project or group scope | group/project | -- |
| Full-text search code/file content at project or group scope | group/project | -- |
| Search GitLab users by name or username | -- | -- |
| Check connection (current user info) | -- | -- |
A
gitlab_setuphelper tool is also registered automatically whenGITLAB_TOKENis missing orGITLAB_BASE_URLis 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
bugin 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-logintomainin 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
mainin project 789 and fetch the log of the failing job""Retry pipeline 12345 in project 789"
"Create a
release/2026.05branch frommainin project 789""Read the contents of
package.jsonon branchmainin 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.tsin MR !42 — this should be wrapped in a try/catch""Search the wanadev group for issues mentioning 'CVE-2024'"
"Show me where
processPaymentis used across project 789""Add @alice as Developer (level 30) to the kp1/api project"
"Protect
mainon 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.pngto 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_milestones → list_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_epic → list_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_groups → list_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 modeNotes
issue_idvsissue_iid--add_issue_to_epicrequires the global issue ID (not the#iiddisplayed in the project). Bothlist_issuesandlist_epic_issuesreturn 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_groupsto discover them, then pass the rightgroup_idto each tool.GitLab CE / Free support -- The server introspects your GitLab instance at startup and detects whether
Issue.weight/Issue.epicare 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].
Available Tools
100 toolsadd_epic_noteA
Ajouter un commentaire sur un epic. Par defaut dry_run=true.
Inputs: group_id (required), epic_iid (required), body (required), dry_run.
add_group_memberA
Add a user to a group with a given access level. dry_run=true by default.
Inputs: group_id (required), user_id (required), access_level (required), expires_at, +1 more.
add_issue_noteA
Ajouter un commentaire sur une issue. Par defaut dry_run=true.
Inputs: project_id (required), issue_iid (required), body (required), dry_run.
add_issue_to_epicA
Link an issue to an epic. dry_run=true by default. Requires project_id and issue_iid (not the global issue ID).
Inputs: group_id (required), epic_iid (required), project_id (required), issue_iid (required), +1 more.
add_linked_itemA
Create a link between two work items (epics or issues). Link types: RELATED, BLOCKS, BLOCKED_BY. dry_run=true by default.
Inputs: source_type (required), source_iid (required), target_gid (required), link_type (required), +3 more.
add_mr_noteA
Add a comment to a merge request. dry_run=true by default.
Inputs: project_id (required), mr_iid (required), body (required), dry_run.
add_project_memberA
Add a user to a project with a given access level. dry_run=true by default.
Inputs: project_id (required), user_id (required), access_level (required), expires_at, +1 more.
approve_merge_requestA
Approve a merge request. dry_run=true by default.
Inputs: project_id (required), mr_iid (required), dry_run.
cancel_pipelineA
Cancel a running pipeline. dry_run=true by default.
Inputs: project_id (required), pipeline_id (required), dry_run.
close_epicA
Fermer un epic. Par defaut dry_run=true : retourne un apercu sans fermer. Passer dry_run=false apres confirmation.
Inputs: group_id (required), epic_iid (required), dry_run.
close_issueA
Fermer une issue. Par defaut dry_run=true : retourne un apercu sans fermer. Passer dry_run=false apres confirmation.
Inputs: project_id (required), issue_iid (required), dry_run.
close_milestoneA
Fermer un milestone. Par defaut dry_run=true.
Inputs: group_id (required), milestone_id (required), dry_run.
close_project_milestoneB
Close a project-level milestone. dry_run=true by default.
Inputs: project_id (required), milestone_id (required), dry_run.
commit_filesA
Atomically commit multiple file actions (create/update/delete/move/chmod) in a single commit. dry_run=true by default.
Inputs: project_id (required), branch (required), commit_message (required), actions (required), +2 more.
create_branchA
Create a new branch from a ref. dry_run=true by default.
Inputs: project_id (required), name (required), ref (required), dry_run.
create_epicA
Creer un nouvel epic dans un groupe GitLab. Par defaut dry_run=true : retourne un apercu sans creer. Passer dry_run=false apres confirmation.
Inputs: group_id (required), title (required), description, labels, +3 more.
create_fileA
Create a new file in a repository. Rejects if the file already exists. dry_run=true by default.
Inputs: project_id (required), file_path (required), branch (required), content (required), +3 more.
create_issueA
Creer une nouvelle issue dans un projet. Par defaut dry_run=true : retourne un apercu sans creer. Passer dry_run=false apres confirmation.
Inputs: project_id (required), title (required), description, labels, +7 more.
create_iterationA
Create a new iteration (sprint) in a group. start_date and due_date are required (YYYY-MM-DD). dry_run=true by default.
Inputs: group_id (required), start_date (required), due_date (required), title, +2 more.
create_labelA
Create a label in a group. dry_run=true by default.
Inputs: group_id (required), name (required), color (required), description, +1 more.
create_merge_requestA
Create a new merge request. dry_run=true by default.
Inputs: project_id (required), source_branch (required), target_branch (required), title (required), +6 more.
create_milestoneA
Creer un nouveau milestone. Par defaut dry_run=true : retourne un apercu sans creer. Passer dry_run=false apres confirmation.
Inputs: group_id (required), title (required), description, start_date, +2 more.
create_mr_approval_ruleA
Create a project-level MR approval rule. dry_run=true by default.
Inputs: project_id (required), name (required), approvals_required (required), rule_type, +5 more.
create_mr_discussionA
Create a code-review comment on a specific line in an MR's diff (a 'discussion' in GitLab terminology). Requires the diff_refs (base_sha, head_sha, start_sha) returned by get_mr_diff. Provide exactly one of new_line / old_line. dry_run=true by default.
Inputs: project_id (required), mr_iid (required), body (required), file_path (required), +6 more.
create_project_milestoneA
Create a milestone on a project. dry_run=true by default.
Inputs: project_id (required), title (required), description, start_date, +2 more.
delete_epic_noteA
Delete an existing epic note. This is destructive and cannot be undone. dry_run=true by default.
Inputs: note_id (required), dry_run.
delete_fileA
Delete a file from a repository. dry_run=true by default. This is destructive on the branch.
Inputs: project_id (required), file_path (required), branch (required), commit_message (required), +1 more.
delete_issue_noteA
Delete an existing issue note. This is destructive and cannot be undone. dry_run=true by default.
Inputs: note_id (required), dry_run.
delete_labelA
Delete a label from a group. dry_run=true by default. This is destructive and cannot be undone.
Inputs: group_id (required), label_id (required), dry_run.
delete_mr_approval_ruleA
Delete a project-level MR approval rule. dry_run=true by default. This is destructive.
Inputs: project_id (required), rule_id (required), dry_run.
delete_mr_noteA
Delete an existing MR note. This is destructive and cannot be undone. dry_run=true by default.
Inputs: note_id (required), dry_run.
get_current_userARead-only
Obtenir les informations de l'utilisateur connecte (verifie que le token fonctionne).
Inputs: no named parameters.
get_epicARead-only
Obtenir les details complets d'un epic par son numero (IID).
Inputs: group_id (required), epic_iid (required).
get_epic_widgetsARead-only
Get Work Item widgets for an epic: health status, progress, milestone, iteration, and linked items.
Inputs: group_id (required), epic_iid (required).
get_fileARead-only
Get the content of a file from the repository.
Inputs: project_id (required), file_path (required), ref.
get_issueARead-only
Obtenir les details d'une issue par son projet et son numero (IID).
Inputs: project_id (required), issue_iid (required).
get_job_logARead-only
Get the log output of a CI job (last 2000 chars).
Inputs: project_id (required), job_id (required).
get_merge_requestBRead-only
Obtenir les details d'une merge request par son projet et son numero (IID).
Inputs: project_id (required), mr_iid (required).
get_milestoneARead-only
Obtenir les details d'un milestone par son ID.
Inputs: group_id (required), milestone_id (required).
get_mr_diffARead-only
Get the file changes (diff summary) of a merge request. Returns diff_refs (base_sha/head_sha/start_sha) needed to create line-positioned discussions via create_mr_discussion.
Inputs: project_id (required), mr_iid (required).
get_pipelineARead-only
Get details of a specific pipeline (status, duration, jobs).
Inputs: project_id (required), pipeline_id (required).
get_project_milestoneBRead-only
Get details of a project-level milestone.
Inputs: project_id (required), milestone_id (required).
get_work_item_idARead-only
Resolve the WorkItem global ID (gid://gitlab/WorkItem/N) for an epic or issue. Required as parent_work_item_id / child_work_item_ids on link_work_items and unlink_work_items.
Inputs: item_type (required), iid (required), group_id, project_id.
get_work_item_type_idARead-only
Discover the global ID of a Work Item type (e.g. EPIC, ISSUE, TASK) for a given namespace. Required as workItemTypeId on workItemCreate. IDs vary per GitLab instance and version, so call this once per (namespace, type) and cache the result.
Inputs: namespace_path (required), type_name (required).
link_work_itemsA
Attach one or more work items (issues or epics) as children of a parent work item (epic). Uses the Work Items hierarchy widget — the canonical GitLab 17+ replacement for add_issue_to_epic. Idempotent: existing children of the parent are preserved. Resolve GIDs via get_work_item_id. dry_run=true by default.
Inputs: parent_work_item_id (required), child_work_item_ids (required), dry_run.
list_boardsARead-only
Lister les boards (tableaux kanban) d'un groupe GitLab avec leurs colonnes.
Inputs: group_id (required).
list_branchesCRead-only
List branches of a project. Filter by search term.
Inputs: project_id (required), search.
list_commitsARead-only
List recent commits for a project. Filter by branch or file path.
Inputs: project_id (required), ref, path.
list_epic_issuesBRead-only
Lister les issues rattachees a un epic. Affiche l'ID global et le IID projet de chaque issue.
Inputs: group_id (required), epic_iid (required).
list_epic_notesARead-only
Lister les commentaires d'un epic.
Inputs: group_id (required), epic_iid (required).
list_epicsARead-only
Lister les epics d'un groupe GitLab. Filtrer par etat, recherche textuelle ou labels.
Inputs: group_id (required), state, search, labels, +2 more.
list_group_membersARead-only
Lister les membres d'un groupe GitLab avec leur niveau d'acces.
Inputs: group_id (required), search.
list_groupsARead-only
Lister les groupes GitLab accessibles. IMPORTANT : appelez ce tool en premier quand l'utilisateur mentionne un groupe par son nom, pour obtenir le group_id (ID ou full_path) a passer aux autres tools.
Inputs: search, top_level_only.
list_issue_notesBRead-only
Lister les commentaires d'une issue.
Inputs: project_id (required), issue_iid (required).
list_issuesARead-only
Lister les issues d'un groupe GitLab. Filtrer par etat, recherche, labels, milestone ou assignee.
Inputs: group_id (required), state, search, labels, +5 more.
list_iterationsARead-only
List iterations (sprints) for a GitLab group. Filter by state (upcoming, current, closed) or search by title. Requires GitLab Premium/Ultimate.
Inputs: group_id (required), state, search.
list_labelsARead-only
Lister les labels d'un groupe GitLab avec le nombre d'issues et MRs associees.
Inputs: group_id (required), search.
list_merge_requestsARead-only
Lister les merge requests d'un groupe GitLab. Filtrer par etat, auteur, reviewer, labels ou milestone.
Inputs: group_id (required), state, search, labels, +5 more.
list_milestonesARead-only
Lister les milestones d'un groupe GitLab. Filtrer par etat ou recherche textuelle.
Inputs: group_id (required), state, search.
list_mr_approval_rulesARead-only
List the project-level MR approval rules: who must approve, how many approvals are required, applies-to-which-branches.
Inputs: project_id (required).
list_mr_notesCRead-only
List comments on a merge request.
Inputs: project_id (required), mr_iid (required).
list_pipelinesARead-only
List recent pipelines for a project. Filter by branch (ref) or status (running, pending, success, failed, canceled).
Inputs: project_id (required), ref, status.
list_project_issuesARead-only
List issues for a specific project (not group). Filter by state, labels, milestone, assignee, iteration.
Inputs: project_id (required), state, search, labels, +3 more.
list_project_milestonesARead-only
List milestones at the project level. On GitLab CE/Free, milestones are project-scoped and this is the only way to list them.
Inputs: project_id (required), state, search.
list_projectsARead-only
Lister les projets d'un groupe GitLab. Filtrer par recherche ou statut d'archivage.
Inputs: group_id (required), search, archived.
list_protected_branchesARead-only
List protected branches for a project, with their push/merge/unprotect access levels.
Inputs: project_id (required).
list_repository_treeCRead-only
List files and directories in a project repository.
Inputs: project_id (required), path, ref.
list_workitem_statusesARead-only
List allowed Status widget values for a Work Item type in a group (GitLab 17+). Returns global IDs to pass as status_id to update_issue / update_epic.
Inputs: group_id (required), work_item_type (required).
merge_merge_requestB
Merge a merge request. dry_run=true by default.
Inputs: project_id (required), mr_iid (required), merge_commit_message, squash, +2 more.
protect_branchA
Protect a branch with given push/merge/unprotect access levels. Access levels: 0=NoAccess, 30=Developer, 40=Maintainer, 60=Admin. dry_run=true by default.
Inputs: project_id (required), name (required), push_access_level, merge_access_level, +2 more.
rebase_merge_requestA
Trigger an asynchronous rebase of the MR's source branch on top of the target branch. Useful when CI requires a linear history before merge. dry_run=true by default.
Inputs: project_id (required), mr_iid (required), skip_ci, dry_run.
remove_memberA
Remove a user from a group or project. dry_run=true by default. This is destructive.
Inputs: scope (required), id (required), user_id (required), dry_run.
reopen_epicA
Reopen a closed epic. dry_run=true by default.
Inputs: group_id (required), epic_iid (required), dry_run.
reopen_issueA
Reopen a closed issue. dry_run=true by default.
Inputs: project_id (required), issue_iid (required), dry_run.
resolve_mr_discussionA
Mark an MR discussion as resolved (or unresolved). dry_run=true by default.
Inputs: project_id (required), mr_iid (required), discussion_id (required), resolved, +1 more.
retry_pipelineA
Retry a failed pipeline. dry_run=true by default.
Inputs: project_id (required), pipeline_id (required), dry_run.
search_blobsARead-only
Search code/file contents by full-text query within a project or group. Returns matching blobs with line context. Maps to GET /:scope/:id/search?scope=blobs.
Inputs: scope (required), id (required), query (required), ref.
search_issuesBRead-only
Search issues by full-text query within a project or group. Maps to GET /:scope/:id/search?scope=issues.
Inputs: scope (required), id (required), query (required), state.
search_merge_requestsBRead-only
Search merge requests by full-text query within a project or group. Maps to GET /:scope/:id/search?scope=merge_requests.
Inputs: scope (required), id (required), query (required), state.
search_usersARead-only
Search for GitLab users globally by name or username.
Inputs: query (required).
set_epic_health_statusA
Set the health status of an epic (onTrack, needsAttention, atRisk, or null to clear). dry_run=true by default.
Inputs: group_id (required), epic_iid (required), health_status (required), dry_run.
set_epic_iterationB
Associate an iteration (sprint) with an epic (uses Work Items API). dry_run=true by default.
Inputs: group_id (required), epic_iid (required), iteration_id (required), dry_run.
set_epic_milestoneA
Associate a milestone with an epic (uses Work Items API). dry_run=true by default.
Inputs: group_id (required), epic_iid (required), milestone_id (required), dry_run.
set_issue_health_statusB
Set the health status of an issue (onTrack, needsAttention, atRisk, or null to clear). dry_run=true by default.
Inputs: project_id (required), issue_iid (required), health_status (required), dry_run.
unlink_work_itemsA
Detach one or more work items from their current parent. Per-child operation: each child is unset from whatever parent it currently has (parent_work_item_id is accepted for symmetry but the unlink does not assert it). dry_run=true by default.
Inputs: child_work_item_ids (required), parent_work_item_id, dry_run.
unprotect_branchA
Remove branch protection rules from a branch. dry_run=true by default.
Inputs: project_id (required), name (required), dry_run.
update_epicA
Mettre a jour un epic existant. Par defaut dry_run=true : retourne un apercu sans modifier. Passer dry_run=false apres confirmation.
Inputs: group_id (required), epic_iid (required), title, description, +7 more.
update_epic_noteA
Edit the body of an existing epic note. Get note_id from list_epic_notes. dry_run=true by default.
Inputs: note_id (required), body (required), dry_run.
update_fileA
Update an existing file in a repository. Supports optimistic concurrency via last_commit_id. dry_run=true by default.
Inputs: project_id (required), file_path (required), branch (required), content (required), +4 more.
update_issueA
Mettre a jour une issue existante. Par defaut dry_run=true : retourne un apercu sans modifier. Passer dry_run=false apres confirmation.
Inputs: project_id (required), issue_iid (required), title, description, +9 more.
update_issue_noteA
Edit the body of an existing issue note. Get note_id from list_issue_notes. dry_run=true by default.
Inputs: note_id (required), body (required), dry_run.
update_iterationA
Update an existing iteration (sprint). The REST path uses iteration_iid (per-group), not the global id. dry_run=true by default.
Inputs: group_id (required), iteration_iid (required), title, description, +4 more.
update_labelB
Update a label in a group. dry_run=true by default.
Inputs: group_id (required), label_id (required), new_name, color, +2 more.
update_member_access_levelA
Change a member's access level on a group or project. dry_run=true by default.
Inputs: scope (required), id (required), user_id (required), access_level (required), +2 more.
update_merge_requestA
Update a merge request (title, description, labels, assignees, reviewers). dry_run=true by default.
Inputs: project_id (required), mr_iid (required), title, description, +6 more.
update_milestoneA
Mettre a jour un milestone existant. Par defaut dry_run=true.
Inputs: group_id (required), milestone_id (required), title, description, +3 more.
update_mr_approval_ruleB
Update an existing project-level MR approval rule. dry_run=true by default.
Inputs: project_id (required), rule_id (required), name, approvals_required, +5 more.
update_mr_noteA
Edit the body of an existing MR note. Get note_id from list_mr_notes. dry_run=true by default.
Inputs: note_id (required), body (required), dry_run.
update_project_milestoneB
Update a project-level milestone. dry_run=true by default.
Inputs: project_id (required), milestone_id (required), title, description, +4 more.
upload_fileA
Upload a file to a project so it can be embedded in an issue, MR, or epic description. Returns the Markdown snippet GitLab expects (e.g. ). Provide exactly one of file_path (read from local disk) or file_base64 (inline data). dry_run=true by default.
Inputs: project_id (required), filename (required), file_path, file_base64, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 100 tools
Most tools follow a clear resource+action pattern, so group vs project variants and note/diff/discussion tools are generally distinguishable. However, add_issue_to_epic and link_work_items explicitly overlap (the latter is described as the replacement), and list_issues/list_project_issues plus several similar work-item helpers add some ambiguity.
The vast majority use consistent snake_case verb_noun names (list_*, get_*, create_*, update_*, close_*, delete_*). Minor inconsistencies: `mr` abbreviations vs `merge_request`, and `workitem` vs `work_item` in list_workitem_statuses, prevent a perfect score.
100 tools is an extreme count for an MCP surface, far beyond typical scoped servers, and includes redundant group/project variants plus legacy/new Work Item linking (add_issue_to_epic vs link_work_items). Even though GitLab is broad, this bloated surface is expensive for agents to navigate and many tools feel duplicative rather than earning their place.
Core lifecycles for epics, issues, milestones, MRs, notes, labels, members, branches/files, and pipelines are well covered. Notable gaps remain: no delete issue/epic/milestone, no close/reopen/delete MR, no project member listing, no branch deletion, and no project/group creation, so agents will hit dead ends in some administrative workflows.
Maintenance
Related MCP Connectors
Operate GitHub from your AI assistant: repos, PRs, issues, Actions. Previews and read-only mode.
Plan Salesforce deploys, open pull requests and trigger pipelines from your AI client.
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Writes your daily standup from GitLab or GitHub merge request state: what's ready, blocked or waiting on your review, and why a pipeline is red, read from the failing job log. OAuth sign-in, no API keys; can post the note to Slack, Discord or Google Chat on a schedule.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides GitLab integration for AI assistants using Model Context Protocol, enabling repository operations, file management, issue tracking, merge requests, and branch/tag administration through natural language.2-
- AlicenseNot gradedqualityDmaintenanceEnables interaction with GitLab repositories through secure OAuth 2.0 authentication. Supports comprehensive GitLab operations including merge requests, issues, file management, commits, and branch operations through natural language.18 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables interaction with GitLab repositories through natural language, supporting project management, issue tracking, merge requests, file access, and repository operations. Includes a conversational agent interface with structured outputs for comprehensive GitLab workflow automation.-
- AlicenseNot gradedqualityDmaintenanceEnables GitLab repository management, including branches, merge requests, issues, pipelines, and more through natural language.MIT