# An MCP review gate: exposing the whole pipeline as a tool an agent can call.

> commitbrief mcp runs an MCP server over stdio — stdlib-only, zero new dependencies — that exposes one review tool. The agent gets the exact same pipeline you get from the CLI, because it reuses the CLI's review path verbatim.

Published September 28, 2026 by CommitBrief (https://commitbrief.com)

Canonical URL: https://commitbrief.com/blog/mcp-review-gate/
Tags: mcp, agents, integration

---

Coding agents are increasingly the thing writing the diff. If an agent authored the change, the most useful place for a review is *inside the agent's loop* — a tool it can call before it declares the work done, not a separate step a human remembers to run afterwards. The [previous post](/blog/reviewing-against-your-architecture) was about what goes into a review; this one is about a new way to *invoke* one.

`commitbrief mcp` runs an [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server over stdio. Point any MCP client — Claude Desktop, an editor agent, your own harness — at it, and the client gets a `review` tool it can call with the same arguments you'd pass on the command line.

```jsonc
// An MCP client's server config
{
  "mcpServers": {
    "commitbrief": { "command": "commitbrief", "args": ["mcp"] }
  }
}
```

## One tool, the real pipeline

The server exposes exactly one tool — `review` — with the arguments that matter:

- `staged` / `unstaged` / `diff` — what to review (the same scope choices the CLI has)
- `provider` / `model` — override the provider or model for this call
- `fail_on` / `min_severity` — the severity gate and the display floor
- `no_flaky` — skip the [flaky-test pre-pass](/blog/catching-flaky-tests-before-merge) for this call

The important part isn't the argument list — it's what happens behind it. The tool **reuses the CLI's review path verbatim.** It doesn't reimplement reviewing for agents; it drives the exact same `runReview` the terminal command does, with `--json` and `--quiet` forced on, and captures the schema-v1 JSON into a buffer. So the agent's review goes through every stage your terminal review does: the three-layer file filter, the pre-send `.commitbrief/` guard, the secret scan, the cost preflight, the response cache, the flaky detector, and the signal-control stage. No fork, no "agent-lite" variant that drifts out of sync. What you'd get from `commitbrief --staged --json` is what the agent gets.

The tool returns the structured findings plus a short text summary. Two deliberate choices about how it reports:

- **`--fail-on` is reported, not thrown.** If the review trips the severity gate, that shows up *in the summary text* the agent reads — not as a tool error. An agent should see "3 findings at or above high" as information to act on, not as a tool that failed to run.
- **Real failures surface as errors.** A provider outage, a bad diff, a missing key — those come back as MCP `isError` content, because those genuinely are the tool failing.

## Stdlib-only, on purpose

The whole MCP server is built on the standard library — `encoding/json` for the messages, `bufio` for line framing — speaking JSON-RPC 2.0 (`initialize`, `tools/list`, `tools/call`, `ping`) on protocol version `2024-11-05`. **No MCP SDK, zero new dependencies.**

That was a considered choice, not stubbornness. CommitBrief is [GPL-3.0 and careful about its dependency tree](/blog/api-freeze-v1) — every dependency is a license to audit and a supply-chain surface to trust. The MCP wire protocol at the level this server needs is a few well-specified JSON-RPC methods over newline-delimited stdio; wrapping the standard library around that is less code than integrating and tracking an SDK, and it can't rot when the SDK ships a breaking change. The protocol layer lives in its own package and takes the review tool as an injected handler, so it doesn't reach back into the CLI — the seam stays clean.

## Why one tool and not ten

It would be easy to expose a dozen tools — `configure`, `set_provider`, `clear_cache`, `run_flaky`. I didn't, because a review tool the agent invokes right before it finishes is the entire high-value surface, and every additional tool is more for the model to misuse. One tool with the right arguments is a smaller, sharper contract than a toolbox the agent has to reason about. If a real use case demands another tool later, it's an additive change behind the same injected-handler seam; until then, the surface stays minimal.

The effect is that a review becomes something an agent can gate itself on. An agent that just wrote a feature can call `review` with `fail_on: "high"`, read the findings back, and decide whether to fix-and-recheck before handing the work to you — the [zeroth reviewer](/blog/force-multiplier-manifesto) running inside the loop that produced the code.

The next post takes the review outward instead of inward — off your machine and onto a GitHub pull request, posted as inline comments with a verdict, straight from the terminal.