Skip to content

Code Review Workflow Examples

These step-by-step workflows cover the full merge request review cycle: finding MRs that need your attention, reading their diffs, checking approval state, leaving notes and threaded discussions, and finally merging or rebasing. Each example pairs the prompt you type with the exact catalog action the server runs, written as domain.action → parameters: on the default dynamic surface that is the action you pass to gitlab_execute_action, and with GITLAB_MCP_TOOL_SURFACE=meta it is the action of the gitlab_<domain> meta-tool, so you can reuse the call directly. Diffs, notes, discussions and draft notes live in the mr_review domain (gitlab_mr_review on the meta surface), the rest of the MR lifecycle in merge_request.

This is the core review loop: list the open MRs assigned to you, read the file changes, post review feedback, and approve once the code looks good. The diagram traces a single MR (!42) through that sequence.

GitLab APIMCP ServerAI AssistantUserGitLab APIMCP ServerAI AssistantUser"Review MR !42"merge_request.listGET /projects/:id/merge_requestsMR listOpen MRsmr_review.changes_getGET /projects/:id/merge_requests/:iid/changesDiff dataFile changesmr_review.note_createPOST /projects/:id/merge_requests/:iid/notesmerge_request.approvePOST /projects/:id/merge_requests/:iid/approve"Review complete, MR approved"

Prompt: “Show me all merge requests assigned to me for review in the backend project”

merge_request.list → project_id: "my-group/backend",
reviewer_username: "johndoe", state: "opened"

Returns: MR titles, authors, branches, labels, and review status.

Prompt: “Show me the file changes in MR !42”

mr_review.changes_get → project_id: "my-group/backend", merge_request_iid: 42

Returns: list of changed files with additions, deletions, and full diffs.

Prompt: “Who has approved MR !42 and who still needs to approve?”

merge_request.approval_state → project_id: "my-group/backend",
merge_request_iid: 42

Returns: approval rules, required approvals, current approvals, and eligible approvers.

Prompt: “Approve merge request !42 in the backend project”

merge_request.approve → project_id: "my-group/backend",
merge_request_iid: 42

There is no separate “AI review” tool. AI-powered review happens when the assistant reads an MR’s diff with mr_review.changes_get, reasons over the code, and then writes its findings back as notes or threaded discussions. A typical request, “Read the changes in MR !42 and flag any error-handling or security issues”, chains the read action above with the mr_review.note_create and mr_review.discussion_create actions below, all within a single conversation.


Share review feedback directly on the MR. Post a single inline comment, open a threaded discussion for a larger topic, find threads that are still unresolved, or stage draft notes to publish your whole review at once.

The three comment types behave differently, and picking the wrong one is the most common review mistake:

TypeActionResolvable?Visible immediately?Use it for
Notemr_review.note_createNoYesA single standalone remark
Discussionmr_review.discussion_createYesYesFeedback that must be resolved before merge
Draft notemr_review.draft_note_createYes, once publishedNo — staged until publishedA multi-comment review published in one batch

Only discussions count toward the unresolved-threads gate. Draft notes keep the author from receiving one notification per comment while you work through a large MR.

Prompt: “Add a comment to MR !42 saying ‘The error handling in auth.go needs a retry mechanism’”

mr_review.note_create → project_id: "my-group/backend",
merge_request_iid: 42, body: "The error handling in auth.go needs a retry mechanism"

Prompt: “Start a discussion on MR !42 about the database migration strategy”

mr_review.discussion_create → project_id: "my-group/backend",
merge_request_iid: 42, body: "Let's discuss the database migration strategy..."

Prompt: “Show me all unresolved discussion threads in MR !42”

mr_review.discussion_list → project_id: "my-group/backend",
merge_request_iid: 42

Filter the results for threads where resolved: false to find outstanding review items.

Prompt: “Create a draft review note on MR !42 — I’ll publish all my comments together”

mr_review.draft_note_create → project_id: "my-group/backend",
merge_request_iid: 42, note: "Consider using a context timeout here..."

Draft notes are only visible to you until you publish them all at once with mr_review.draft_note_publish_all.


