Free AI code reviews for every pull request. You bring an API key; Robin reviews show up like a teammate left comments.
- A review when you open a pull request (or when someone comments
/robin) - A short summary plus inline comments on changed lines
- Your choice of AI provider β including free options
When there's nothing worth flagging, Robin says so instead of inventing nitpicks:
You are not signing up for a separate review bot service. The workflow runs in your repo and calls the AI URL you configure.
Using Cursor, Copilot, Claude Code, or similar? Copy this prompt after secrets are set:
Add Robin to this repository.
- Workflow file: .github/workflows/robin.yml
- Reusable workflow: antongulin/robin/.github/workflows/review.yml@main
- Action ref if needed: antongulin/robin@main
- Secrets: LLM_API_KEY, LLM_BASE_URL, LLM_MODEL
- Do NOT use @v0 or any v0 tag
- Do NOT use pull_request_target or synchronize on pull_request
Read AGENTS.md in the robin repo for full rules.
In a terminal, from your project folder, run:
curl -fsSL https://robinreview.dev/install.sh | bashThis creates .github/workflows/robin.yml for you (it never overwrites an existing file).
You still need to add the three secrets β do Steps 1 and 2 below, then commit and push.
You can skip Step 3: the script already did it.
Prefer to do it by hand, or read the script first? It's scripts/install.sh β follow the manual 3 steps instead.
The easiest free setup uses OpenRouter:
- Create an account at openrouter.ai.
- Create an API key in the dashboard.
- Use these values for your GitHub secrets:
| Secret name | Value |
|---|---|
LLM_API_KEY |
Your OpenRouter key (sk-or-...) |
LLM_BASE_URL |
https://openrouter.ai/api/v1 |
LLM_MODEL |
openrouter/free |
Tip
openrouter/free picks a free model for each review β $0 from OpenRouter. OpenRouter rotates which model runs; leave this secret as openrouter/free β the action retries and uses provider fallbacks when a route is temporarily unavailable. You only spend GitHub Actions minutes while the job runs (often a few minutes per review).
- Public repos: standard GitHub-hosted runners are free with no monthly minute cap.
- Private repos: GitHub Free includes about 2,000 minutes/month; GitHub Pro includes about 3,000 minutes/month (check your plan for current limits).
Other providers (OpenAI, Groq, Ollama, etc.) work too. See Supported providers or docs/ADVANCED.md.
- Open your repository on GitHub (not this one).
- Go to Settings β Secrets and variables β Actions.
- Click New repository secret and add each name from the table above.
Warning
Never put API keys inside workflow files, pull request comments, or chat with an AI. Only use GitHub Secrets.
Note
Ran the Quick install one-liner above? Skip this step β the script already created this file. Just finish Steps 1 and 2 (the secrets), then commit and push.
Create a new file in your repo:
Path: .github/workflows/robin.yml
Contents: copy this exactly:
name: Robin
on:
pull_request:
types: [opened, reopened, ready_for_review]
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
jobs:
review:
uses: antongulin/robin/.github/workflows/review.yml@main
secrets:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}Commit and push. Open a pull request β you should see a review within a few minutes.
Important
Use @main for the latest fixes, or pin a release tag (for example @v1 or @v1.0.0) after releases exist. Do not use @v0. See Version pins below.
By default, the reusable workflow runs on GitHub's hosted ubuntu-latest runner:
with:
runner: '"ubuntu-latest"'To run reviews on your own machine, Mac mini, home server, local Linux box, or Coolify runner, pass runner as valid JSON. Use a JSON string for one label or a JSON array for multiple labels.
To create a local runner, go to:
Repository Settings -> Actions -> Runners -> New self-hosted runner
Then add labels such as local, linux, mac, or coolify, and reference those labels through the runner input.
A matching self-hosted runner must be online when GitHub starts the review job. It can be a local runner process (./run.sh), a service (./svc.sh start), a Docker container, or a Coolify-managed service. Docker is optional; it is just one way to run the GitHub Actions runner.
If no matching runner is online, GitHub queues the job until one comes online. It will not fall back to ubuntu-latest unless you add a separate fallback job. For reliable PR reviews, keep an always-on runner available, such as a Mac mini, home server, VPS, or Coolify service. A laptop runner only works while the laptop is awake and the runner process or service is running.
Warning
Self-hosted runners can execute arbitrary workflow code. Do not use them for untrusted public pull requests. Prefer repo-owned private repos or trusted collaborators only. Consider ephemeral runners for stronger isolation.
Local machine runner:
jobs:
review:
uses: antongulin/robin/.github/workflows/review.yml@main
with:
runner: '["self-hosted", "local"]'
secrets:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}Coolify runner:
jobs:
review:
uses: antongulin/robin/.github/workflows/review.yml@main
with:
runner: '["self-hosted", "linux", "coolify"]'
secrets:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}| When | What happens |
|---|---|
| You open a PR | Review runs once automatically |
| You push more commits | No new review (saves time and API usage) |
| You want another review | Comment /robin on the PR (first line of the comment) |
| You want a short overview only | Comment /summary |
| You need help | Comment /help |
/review still works as an alias for /robin. Only people with write access (or higher) on the repo can run these commands by default.
The bot posts a status comment, then a review with severity counts:
## πΉ Robin
π¨ **1 High** | β οΈ **1 Medium** | π‘ **2 Suggestions**
### Summary
Focused change. Main risk: timeout errors are not handled clearly.
### Findings Not Posted Inline
**1 (`src/example.ts:24`)** β Retries exist but timeout failures lack context.The one-line installer also installs a small companion skill into every coding agent
on your machine (Claude Code, Cursor, Copilot, Windsurf, β¦) via the cross-platform
skills CLI β npx skills add https://github.com/antongulin/robin --all --global. It
ships with Robin; there's nothing separate to sign up for. (Skip it with ROBIN_SKILL=0,
or install it by hand with that command.) Once it's there, you can say things like:
"review this PR with Robin" Β· "robin this PR" Β· "fix the Robin feedback and merge"
β¦and the agent drives a bounded review β fix β re-review β merge loop: it waits for Robin's review, fixes only the findings it can verify (skipping noise from weaker free models), replies to each comment, resolves threads, and merges when green β capped at five passes. Source: skills/robin/SKILL.md.
| Provider | LLM_BASE_URL |
LLM_MODEL example |
|---|---|---|
| OpenRouter (free) | https://openrouter.ai/api/v1 |
openrouter/free |
| OpenAI | https://api.openai.com/v1 |
gpt-4o |
| Groq | https://api.groq.com/openai/v1 |
llama-3.3-70b-versatile |
| Ollama (your server) | http://YOUR_SERVER:11434/v1 |
llama3.2 |
GitHubβs servers cannot reach localhost on your laptop. For Ollama at home, use a public server, a tunnel, or a self-hosted runner.
Copy .github/robin.yml.example to .github/robin.yml to set max-diff-size, skip extra paths, and more. Details: docs/ADVANCED.md.
Add .github/code-reviewer.md in your repo:
# Reviewer rules
- Focus on bugs and security, not formatting.
- Ask for tests when business logic changes.| Problem | What to try |
|---|---|
| Workflow fails immediately | Check all three secrets exist and the workflow uses @main |
Input required: model or llm-base-url |
Add missing secrets (Step 2) |
| Review never appears | Open Actions tab β open the failed run β read the error |
/robin does nothing |
Put /robin on the first line; you need write access on the repo |
| Review is very short | PR may be huge β see docs/ADVANCED.md (max-diff-size) |
Empty response from LLM |
Free routers sometimes return no text β the action retries automatically; comment /robin again |
OpenRouter stall / job runs 15 min with no review |
Auto-router hung β action now aborts after 45s with no stream and retries |
404 Provider returned error |
Normal for openrouter/free when one provider is down β the action retries up to 5 times; keep LLM_MODEL=openrouter/free |
More fixes: docs/ADVANCED.md#troubleshooting
| Pin | When to use |
|---|---|
@main |
Latest changes on the default branch |
@v1 |
Latest 1.x release (updated on each release) |
@v1.0.0 |
Exact version (most predictable) |
| Full commit SHA | Maximum supply-chain safety |
uses: antongulin/robin/.github/workflows/review.yml@v1Releases and notes are published automatically from CHANGELOG.md when changes land on main. See CONTRIBUTING.md for commit message format.
- docs/ADVANCED.md β all settings, strict mode, manual-only reviews, security notes
- CONTRIBUTING.md β run tests and send pull requests
- CHANGELOG.md β release history
Robin is free and open source (MIT). If it saves you money on code review, you can help keep it maintained:
- β Star the repo β it's the cheapest way to help others find it.
- π Sponsor the project to support ongoing work.
- π Open an issue for bugs or ideas.
Built by Anton Gulin, AI Architect building AI systems, agent workflows, and software automation. Need a custom AI agent, code-review pipeline, or QA automation? Visit Anton.QA.
git clone https://github.com/antongulin/robin.git
cd robin
npm ci
npm run lint
npm test
npm run buildRuntime code lives in dist/index.js; run npm run build before releasing. A full build removes intermediate files under dist/ after bundling so only index.js remains locally (same file CI checks against).
If you ran tsc alone and see extra files under dist/, run npm run clean.

