Disclaimer: This is an independent, community-built recreation of Anthropic's Claude Code Review feature. It is not affiliated with, endorsed by, or connected to Anthropic in any way. The behavior, output format, and agent architecture were reverse-engineered from publicly available screenshots, documentation, and blog posts. This project exists so that individuals and small teams can self-host a similar experience using their own Claude API keys or Claude Code subscriptions, without needing a Teams or Enterprise plan.
A self-hosted GitHub bot that automatically reviews your pull requests using Claude. It finds bugs, security issues, and style problems β then posts inline comments just like a human reviewer would.
Anthropic's managed Code Review costs $15-80+ per review. Real-world benchmarks show it hitting $31 for a 70-line Markdown diff and $78 for a large Go PR β that's potentially $15,000+/month for an active team.
This project gives you the same multi-agent architecture for a fraction of the cost:
| Managed Code Review | This Project (API key) | This Project (subscription) | |
|---|---|---|---|
| Small PR | $15-31 | $5-15 | $0 (included) |
| Large PR | $50-80 | $20-50 | $0 (included) |
| Review time | 20-47 min | 10-30 min | 10-30 min |
| Setup | Toggle in dashboard | Self-host | Self-host |
You get the same review depth β parallel agents, codebase exploration, adversarial verification β running on your own infrastructure.
When you open a PR, the bot:
- Clones your repo and reads the actual code (not just the diff)
- Runs 3 AI agents in parallel β bug finder, security auditor, style checker
- A verification agent double-checks every finding to filter out false positives
- Posts a review with inline comments on the exact lines that need fixing
- When you push fixes and the code is clean, it resolves old threads and approves
You need three things: this repo running on a server, a GitHub App, and a Claude API key.
git clone https://github.com/fantaize/reviewer.git
cd reviewer
npm installGo to console.anthropic.com and create an API key. You'll need this in Step 4.
Alternatively, if you have a Claude Code subscription, you can use that instead (see Authentication below).
This is the part that connects the bot to your repos. Follow these steps exactly:
-
Fill in the basic info:
- App name: Whatever you want (e.g. "My Code Reviewer")
- Homepage URL:
https://github.com(doesn't matter, just needs a URL) - Webhook URL: Your server's public URL followed by
/webhook- If you're running locally, use smee.io β click "Start a new channel", copy the URL, and paste it here. You'll proxy it to localhost later.
- Webhook secret: Generate one by running
openssl rand -hex 20in your terminal. Save this β you'll need it in Step 4.
-
Scroll down to Permissions. Set these exactly:
Permission Access Contents Read-only Pull requests Read & write Issues Read & write -
Scroll down to Subscribe to events. Check these two boxes:
- Pull request
- Issue comment
-
Under "Where can this GitHub App be installed?", select Only on this account.
-
Click Create GitHub App.
-
You'll land on the app settings page. Copy the App ID (it's a number near the top).
-
Scroll down to Private keys and click Generate a private key. A
.pemfile will download. Move it to your project folder:mv ~/Downloads/your-app-name.*.private-key.pem ./private-key.pem
-
Now install the app on your repos. On the same app settings page, click Install App in the left sidebar, then click Install next to your account. Choose "All repositories" or select specific ones.
cp .env.example .envOpen .env and fill in:
GITHUB_APP_ID=123456 # The App ID from Step 3.7
GITHUB_PRIVATE_KEY_PATH=./private-key.pem # Path to the .pem from Step 3.8
GITHUB_WEBHOOK_SECRET=your_secret_here # The secret from Step 3.2
ANTHROPIC_API_KEY=sk-ant-... # Your API key from Step 2That's it. The defaults for everything else are fine.
npm run build
npm startYou should see:
[server] AI Code Reviewer listening on port 3000
If you used smee.io in Step 3, open a second terminal:
npx smee -u https://smee.io/YOUR_CHANNEL_ID -t http://localhost:3000/webhookOpen a pull request on one of the repos you installed the app on. You should see the π reaction appear within a few seconds, and a review will be posted once the analysis is complete (usually 1-3 minutes).
npm run build
docker compose up -dMake sure your .env is filled in and private-key.pem is in the project root. The Docker Compose file handles mounting the key and reading the env.
Set your GitHub App's webhook URL to https://your-server.com/webhook.
npm run build
npm startUse a process manager like pm2 to keep it running:
npm install -g pm2
pm2 start dist/index.js --name reviewer
pm2 save
pm2 startupThe server listens on port 3000 by default (PORT env var). Put nginx or Caddy in front of it for HTTPS:
# nginx
server {
listen 443 ssl;
server_name reviewer.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}# Caddyfile
reviewer.yourdomain.com {
reverse_proxy localhost:3000
}
The bot needs access to Claude to run reviews. Two options:
Set ANTHROPIC_API_KEY in your .env. No login, no expiry, works everywhere.
If you have a Claude Pro/Team subscription with Claude Code:
npm install -g @anthropic-ai/claude-code
claude setup-token # generates an auth token
claude auth status # verify it workedLeave ANTHROPIC_API_KEY blank in .env and the bot will use your subscription. The token persists across restarts but can expire β the bot will warn you on startup if it does.
For Docker with subscription auth, mount the token directory:
volumes:
- ~/.claude:/root/.claude:ro| Variable | Required | Default | Description |
|---|---|---|---|
GITHUB_APP_ID |
Yes | β | Your GitHub App ID |
GITHUB_PRIVATE_KEY_PATH |
Yes | β | Path to .pem private key |
GITHUB_WEBHOOK_SECRET |
Yes | β | Webhook secret for verifying payloads |
ANTHROPIC_API_KEY |
Yes* | β | Claude API key (*or use subscription auth) |
PORT |
No | 3000 |
Server port |
CONFIDENCE_THRESHOLD |
No | 80 |
Min confidence to post a finding (0-100) |
MODEL |
No | claude-opus-4-6 |
Model for analysis agents |
VERIFIER_MODEL |
No | same as MODEL |
Model for verification agent |
EFFORT |
No | max |
Reasoning effort: low / medium / high / max |
REVIEW_MODE |
No | once |
When to review: once, every_push, or manual (@bot review) |
| Mode | Trigger | Description |
|---|---|---|
once |
PR creation | Reviews once when a PR is opened or marked ready for review. Default. |
every_push |
Every push | Reviews on every push to the PR, plus on creation. Resolves old threads when issues are fixed. |
manual |
@bot review |
Only reviews when someone mentions the bot with "review" on the PR. |
Set REVIEW_MODE in your .env:
REVIEW_MODE=once # review once when PR is opened (default)
REVIEW_MODE=every_push # re-review on every push
REVIEW_MODE=manual # only review when someone comments @bot reviewDrop a REVIEW.md in any repo's root to customize what the bot looks for:
## Rules
1. All API endpoints must validate input with zod
2. Use `logger.error()` instead of `console.error()`
3. No raw SQL β use the query builder
## Ignore Patterns
- docs/**
- **/*.test.ts
- migrations/**
## Custom Instructions
This is a financial services app. Focus on data validation and auth.once mode (default) β the bot reviews once when a PR is opened or marked ready for review.
every_push mode β the bot reviews on every push. When you fix all the issues and push again, it resolves the old review threads and approves.
manual mode β the bot only reviews when you mention it on a PR. The bot name is auto-detected from your GitHub App. You can add instructions after "review":
@my-code-reviewer review focus on the database migration and check for data loss
Each review runs 3 analysis agents + 1 verification agent + 1 summarizer. Default config uses Opus with max reasoning effort for maximum depth.
| PR Size | Estimated Cost |
|---|---|
| Small (<50 lines) | $5-15 |
| Medium (50-500 lines) | $15-30 |
| Large (500+ lines) | $30-50 |
Default config optimizes for maximum review depth (~10-30 minutes per review). Agents get up to 200 turns each with full codebase access including Bash, Read, Grep, and Glob tools.
To reduce costs: set MODEL=claude-sonnet-4-6 and EFFORT=medium.
PR Opened/Updated
β
βΌ
βββββββββββ
β Webhook βββββ Verify signature, skip drafts, dedup
ββββββ¬βββββ
β
βΌ
βββββββββββ
β Clone βββββ Shallow clone at PR head SHA
ββββββ¬βββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β Parallel Analysis β
β βββββββββ ββββββββββββ βββββββββ β
β β Bugs β β Security β β Style β β
β βββββ¬ββββ ββββββ¬ββββββ βββββ¬ββββ β
ββββββββΌβββββββββββΌββββββββββββΌβββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββββββββββββββββββββββ
β Deduplicate Findings β
ββββββββββββββββββ¬βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β Adversarial Verification β
β "Try to DISPROVE each finding" β
ββββββββββββββββββ¬βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β Filter by confidence threshold β
β Rank: severity β confidence β
ββββββββββββββββββ¬βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β Post review body + inline comments β
ββββββββββββββββββ¬βββββββββββββββββββββ
β
(on re-push with 0 findings)
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β Resolve outdated review threads β
β Approve PR β
βββββββββββββββββββββββββββββββββββββββ
Bot doesn't react to PRs:
- Check that the GitHub App is installed on the repo
- Check that your webhook URL is correct and the server is reachable
- Check server logs for incoming webhook events
"Resource not accessible by integration" error:
- You're missing a permission. Go to your GitHub App settings and make sure Contents, Pull requests, and Issues are all set correctly. After changing permissions, you need to accept the new permissions on the installation page.
Reviews fail with auth errors:
- If using API key: check that
ANTHROPIC_API_KEYis set correctly in.env - If using subscription: run
claude auth statusto check. Re-runclaude setup-tokenif expired.
Bot posts no findings on obviously buggy code:
- Try lowering
CONFIDENCE_THRESHOLD(default 80). The verifier is aggressive about filtering. - Try
EFFORT=maxfor more thorough analysis.
Reviews are too expensive:
- Set
MODEL=claude-sonnet-4-6andVERIFIER_MODEL=claude-sonnet-4-6 - Set
EFFORT=medium
src/
βββ index.ts # Express server + webhook endpoint
βββ webhook.ts # PR event handlers + dedup
βββ review.ts # Review pipeline + repo cloning
βββ github.ts # GitHub App auth + API helpers
βββ diff.ts # Unified diff parser
βββ config.ts # REVIEW.md loader
βββ formatter.ts # Findings β GitHub review comments
βββ agents/
βββ types.ts # Shared types
βββ runner.ts # Claude Agent SDK wrapper
βββ bug-finder.ts # Bug detection agent
βββ security.ts # Security audit agent
βββ style.ts # Style/convention checker
βββ verifier.ts # Adversarial verification agent
βββ orchestrator.ts # Parallel dispatch + dedup + rank
MIT