Gitlab Review
AI-assisted GitLab merge request code review with human approval gate. Uses GraphQL for notes and MR metadata, REST fallback for diff content and approve/unapprove (no CLI dependencies). Designed to pair with @dougschaefer/writing-voice for tone-consistent reviews driven from an agent harness.
Authentication
Requires a GitLab personal access token with api scope, stored in a
swamp vault.
Methods
- get_mr_diff — Fetch MR metadata (GraphQL) and file diffs (REST)
- analyze — Store an AI-generated review draft
- edit_draft — Revise the draft (versioned, retains history)
- update_review — Edit an existing comment via GraphQL updateNote
- approve_mr — Approve the MR without posting a comment (REST)
- unapprove_mr — Remove approval / request changes (REST; idempotent — a never-approved MR is a no-op)
- post_review — Post draft via GraphQL createNote, optionally approve/unapprove
- post_line_comment — Post a comment positioned on a specific file/line in the diff (REST discussions)
2026.08.07.1
Added: post_line_comment method — posts a comment positioned on a specific
file/line in an MR diff (GitLab REST discussions API), for the standard
diff-level code-review UX that post_review (top-level notes only) doesn't
cover. Fetches the MR's current diff versions to build the required
base_sha/start_sha/head_sha position, then creates a positioned
discussion thread. Accepts newLine and/or oldLine (at least one required)
to comment on added, deleted, or context lines. New lineComment resource
records discussionId, noteId, and the file/line position of each posted
comment, keyed per file/line so multiple comments on the same MR are stored
as separate instances (lifetime: 30d, garbageCollection: 20, additive —
no changes to existing resources).
2026.07.18.1
Added: An upgrades array entry (no-op) to review.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.
2026.07.08.1
Fixed:
unapprove_mrandpost_review action=request_changesare now idempotent. GitLab's unapprove endpoint returns HTTP 404 when the caller has no approval to remove; that is the desired end state for "request changes", not an error. A never-approved MR no longer fails the call — the comment still posts and the MR is left unapproved. Non-404 errors still propagate.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| host | string | GitLab hostname (e.g. gitlab.example.com) |
| token | string | GitLab personal access token |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path (e.g. mygroup/myproject) |
| iid | number | Merge request IID |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| body | string | Review comment body (markdown) |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| body | string | Updated review comment body (markdown) |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| noteId | number | Note ID to update |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| Argument | Type | Description |
|---|---|---|
| project | string | Project path |
| iid | number | Merge request IID |
| body | string | Comment body (markdown) |
| newPath | string | File path on the new side of the diff |
| oldPath? | string | File path on the old side of the diff (defaults to newPath — |
| newLine? | number | Line number on the new side (added/changed lines) |
| oldLine? | number | Line number on the old side (deleted lines) |
Resources
2026.07.18.1
Added: An upgrades array entry (no-op) to review.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.
2026.07.08.1
Fixed:
unapprove_mrandpost_review action=request_changesare now idempotent. GitLab's unapprove endpoint returns HTTP 404 when the caller has no approval to remove; that is the desired end state for "request changes", not an error. A never-approved MR no longer fails the call — the comment still posts and the MR is left unapproved. Non-404 errors still propagate.
2026.07.08.1
Fixed:
unapprove_mrandpost_review action=request_changesare now idempotent. GitLab's unapprove endpoint returns HTTP 404 when the caller has no approval to remove; that is the desired end state for "request changes", not an error. A never-approved MR no longer fails the call — the comment still posts and the MR is left unapproved. Non-404 errors still propagate.
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License declared1/1earned
- Verified public repository2/2earned