# Report Stale GitLab Merge Requests

Yes. An agent reads open merge requests across a GitLab group and reports which wait on review, fail their pipeline or have conflicts, oldest first.

[Run this on Rush](https://cloud.getrush.ai/run/merge-request-report/gitlab/).

## What the agent does

The run reads GitLab through GitLab's own MCP server, `https://gitlab.com/api/v4/mcp`, the GitLab entry in the Rush connector catalog. Connect it once with `POST /me/connections {"type": "mcp", "name": "gitlab", "url": "https://gitlab.com/api/v4/mcp", "auth": {"mode": "oauth"}}` and finish the GitLab sign-in from the `authorize_url`. The agent then sees what that GitLab account sees. Nothing is cloned: the request has no `resources`, because the work is reading merge request state, not code.

The agent lists open merge requests for the whole group with the server's `list_merge_requests` tool, passing the group rather than one project and `state` set to opened, and paging until the list ends. Drafts are kept in a separate section, since a draft waiting a month is a different problem from a ready merge request waiting a month. For each one it records the project, author, assigned reviewers, labels, the time it was opened and the time of its last update.

Then it reads each merge request in more detail with `get_merge_request`, asking for one facet at a time: `pipelines` to get the status of the latest pipeline on the head commit, `approvals` to see who has approved and whether the required count is met, and `conflicts` when the merge status says the branch cannot be merged cleanly. `notes` show the last comment and who wrote it, which separates "waiting for the author to answer review" from "nobody has looked".

With that, each merge request goes into exactly one state, checked in order: has conflicts, failing pipeline, approved but unmerged, waiting for review. A merge request that both conflicts and fails is listed under conflicts, because that has to be fixed first. Age is counted from when it was opened, and the time since the last activity is shown beside it. The agent calls none of the tools that write, such as `save_note`, `save_merge_request_review` or `accept_merge_request`.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Use the GitLab connection to read every open merge request across the group my-group and its subgroups. Write merge-requests.md grouping them into: has conflicts, failing pipeline (latest pipeline on the head commit), approved but unmerged, waiting for review, and drafts. For each give the project, title with link, author, reviewers, age in days since opened, days since last activity and the last commenter, oldest first within each group. End with each reviewer and how many merge requests wait on them. Change nothing: no comments, approvals, merges or pipeline retries.",
  "connections": [
    "gitlab"
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The session returns `merge-requests.md` as an artifact. It opens with a count per state, then one table per state with the project, the merge request title linked to GitLab, author, reviewers, age, days since the last activity and who spoke last. The closing section lists each reviewer with the merge requests waiting on them, which is usually the part a lead reads first.

Every state is backed by a tool call kept in the session's transcript: the pipeline status, the approvals and the merge status the agent read. If a merge request looks misfiled, the transcript shows what GitLab returned for it at the time. Merge requests change by the hour, so treat the report as a snapshot from when the session ran, and check a merge request's page before chasing its author.

## Run it on every Monday morning

Stuck reviews build up quietly, so this report is most useful on a fixed day. A Project automation with a weekly schedule can send the request every Monday before stand-up, or a GitLab scheduled pipeline can call a small job of yours that posts it to `POST /o/{org}/sessions` with the API key.

When the `run.completed` webhook arrives, your server reads the artifact from the session and posts the reviewer section to the team's chat. The same session can take a follow-up during the week, such as asking for just one project's merge requests, without reading the whole group again.

## Why run it on Rush?

GitLab's merge request list can filter by state or reviewer, but not tell you which open merge request is held up by a red pipeline versus a missing approval across forty projects. Doing that by hand means opening each one. The agent opens each one, in its own sandbox, and keeps the answer GitLab gave for every merge request in the transcript.

The run needs no checkout and no laptop session left open, and each group gets its own session, so a platform team can run the report for several groups at once up to the key's concurrent run limit. The prompt rules out writes, and the transcript lists every tool the agent called, so you can confirm nothing in GitLab changed.

## Frequently asked questions

### Does this work with self-managed GitLab?

The catalog entry points at gitlab.com. A self-managed instance with the MCP server enabled has its own address under `/api/v4/mcp`; connect that URL instead with the same `POST /me/connections` call and name it on the run.

### Will it comment on or ping the authors?

No. The prompt says change nothing, and the agent only calls listing and reading tools. If you want reminders posted, ask for it in a follow-up and review the list first.

### How does it decide a pipeline is failing?

It reads the latest pipeline for the merge request's head commit. An older failed pipeline that a newer push fixed does not count. A pipeline still running is reported as running, not failing.

### Can it cover only some projects?

Yes. Name the projects in the prompt, or a subgroup instead of the top group. The agent passes the narrower scope to `list_merge_requests`.