Drive a merge request through its full lifecycle: open it from a feature branch, rebase it onto the latest target, merge it (optionally squashing), or close it when an approach is superseded.

Prompt: “Create a merge request from branch feature/auth-refactor to main in the backend project”

merge_request.create → project_id: "my-group/backend",
source_branch: "feature/auth-refactor", target_branch: "main",
title: "Refactor authentication module"

Prompt: “Merge MR !42 using squash commit”

merge_request.merge → project_id: "my-group/backend",
merge_request_iid: 42, squash: true

Prompt: “Rebase MR !42 against the latest main branch”

merge_request.rebase → project_id: "my-group/backend",
merge_request_iid: 42

Prompt: “Close MR !99, the approach was superseded by MR !105

merge_request.update → project_id: "my-group/backend",
merge_request_iid: 99, state_event: "close"

Before opening or merging an MR, compare two branches to see exactly what would change. The comparison returns the commits, changed files, and diff statistics between them.

Prompt: “Compare the develop branch with main in the backend project”

repository.compare → project_id: "my-group/backend",
from: "main", to: "develop"

Returns: list of commits, changed files, and diff statistics between the two branches.

On the default dynamic surface the assistant discovers the review action and its schema first, then executes it, so every block above is the action of a gitlab_execute_action call. The two-step pattern is find, then execute:

gitlab_find_action → query: "merge requests waiting for my review"
gitlab_execute_action → action: "merge_request.list", params: { project_id: "my-group/backend", reviewer_username: "johndoe", state: "opened" }

Reading a diff and posting a threaded comment follow the same shape:

gitlab_find_action → query: "merge request diff"
gitlab_execute_action → action: "mr_review.changes_get", params: { project_id: "my-group/backend", merge_request_iid: 42 }
gitlab_execute_action → action: "mr_review.discussion_create", params: { project_id: "my-group/backend", merge_request_iid: 42, body: "Let's discuss the database migration strategy..." }

With GITLAB_MCP_TOOL_SURFACE=meta the same calls go to gitlab_merge_request with action: list and to gitlab_mr_review with action: changes_get and action: discussion_create, each with the parameters nested under params.


Frequently asked questions

How do I review a GitLab merge request with an AI assistant?

A full review is three calls: merge_request.list with reviewer_id finds the MRs waiting on you, mr_review.changes_get fetches the diff so the assistant can read the actual code, and mr_review.discussion_create posts threaded feedback on specific lines. On the default dynamic surface these are the action values for gitlab_execute_action; with GITLAB_MCP_TOOL_SURFACE=meta they are the list action of the gitlab_merge_request meta-tool and the changes_get and discussion_create actions of gitlab_mr_review. Reviewing a twelve-file MR therefore costs three tool calls, not one per file.

What is the difference between a note, a discussion, and a draft note?

A note (mr_review.note_create) is a single standalone comment that posts immediately. A discussion (mr_review.discussion_create) opens a resolvable thread that others can reply to and that shows up in the unresolved-threads count gating merge. A draft note (mr_review.draft_note_create) is staged privately and stays invisible to the author until you publish the whole review at once — which is what you want when leaving many comments, so the MR author gets one notification instead of twenty.

How do I find unresolved review threads on a merge request?

Run mr_review.discussion_list for the MR (the discussion_list action of gitlab_mr_review when GITLAB_MCP_TOOL_SURFACE=meta), then filter the returned threads for resolved: false. Notes created with mr_review.note_create are not resolvable and never appear as outstanding items, so only discussions show up here. This is the check to run before merging when the project requires all threads resolved.

Can an AI assistant approve and merge a merge request?

Yes, subject to the same permissions and safeguards as any other mutation. Approval is merge_request.approve and merging is merge_request.merge (the approve and merge actions of gitlab_merge_request on the meta surface). Both are classified as mutating, so they are unavailable under GITLAB_MCP_READ_ONLY=true and return a preview instead of executing under GITLAB_MCP_SAFE_MODE=true. GitLab still enforces its own approval rules — an assistant cannot merge an MR that has not met the project's required approvals.