approve_merge_request
Approve a merge request
Run GitLab from the agent — merge requests and their review threads, issues, branches, files, CI lint and the settings around them.
LABSCO SUMMARY
What it takes off you is the click path through a merge request: the agent lists the changed files, pulls diffs for the ones that matter, leaves draft notes as it reads, publishes them in one pass with a reviewer state, and resolves the threads that got fixed. Issues, branches and CI lint sit behind the same token, and the permission mode decides how far it can go.
A wide GitLab server built around the review loop. Merge requests are the deepest part of it: diffs by file or by version, threads resolved, draft notes held back and published together, approvals and merges. It speaks stdio for local clients, SSE for older ones, and Streamable HTTP when you run it as a shared server.
npx on your PATH and a GitLab personal access token in GITLAB_PERSONAL_ACCESS_TOKEN, scoped api or read_api. GITLAB_API_URL points at the instance and defaults to https://gitlab.com/api/v4, so a self-managed GitLab means setting it. Inside GitLab CI, GITLAB_JOB_TOKEN can stand in for the personal token; GITLAB_USE_OAUTH=true swaps the token for a browser sign-in instead.
One command plus a key — npm install -g @zereight/mcp-gitlab, then supply credentials
USE CASES
List the changed files first, pull the diffs worth reading, write comments as drafts, then publish the whole set with a reviewer state attached.
Who still has to approve, the approval itself, and the merge — with squash and source-branch removal — without opening the web UI.
Blame maps a range of lines to the commits that last touched them, and the commit and its diff explain what that change was for.
The issues assigned to you come back in one call, and small description edits go as a patch rather than a full rewrite.
Start the server with GITLAB_PERMISSION_MODE=modify — create and update stay available, every delete tool disappears from the list.
Validate the YAML you are about to commit, or the .gitlab-ci.yml already in the project, against the project's own CI settings.
Counted once with only startup setup. Other versions, modes or optional credentials may expose a different list.
approve_merge_requestApprove a merge request
bulk_publish_draft_notesPublish all draft notes for a merge request. Optionally sets reviewer_state and posts a summary note (GitLab 19.2+). Can set reviewer_state even with no drafts.
create_branchCreate a new branch
create_commit_statusCreate or update the status of a commit
create_draft_noteCreate a draft note for a merge request
create_groupCreate new group or subgroup
create_issueCreate a new issue
create_issue_emoji_reactionAdd an emoji reaction to an issue (e.g. thumbsup, rocket, eyes)
create_issue_linkCreate an issue link between two issues
create_issue_noteAdd a note to an issue, optionally replying to a discussion thread
create_issue_note_emoji_reactionAdd an emoji reaction to an issue note. Pass discussion_id for discussion thread replies.
create_labelCreate a new label in a project
create_merge_requestCreate a new merge request
create_merge_request_discussion_noteAdd a new discussion note to an existing merge request thread
create_merge_request_emoji_reactionAdd an emoji reaction to a merge request (e.g. thumbsup, rocket, eyes)
create_merge_request_noteAdd a new note to a merge request
create_merge_request_note_emoji_reactionAdd an emoji reaction to a merge request note. Pass discussion_id for discussion thread replies.
create_merge_request_threadCreate a new thread on a merge request
create_noteCreate a new note (comment) to an issue or merge request
create_or_update_fileCreate or update a file in a GitLab project
create_repositoryCreate a new GitLab project
delete_branchDelete branch from project
delete_draft_noteDelete a draft note
delete_issueDelete an issue
delete_issue_emoji_reactionRemove an emoji reaction from an issue
delete_issue_linkDelete an issue link
delete_issue_note_emoji_reactionRemove an emoji reaction from an issue note. Pass discussion_id for discussion thread replies.
delete_labelDelete a label from a project
delete_merge_request_discussion_noteDelete a discussion note on a merge request
delete_merge_request_emoji_reactionRemove an emoji reaction from a merge request
delete_merge_request_noteDelete an existing merge request note
delete_merge_request_note_emoji_reactionRemove an emoji reaction from a merge request note. Pass discussion_id for discussion thread replies.
discover_toolsDiscover and activate additional tool categories for this session. Available categories: merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities. Already-active categories are listed in the response.
download_attachmentDownload an uploaded file from a project (images returned as base64; use local_path to save to disk)
fork_repositoryFork a project to your account or specified namespace
get_branchGet branch details (commit, protection status)
get_branch_diffsGet diffs between two branches or commits
get_ci_catalog_resourceGet details for a GitLab CI/CD Catalog resource, including versions and components
get_commitGet details of a specific commit
get_commit_diffGet changes/diffs of a specific commit
get_draft_noteGet a single draft note from a merge request
get_file_blameGet git blame for a file at a given ref. Each entry maps a contiguous range of source lines to the commit that last changed them (id, author, authored_date, message). Use range_start/range_end to limit blame to specific lines.
get_file_contentsGet contents of a file or directory from a GitLab project
get_issueGet details of a specific issue. Returns a slim milestone by default; set full_response=true for the complete milestone object
get_issue_linkGet a specific issue link
get_labelGet a single label from a project
get_merge_requestGet details of a merge request (mergeRequestIid or branchName required). Set include_summaries=true for deployment/commit/approval summaries
get_merge_request_approval_stateGet merge request approval details including approvers
get_merge_request_conflictsGet the conflicts of a merge request
get_merge_request_diffsGet the changes/diffs of a merge request (mergeRequestIid or branchName required)
get_merge_request_file_diffGet diffs for specific files from a merge request (mergeRequestIid or branchName required)
get_merge_request_noteGet a specific note for a merge request
get_merge_request_notesList notes for a merge request
get_merge_request_versionGet a specific version of a merge request
get_namespaceGet details of a namespace (user or group) by ID or path. Groups are namespaces with kind='group'.
get_projectGet details of a specific project
get_project_eventsList events for a project (before/after: YYYY-MM-DD)
get_protected_branchGet details of a single protected branch (access levels, force push settings)
get_repository_treeList files and directories in a repository
get_userGet user details by ID
get_usersGet GitLab user details by usernames
health_checkVerify server status and authentication. When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted.
list_branchesList branches in project with search filter
list_ci_catalog_resourcesList GitLab CI/CD Catalog resources/components visible to the user
list_commit_statusesList statuses for a commit
list_commitsList repository commits with filtering options
list_draft_notesList draft notes for a merge request
list_eventsList events for the authenticated user (before/after: YYYY-MM-DD)
list_group_iterationsList group iterations with filtering options
list_group_membersList members of a GitLab group with optional name or username search
list_group_projectsList projects in a group
list_issue_discussionsList discussions for an issue
list_issue_emoji_reactionsList all emoji reactions on an issue
list_issue_linksList all issue links for a specific issue
list_issue_note_emoji_reactionsList all emoji reactions on an issue note. Pass discussion_id for discussion thread replies.
list_issuesList issues (default: created by current user; use scope='all' for all)
list_labelsList labels for a project
list_merge_request_changed_filesList changed file paths in a merge request without diff content (mergeRequestIid or branchName required)
list_merge_request_diffsList merge request diffs with pagination (mergeRequestIid or branchName required)
list_merge_request_emoji_reactionsList all emoji reactions on a merge request
list_merge_request_note_emoji_reactionsList all emoji reactions on a merge request note. Pass discussion_id for discussion thread replies.
list_merge_request_pipelinesList pipelines for a merge request with pagination
list_merge_request_versionsList all versions of a merge request
list_merge_requestsList merge requests (without project_id: user's MRs; with project_id: project MRs)
list_namespacesList all namespaces (users and groups) available to the current user. Filter by kind='group' for groups only.
list_project_membersList members of a GitLab project
list_projectsList projects accessible by the current user
list_protected_branchesList protected branches in a project, supports search filter
list_todosList GitLab to-do items for the current user
mark_all_todos_doneMark all pending GitLab to-do items as done for the current user
mark_todo_doneMark a GitLab to-do item as done
merge_merge_requestMerge a merge request
mr_discussionsList discussion items for a merge request
my_issuesList issues assigned to the authenticated user
protect_branchProtect a repository branch (set push/merge/unprotect access levels)
publish_draft_notePublish a single draft note
push_filesPush multiple files in a single commit
resolve_merge_request_threadResolve a thread on a merge request
search_repositoriesSearch for GitLab projects
unapprove_merge_requestUnapprove a merge request
unprotect_branchRemove protection from a previously protected branch
update_default_branchChange the default branch of a project
update_draft_noteUpdate an existing draft note
update_issueUpdate an issue. Returns a slim confirmation by default; set full_response=true for the complete updated issue object
update_issue_description_patchApply a patch (search/replace or unified diff) to an issue description. Reduces token usage by allowing small changes without sending the full description. Supports dry_run to preview changes and create_note to summarize updates.
update_issue_noteModify an existing issue thread note
update_labelUpdate an existing label in a project
update_merge_requestUpdate a merge request (mergeRequestIid or branchName required)
update_merge_request_discussion_noteUpdate a discussion note on a merge request
update_merge_request_noteModify an existing merge request note
update_projectUpdate project settings such as description, visibility, default branch, and feature access levels
upload_markdownUpload a file for use in markdown content
validate_ci_lintValidate provided GitLab CI/CD YAML content for a project
validate_project_ci_lintValidate an existing .gitlab-ci.yml configuration for a project
verify_namespaceVerify if a namespace path exists. Use parent_id to scope the check to a specific parent namespace — required for nested namespaces where the same path may exist under different parents.
whoamiGet current authenticated user details
BEFORE YOU INSTALL
116 tools when we connected; the project documents 217. The rest sit in opt-in groups such as Pipelines, Wiki, Releases and Variables; enable them with GITLAB_TOOLSETS=all or a group list, or call discover_tools. GITLAB_PERMISSION_MODE=readonly hides every write tool.
INSTALLATION
npm install -g @zereight/mcp-gitlab{
"inputs": [
{
"type": "promptString",
"id": "gitlab-token",
"description": "GitLab Personal Access Token",
"password": true
}
],
"servers": {
"zereight.gitlab-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@zereight/mcp-gitlab@latest"
],
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "${input:gitlab-token}",
"GITLAB_API_URL": "https://gitlab.com/api/v4",
"GITLAB_PERMISSION_MODE": "full"
}
}
}
}claude mcp add gitlab --transport stdio --scope local --env GITLAB_PERSONAL_ACCESS_TOKEN=<YOUR_GITLAB_PERSONAL_ACCESS_TOKEN> --env GITLAB_API_URL=https://gitlab.com/api/v4 -- zereight-mcp-gitlab{
"mcpServers": {
"gitlab": {
"command": "zereight-mcp-gitlab",
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "<YOUR_GITLAB_PERSONAL_ACCESS_TOKEN>",
"GITLAB_API_URL": "https://gitlab.com/api/v4",
"GITLAB_READ_ONLY_MODE": "false"
}
}
}
}codex mcp add gitlab --env GITLAB_PERSONAL_ACCESS_TOKEN=<YOUR_GITLAB_PERSONAL_ACCESS_TOKEN> --env GITLAB_API_URL=https://gitlab.com/api/v4 -- zereight-mcp-gitlab{
"mcpServers": {
"gitlab": {
"command": "zereight-mcp-gitlab",
"args": [
"--token=<YOUR_GITLAB_TOKEN>",
"--api-url=https://gitlab.com/api/v4"
],
"tools": [
"*"
]
}
}
}docker run -i --rm -e HOST=0.0.0.0 -e GITLAB_PERSONAL_ACCESS_TOKEN=<YOUR_GITLAB_PERSONAL_ACCESS_TOKEN> -e GITLAB_API_URL="https://gitlab.com/api/v4" -e GITLAB_PERMISSION_MODE=readonly -e GITLAB_TOOLSETS=wiki,milestones,pipelines -e SSE=true -e SSE_AUTH_TOKEN=<YOUR_SSE_AUTH_TOKEN> -p 3333:3002 zereight050/gitlab-mcp{
"mcpServers": {
"gitlab": {
"type": "sse",
"url": "http://localhost:3333/sse",
"headers": {
"Authorization": "Bearer <YOUR_SSE_AUTH_TOKEN>"
}
}
}
}docker run -i --rm -e HOST=0.0.0.0 -e REMOTE_AUTHORIZATION=true -e GITLAB_API_URL="https://gitlab.com/api/v4" -e GITLAB_PERMISSION_MODE=readonly -e GITLAB_TOOLSETS=wiki,milestones,pipelines -e STREAMABLE_HTTP=true -p 3333:3002 zereight050/gitlab-mcp{
"mcpServers": {
"gitlab": {
"type": "streamable-http",
"url": "http://localhost:3333/mcp",
"headers": {
"Authorization": "Bearer <YOUR_TOKEN>"
}
}
}
}Clients spell the "type" value differently: Claude Code and VS Code use "http", Cline uses "streamableHttp", and Roo Code uses "streamable-http". Claude Desktop does not accept a URL entry in its config file.