Every PR rots in the queue for the same reason: humans don’t have the bandwidth to read every diff carefully. A code review bot solves the boring half — null checks, missing tests, ADR drift, secrets, unobvious naming — so the human reviewer can spend their attention on architecture and intent. The blocker isn’t the model. It’s wiring GitHub, your tracker, and your chat into a clean tool loop.
A useful reviewer needs: list PRs, read PR diff, read file content at a commit, create a review, create line comments, optionally label the PR, optionally request changes. Mapping these to a typed tool surface the model can call without inventing parameter names is the actual integration work.
Teams that ship hand-roll a thin wrapper, watch it drift when GitHub renames a field, and end up maintaining a tiny SDK forever. None of that work is differentiated. None of it is what your reviewer policy should be optimizing for.
wmcp.sh exposes the GitHub API as schema-valid MCP tools via /integration/github, so your agent calls pulls.get and pulls.createReviewComment by name with typed args — and you spend your week on the review prompt instead. wmcp.sh is not affiliated with GitHub.
1. PR webhook. Your GitHub App fires on pull_request.opened and pull_request.synchronize. The handler enqueues the repo + PR number with a unique correlation ID so reviews are idempotent.
2. Tool gateway (wmcp.sh). The runner pulls MCP tools for /integration/github (PR + file + review methods), Linear (for non-blocking follow-ups), and Slack (for the summary post).
3. Reasoning loop. The agent fetches the diff, fetches related file context at the head SHA, drafts a structured review (summary + line comments + tags), and submits it as COMMENT review state (never APPROVED).
4. Track + notify. Non-blocking findings become Linear issues with a backlink to the line. A Slack message lands in the team channel with the summary and PR link.
| Capability | System | How wmcp.sh wires it |
|---|---|---|
| Read PR + diff | GitHub | ✅ /integration/github — pulls.get, pulls.listFiles |
| Read file at commit SHA | GitHub | ✅ repos.getContent with ref parameter |
| Submit review + line comments | GitHub | ✅ pulls.createReview (scoped to COMMENT state) |
| File follow-up tickets | Linear | ✅ OpenAPI adapter — issues.create only |
| Post summary | Slack | ✅ /integration/slack |
| Look up ADR / standards | Notion or repo /docs | ✅ /integration/notion or generic fetch |
Python sketch. Receives a repo + PR number; emits a review with line-anchored comments. Never approves, never merges.
import os, httpx
from anthropic import Anthropic
client = Anthropic()
WMCP = "https://wmcp.sh"
def tools_for(url):
return httpx.get(f"{WMCP}/api/v1/tools", params={"url": url}).json()["tools"]
tools = (
tools_for("https://api.github.com")
+ tools_for("https://api.linear.app")
+ tools_for("https://slack.com/api")
)
repo = os.environ["REPO"] # e.g. "acme/api"
pr = os.environ["PR_NUM"]
msg = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
tools=tools,
messages=[{"role": "user",
"content": f"Review PR {repo}#{pr}. Read the diff and related files. "
"Submit a review (COMMENT state, never APPROVE). For non-blocking findings, "
"file a Linear issue. Post a one-line summary to #eng-reviews."}],
)
print(msg.content)
pulls.* and repos.getContent onlypulls.createReviewComment, which wmcp.sh exposes through /integration/github.Custom rules + ADR adapter + hosted MCP at mcp.yourbrand.com + verified badge. Starter $499 one-time · Managed Retainer $999/mo · Enterprise $4,999+/mo.