rag_for_git

mcp
Security Audit
Pass
Health Pass
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 11 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

AI pull-request reviewer: hybrid RAG + a code graph + Claude Code. Whole-repo context, inline GitHub comments grounded on exact code. MCP server + Claude Code plugin.

README.md

rag_for_git

An AI pull-request reviewer that reads your whole repository — hybrid RAG + a code graph + Claude Code.
Plain linters check a diff in isolation; this agent gives the model the same context a human
reviewer has — semantic + lexical retrieval over the entire repo and a structural code graph —
then posts the result back to GitHub as inline comments on the exact diff lines, with applyable fixes.

PyPI
Python 3.11–3.13
License: MIT
MCP server
Claude Code plugin

🇷🇺 Русская версия — глубокий, сверенный с кодом разбор: README.ru.md


Table of contents


Why it exists

Plain linters catch syntax and style but miss meaning and relationships — the things a human
reviewer actually looks for:

  • a changed function contract that silently breaks its callers,
  • a guard clause removed three files away from where it mattered,
  • a change that contradicts an existing test,
  • an edge case that only shows up once you read the helper it calls.

Catching those needs context beyond the diff: who calls this, what it implements, which tests
pin its behaviour. rag_for_git gives the model that context — semantic + lexical retrieval over
the whole repository and a structural code graph — then runs an agentic tool loop per
changed file and posts the result back to GitHub as inline comments on the exact diff lines,
plus a summary and applyable fixes
.

It is not a wrapper around "send the diff to an LLM." It is a retrieval + code-graph pipeline with
a deterministic, anti-hallucination publishing tail.

What a review looks like

An illustrative inline comment the agent posts on a changed line — it found the bug by following
the call graph from the edited function to its callers and a contract test:

🟠 correctness — an expired token is no longer rejected

verify_token used to raise on an expired signature; the new guard only checks payload is None, so _decode() returning a payload with a past exp now passes as valid. Two call sites
depend on that raise — require_auth (auth/deps.py:48) and the contract test
test_expired_rejected (tests/test_auth.py:71), which this change would break.

    if payload is None or payload.get("exp", 0) < now:
        raise InvalidToken("expired or malformed token")

Every finding is grounded on an exact quote from the diff, carries a category / severity /
confidence, and — when it's safe — ships as a one-click GitHub suggestion. A hidden fingerprint
(<!-- ai-review:… -->) makes re-runs idempotent: the same issue is never posted twice.

Highlights

  • Whole-repo context, not just the diff. Hybrid retrieval (pgvector ANN + BM25, fused with RRF,
    reranked by Voyage) over the entire indexed codebase — for changed files the agent sees the new
    version, for everything else a stable base index.
  • It sees impact. A Neo4j code graph (CALLS / IMPLEMENTS) expands each changed symbol 1–2
    hops to surface callers, callees, implementations, and the tests that pin them.
  • Anti-hallucination by construction. A finding must quote real code to be placed on a line; a
    dedicated verify pass drops invented findings; line grounding is exact-match.
  • Real GitHub output. Inline comments on diff lines, applyable suggestion blocks under safe
    invariants, a summary for everything off-diff — idempotent across re-runs.
  • Lives in your editor, not a CI black box. Ships as a Claude Code plugin and as an MCP
    server
    usable from 12+ AI clients (Cursor, VS Code, Gemini CLI, Codex, Windsurf, Claude
    Desktop, …). One uvx command; published on PyPI.
  • Local-first. Your code stays on your machine — only embedding/query text goes to Voyage; the
    stores (Postgres/ParadeDB + Neo4j) run in local Docker.
  • More than review. The same RAG + graph powers grounded codebase Q&A (ask), disciplined
    task-context gathering (solve-task), PR walkthroughs, and per-subsystem summaries.

How a review runs

A single PR review is three stages:

prepare_review (MCP)analyze (Claude subagents)publish_review (MCP)

  1. prepareGitHubProvider pulls the PR (base/head SHA) and changed files; changed .py
    files are chunked (tree-sitter) and embedded (Voyage) into an ephemeral overlay ref="pr:N";
    policy and per-file review units are assembled.
  2. analyze — the Claude Code skill fans out one subagent per file. Each reasons over the diff
    in a tool loop, pulling in whatever code it needs: search_code, get_related_symbols,
    read_file, get_definition, find_callers, get_changed_file_diff. In parallel,
    dimension subagents run a performance and maintainability pass, plus a requirements
    pass when a task board is wired up, and a final verify pass strips hallucinations.
  3. publish — a deterministic tail: policy gate (category/severity/confidence/paths) → line
    grounding by exact code quote (anti-hallucination) → dedup → assemble (inline vs summary,
    suggestion invariants, fingerprint idempotency, comment cap) → post to GitHub → history record
    → overlay/session cleanup.

Status: working v1. Target analysis language is Python; VCS is GitHub (behind a
VCSProvider interface). Proven live: it catches real bugs and sees the impact on calling code
and existing tests.

How it works / Architecture

The core is the reviewer/ library, assembled in reviewer/app.py::build_components(settings)
from Settings (pydantic-settings, .env). Entry points are reviewer/entrypoints/cli.py (Click)
and reviewer/entrypoints/mcp_server.py (FastMCP). Three pieces work together:

  • RAG (hybrid retrieval). Postgres/ParadeDB stores code chunks with pgvector (HNSW ANN) and
    pg_search (BM25). A query embeds with Voyage, runs both ANN and BM25 search, and the result
    lists are merged with Reciprocal Rank Fusion (RRF), then reranked with Voyage rerank-2.5.
  • Code graph (SCIP or tree-sitter, Neo4j). Symbols and their relationships live in Neo4j.
    The graph orchestrator (graph/backend.py) picks a backend via GRAPH_BACKEND
    (auto|scip|treesitter): SCIP (@sourcegraph/scip-python) gives a precise, type-aware graph
    with CALLS + IMPLEMENTS edges; tree-sitter is a fast fallback with CALLS-by-name only.
    Retrieval expands the changed symbols 1–2 hops to surface callers/callees/implementations/tests.
  • Claude Code plugin via MCP. The reviewer-mcp server exposes prepare_review,
    publish_review, and the agent tools. The Claude Code plugin (plugin/) drives the review: it
    calls prepare_review, runs analysis subagents against those MCP tools, then calls
    publish_review.

The single key linking RAG and the graph is node_id = "path#fqn" (e.g.
rag/embedder.py#VoyageEmbedder.embed_query). Both the chunk in Postgres and the node in Neo4j use
it, so graph expansion and chunk retrieval are stitched together without any mapping table.

Index freshness: a stable base + a PR overlay. A full reindex of a large repo is expensive, so
the index keeps a persistent base and layers PR changes on top:

  • ref="base:<branch>" — the persistent index of a tracked branch (e.g. "base:main",
    "base:master"). Each tracked branch in REVIEW_BRANCHES has its own isolated index. Updated
    incrementally by reviewer index --ref <branch> (only changed files are chunked; only chunks
    with a new content_hash are re-embedded — embeddings are reused across branches by hash,
    saving Voyage quota).
  • ref="pr:N" — an ephemeral overlay of just the PR's changed files at its HEAD.
  • On a query: retrieval = (base:<branch> where path ∉ changed) ∪ overlay. For changed files
    the agent sees the new version; for everything else, the stable base.
  • Multi-branch. A PR is reviewed against the index of its target branch (base_ref from the
    PR). A PR targeting an untracked branch is skipped (prepare_review returns
    {"status":"skipped",...}). The code graph (Neo4j :Symbol) is also branch-scoped via a
    branch property, with unique constraint (repo, branch, id).
                ┌─────────────────────────── reviewer (core library) ───────────────────────────┐
                │                                                                                 │
  GitHub PR ───▶│  VCSProvider (github.py)  ──diff/files/patches──▶  MCPReviewService             │
  (owner/repo#N)│        ▲  publish inline + summary                       │ prepare_review        │
                │        │                                                 ▼                       │
                │        │                          ┌──────────── retrieval/Retriever ──────────┐ │
                │        │                          │  hybrid search        graph expansion      │ │
                │        │                          │  ┌──────────────┐   ┌───────────────────┐  │ │
                │        │                          │  │ Postgres      │   │ Neo4j             │  │ │
                │        │                          │  │ (ParadeDB)    │   │ Symbol(path#fqn)  │  │ │
                │        │                          │  │ pgvector(HNSW)│   │ -[:CALLS]->        │  │ │
                │        │                          │  │ + pg_search   │   │ (IMPLEMENTS: SCIP) │  │ │
                │        │                          │  │   (BM25, RRF) │   │ expand 1–2 hops    │  │ │
                │        │                          │  └──────┬───────┘   └─────────┬─────────┘  │ │
                │        │                          │   Voyage embed/rerank   tree-sitter graph  │ │
                │        │                          └─────────────────┬─────────────────────────┘ │
                │        │                                            ▼ ContextPack                │
                │        │                       Claude Code subagents (skill /rag-reviewer:reviewer_review-pr)
                │        │                         tools: search_code, get_related_symbols,        │
                │        │                         read_file, get_definition, find_callers, …      │
                │        └─────────────────── publish_review (gate/grounding/dedup/assemble) ◀─────┘
                └─────────────────────────────────────────────────────────────────────────────────┘

  Stores (Docker):  Postgres/ParadeDB (:5433)  ·  Neo4j (:7687)
  External API:     Voyage (embeddings voyage-code-3 + reranker rerank-2.5)

For a deeper, code-verified walkthrough of every module and the data flow, see
README.ru.md (Russian).

One-click install prompt

Copy and paste into any AI coding assistant (Claude Code, Cursor, Gemini CLI, Mimo Code, OpenCode, Kimi Code, Codex, Copilot…):

Set up the rag-reviewer MCP server in this AI tool.

Rules:
- Use `uvx --from rag-reviewer@latest reviewer-mcp` to run the server — do NOT pip install, do NOT clone the repo.
- The `bash -lc` wrapper is required on macOS/Linux so uvx is found by GUI tools: command="/bin/bash", args=["-lc", "uvx --from rag-reviewer@latest reviewer-mcp"]. On Windows use command="uvx", args=["--from","rag-reviewer@latest","reviewer-mcp"].
- Detect which AI tool you are running in, then write the MCP entry to the correct config file:
  - Claude Code / generic: .mcp.json in project root ({"mcpServers":{"reviewer":{"command":"/bin/bash","args":["-lc","uvx --from rag-reviewer@latest reviewer-mcp"]}}})
  - Cursor: ~/.cursor/mcp.json (same format)
  - Gemini CLI: ~/.gemini/settings.json ({"mcpServers":{"reviewer":{"command":"/bin/bash","args":["-lc","uvx --from rag-reviewer@latest reviewer-mcp"]}}})
  - Antigravity: ~/.gemini/antigravity/mcp_config.json (same mcpServers format)
  - Windsurf: ~/.codeium/windsurf/mcp_config.json (same mcpServers format)
  - Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows (same mcpServers format)
  - Mimo Code: ~/.config/mimocode/mimocode.json ({"mcp":{"reviewer":{"type":"local","command":["/bin/bash","-lc","uvx --from rag-reviewer@latest reviewer-mcp"],"enabled":true}}})
  - OpenCode: ~/.config/opencode/opencode.json ({"mcp":{"reviewer":{"type":"local","command":["/bin/bash","-lc","uvx --from rag-reviewer@latest reviewer-mcp"]}}})
  - Kimi Code: ~/.kimi-code/mcp.json ({"mcpServers":{"reviewer":{"command":"/bin/bash","args":["-lc","uvx --from rag-reviewer@latest reviewer-mcp"]}}})
  - Codex CLI: ~/.codex/config.toml ([mcp_servers.reviewer] command="/bin/bash" args=["-lc","uvx --from rag-reviewer@latest reviewer-mcp"])
  - VS Code: ~/Library/Application Support/Code/User/mcp.json (key is "servers" not "mcpServers": {"servers":{"reviewer":{"command":"/bin/bash","args":["-lc","uvx --from rag-reviewer@latest reviewer-mcp"]}}})
- After writing the config, run: uvx --from rag-reviewer reviewer check
- Report what config file was written and whether the check passed.

Installation

The MCP server is published on PyPI as rag-reviewer
and runs via uvxno clone of this repo required.

Requirements: Docker, uv (includes uvx),
a Voyage API key, a GitHub token. Python 3.11–3.13 (only needed for a pip/editable install; uvx
manages its own).

Quick setup (recommended, all platforms)

# 0) Install the reviewer CLI — once, globally
uv tool install rag-reviewer
# uv and uvx are the same binary; installing uv gives you both.
# The MCP server launched by your editor uses uvx @latest and self-updates automatically.

# 1) Infrastructure
curl -O https://raw.githubusercontent.com/mimfort/rag_for_git/main/docker-compose.yml
docker compose up -d          # Postgres/ParadeDB (:5433) + Neo4j (:7687)

# 2) Configure keys and settings interactively
reviewer init
#    Interactive wizard: fills VOYAGE_API_KEY, GITHUB_TOKEN, and optional groups
#    (stores, multi-repo, task board). Re-run any time to update settings.
#    CI / non-interactive: reviewer init --yes  (accepts all defaults silently)

# 3) Register the MCP server (and skills) in your editor/CLI
reviewer install --all        # auto-detect installed clients + install skills
#    or a specific one: reviewer install cursor|vscode|claude-code|claude-desktop|windsurf|gemini|antigravity|mimo|opencode|kimi|trae|codex
#    skills go to clients that support them (Gemini/Mimo/Kimi); add --no-skills to skip

# 4) Verify
reviewer check

# Update CLI later:
uv tool upgrade rag-reviewer

reviewer install is cross-platform (Windows / macOS / Linux). It injects the
absolute path to uvx automatically — no bash -lc wrapper needed. The manual
JSON configs below use bash -lc for macOS/Linux only; on Windows use
reviewer install or set "command": "uvx" with "args": ["--from", "rag-reviewer@latest", "reviewer-mcp"] directly.

Claude Code: tools work out of the box. reviewer install claude-code also
writes an allowlist rule mcp__reviewer__* into your global
~/.claude/settings.json (permissions.allow), so the reviewer MCP tools run in
every project without hitting the auto-mode safety classifier — no manual
settings edits. Being global, it also covers the plugin (marketplace) install,
where the server is available everywhere but ships no permission grants.

Where keys are read from. The reviewer resolves its .env from a fixed
location, not the current working directory — MCP clients launch the server
with an arbitrary CWD, so a project-local .env is unreliable. Lookup order:
$REVIEWER_ENV_FILE$XDG_CONFIG_HOME/rag-reviewer/.env (default
~/.config/rag-reviewer/.env) → ./.env (handy when running from a repo clone).
Real environment variables always win over the file, so you can instead pass keys
via an "env": { "VOYAGE_API_KEY": "…", "GITHUB_TOKEN": "…" } block in your MCP
client config — works in every client.

  • Voyage (VOYAGE_API_KEY): https://dashboard.voyageai.com/ — free token pool; attach a card
    to lift the 3 RPM / 10K TPM limit (charged only beyond the free pool).
  • GitHub (GITHUB_TOKEN): a PAT with Pull requests: Read and write + Contents: Read
    (fine-grained) or the repo scope (classic). Quick option: gh auth token.

All other settings have defaults (documented in .env.example and in
Configuration reference below).

Manual setup (alternative)

If you prefer to configure your client config by hand rather than using reviewer install:

Each AI coding tool has its own config file. Pick yours:

Tool Global config file Project config Install guide
Claude Code /plugin marketplace add (see below) .claude-plugin/
Cursor ~/.cursor/mcp.json .cursor/mcp.json
Windsurf ~/.codeium/windsurf/mcp_config.json
Claude Desktop macOS: ~/Library/Application Support/Claude/claude_desktop_config.json; Windows: %APPDATA%\Claude\claude_desktop_config.json
Antigravity ~/.gemini/antigravity/mcp_config.json
Mimo Code ~/.config/mimocode/mimocode.json .mimocode/mimocode.json INSTALL.md
OpenCode ~/.config/opencode/opencode.json .opencode/opencode.json INSTALL.md
Kimi Code ~/.kimi-code/mcp.json .kimi-code/mcp.json INSTALL.md
Gemini CLI ~/.gemini/settings.json .gemini/settings.json GEMINI.md
Codex CLI ~/.codex/config.toml .codex-plugin/plugin.json AGENTS.md
Copilot CLI .github-copilot/plugin.json
Trae IDE ~/Library/Application Support/Trae/User/mcp.json
VS Code ~/Library/Application Support/Code/User/mcp.json (key: servers, not mcpServers)

Files marked ✓ are already present in this repo — if you open rag_for_git as a project in
that tool, the MCP server auto-connects. For a global install (works from any project),
add the entry to the corresponding global config file.

The MCP entry format by tool (macOS/Linux — use reviewer install on Windows):

Mimo Code (mimocode.json):

{
  "$schema": "https://mimo.xiaomi.com//config.json",
  "mcp": {
    "reviewer": {
      "type": "local",
      "command": ["/bin/bash", "-lc", "uvx --from rag-reviewer@latest reviewer-mcp"],
      "enabled": true
    }
  }
}

OpenCode (opencode.json):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "reviewer": {
      "type": "local",
      "command": ["/bin/bash", "-lc", "uvx --from rag-reviewer@latest reviewer-mcp"]
    }
  }
}

Kimi Code / Cursor / Gemini CLI / Codex CLI / Trae / Claude Desktop / Windsurf / Antigravity (standard mcpServers JSON):

{
  "mcpServers": {
    "reviewer": {
      "command": "/bin/bash",
      "args": ["-lc", "uvx --from rag-reviewer@latest reviewer-mcp"]
    }
  }
}

VS Code (mcp.json — note: key is servers, not mcpServers):

{
  "servers": {
    "reviewer": {
      "command": "/bin/bash",
      "args": ["-lc", "uvx --from rag-reviewer@latest reviewer-mcp"]
    }
  }
}

Codex CLI (~/.codex/config.toml):

[mcp_servers.reviewer]
command = "/bin/bash"
args = ["-lc", "uvx --from rag-reviewer@latest reviewer-mcp"]

After adding, restart the tool — reviewer will appear alongside other MCP servers.

Claude Code (plugin marketplace)

Two commands, from any project:

/plugin marketplace add mimfort/rag_for_git
/plugin install rag-reviewer@rag-reviewer-marketplace

You get:

  • Skills: /rag-reviewer:reviewer_review-pr, /rag-reviewer:reviewer_solve-task,
    /rag-reviewer:reviewer_sync-codebase, /rag-reviewer:reviewer_sync-tasks,
    /rag-reviewer:reviewer_performance-review, /rag-reviewer:reviewer_maintainability-review,
    /rag-reviewer:reviewer_ask (see Skills reference).
  • MCP server reviewer exposing the 20 tools in MCP tools reference.

Run /plugin to confirm rag-reviewer is installed and enabled.

Install skills globally (optional)

The 7 skills wrap the MCP tools into guided flows. Without them you can still call MCP tools
directly, but the skills are the intended entry point.

reviewer install already installs them for clients that support file-based skills (Gemini,
Mimo, Kimi). To (re)install just the skills — or pick a specific client — use:

uvx --from rag-reviewer reviewer install-skills --all     # all detected skills-capable clients
uvx --from rag-reviewer reviewer install-skills gemini    # a specific one
uvx --from rag-reviewer reviewer install-skills --list    # show targets + directories

It downloads the skills from GitHub (no repo clone) and unpacks them into each client's global
skills directory, with a path-traversal guard. Manual fallback (equivalent):

curl -sL https://github.com/mimfort/rag_for_git/archive/refs/heads/main.tar.gz -o /tmp/rag-reviewer.tgz
mkdir -p ~/.gemini/skills
tar xz -C ~/.gemini/skills --strip-components=3 -f /tmp/rag-reviewer.tgz 'rag_for_git-main/plugin/skills'
rm /tmp/rag-reviewer.tgz
Tool Global skills directory
Gemini CLI ~/.gemini/skills/
Mimo Code ~/.config/mimocode/skills/
Kimi Code ~/.kimi-code/skills/ + extra_skill_dirs in ~/.kimi-code/config.toml
OpenCode ~/.config/opencode/skills/
Claude Code bundled in the plugin (step above)
Cursor project-level via .cursor-plugin/plugin.json

That's it. Build the base index (recommended — see CLI reference) and review a PR
(see Plugin usage).


Configuration reference

Everything is configured through environment variables (.env, see .env.example with comments).
The only required external key is VOYAGE_API_KEY; GITHUB_TOKEN is required for PR review.
All other settings have working defaults that match the bundled docker-compose.yml. The .env
is resolved from $REVIEWER_ENV_FILE~/.config/rag-reviewer/.env./.env (real env vars
always win).

Voyage — embeddings + reranker (required)

Variable Default Purpose
VOYAGE_API_KEY "" Required. Voyage key for embeddings + reranking.
EMBEDDING_MODEL voyage-code-3 Embedding model.
EMBEDDING_DIM 1024 Embedding dimension; must match the vector(N) column in Postgres — changing it requires a reindex.
EMBEDDING_BATCH_SIZE 256 Texts per embedding request (≤1000 and ≤120K tokens).
RERANK_MODEL rerank-2.5 Voyage reranker model.

GitHub (required for PR review)

Variable Default Purpose
GITHUB_TOKEN "" PAT — Pull requests: Read and write + Contents: Read.
GITHUB_RETRY_ATTEMPTS 3 Retries on GitHub API network errors.
GITHUB_RETRY_BACKOFF_BASE 1.0 Exponential backoff base (seconds).

Stores (Postgres/ParadeDB + Neo4j)

Variable Default Purpose
PG_DSN postgresql://reviewer:reviewer@localhost:5433/reviewer ParadeDB (pgvector + pg_search) on host port 5433.
PG_POOL_MIN_SIZE 1 Min Postgres pool connections.
PG_POOL_MAX_SIZE 4 Max Postgres pool connections.
NEO4J_URI neo4j://localhost:7687 Neo4j bolt URI.
NEO4J_USER neo4j Neo4j user.
NEO4J_PASSWORD reviewerpass Neo4j password (one-off dev default).
GRAPH_BACKEND auto Code-graph engine: auto (SCIP if scip-python in PATH, else tree-sitter), scip, treesitter.

Multi-repo / multi-branch (optional)

Variable Default Purpose
DEFAULT_REPO "" Default owner/name for session-less tools and reviewer index without --repo; empty = multi-repo (repo must be passed explicitly).
REVIEW_BRANCHES main CSV of tracked branches; the first is primary (default for reviewer index --ref and CLI search). PRs targeting a branch outside the list are skipped.

Review policy (env defaults; per-repo .review.yml overrides)

Variable Default Purpose
REVIEW_SEVERITY_THRESHOLD medium Minimum severity to keep: low/medium/high/critical.
REVIEW_MIN_CONFIDENCE 0.5 Drop findings with confidence below this (0..1).
REVIEW_MAX_COMMENTS 25 Cap on inline comments per review.
REVIEW_MAX_FILES 50 Cap on .py files reviewed; the rest go to the summary as skipped.
REVIEW_CATEGORIES "" CSV whitelist of categories (correctness, security, performance, style, requirements); empty = all.
REVIEW_SUGGESTIONS apply apply = applyable GitHub suggestion blocks; text = text-only advice.
REVIEW_OUTPUT_LANGUAGE ru Language of the published findings' text.
REVIEW_SKIP_DRAFTS true Don't review draft PRs.
MAX_TOOL_RESULT_CHARS 8000 Max length of a tool result fed into the prompt.

Observability & sessions (optional)

Variable Default Purpose
REVIEW_HISTORY true Record run history in Postgres (review_runs/review_findings), fail-soft.
REVIEW_SESSION_PERSIST true Persist the PR session in Postgres for crash recovery.
REVIEW_SESSION_TTL_HOURS 24 TTL (hours) of a persisted session.
WEB_ADMIN_USER "" Basic-auth user for reviewer serve; empty = no auth.
WEB_ADMIN_PASSWORD "" Basic-auth password; empty = no auth.

Task board (optional) — deploy-wide default

A board connection is the same for every repo of one team, so it is configured once in the
reviewer-mcp env rather than duplicated in each repo's .review.yml. See
Per-repo policy & task board.

Variable Default Purpose
TASK_BOARD_TYPE "" Board type: yougile, jira, … (selects the skill playbook).
TASK_BOARD_MCP "" Name of the connected board MCP server (LLM-side tools mcp__<mcp>__*).
TASK_BOARD_KEY_PATTERN "" Task-key regex, e.g. [A-Z]+-\d+.
TASK_BOARD_URL_TEMPLATE "" Task-link template, e.g. https://ru.yougile.com/team/<id>/#{code}.
TASK_BOARD_API_KEY "" REST API key for server-side bulk sync (sync_board). Server-internal — never returned to clients.
TASK_BOARD_API_BASE "" REST API base URL; empty → default per type (yougile: https://yougile.com/api-v2).

Getting TASK_BOARD_API_KEY (Yougile). UI: press Ctrl + ~ (or ⚙ next to the company name →
"Настроить") → API → create/copy the key. REST: get companyId (Ctrl + Alt + Q, or
POST /api-v2/auth/companies {login,password}), then POST /api-v2/auth/keys {login,password,companyId}.
The key belongs only in the reviewer-mcp env (~/.config/rag-reviewer/.env), not in a chat or a client config.


CLI reference

All commands run via uvx --from rag-reviewer <command>, or after uv tool install rag-reviewer /
pip install -e ".[dev]" simply as reviewer. Two entry points are installed:
reviewer (the CLI below) and reviewer-mcp (the MCP server, started by your editor/plugin).

Command Arguments Options What it does
check Verify environment readiness (keys, Postgres, Neo4j, GitHub). Prints ✓/✗ per item; exits 1 on any problem. Spends no Voyage quota.
init --path FILE (default ~/.config/rag-reviewer/.env), --yes (accept defaults, CI mode) Interactive wizard that writes the .env (Voyage/GitHub + optional groups).
install [client] --all, --list, --path FILE, --pin VERSION, --no-latest, --no-skills, --dry-run Register the MCP server (and skills) in AI clients (cross-platform).
install-skills [client] --all, --list, --path FILE Install only the skills into a client's global skills directory.
update Check PyPI for a newer rag-reviewer and report how to upgrade.
index <repo> (path to local clone) --ref BRANCH (git ref to read; default = primary branch), --branch NAME (storage key; default = --ref), --repo OWNER/NAME (default from git origin) Build/update the base index of a branch (vectors + graph). Done once, then incremental.
search <query> --repo OWNER/NAME (default DEFAULT_REPO), --branch NAME (default primary) Diagnostic hybrid search over a branch's base index.
status [path] (default .) --repo OWNER/NAME (default from git origin), --branch NAME (default: all REVIEW_BRANCHES) Index health / freshness vs the clone's HEAD. Spends no Voyage quota.
migrate-branches One-time: rename legacy ref="base"base:<primary> after upgrading to multi-branch.
serve --host HOST (default 127.0.0.1), --port PORT (default 8000) Run the observability web admin on the host.
reviewer-mcp MCP server (stdio transport). Started automatically by the plugin / editor.

Examples:

# First-time setup
uvx --from rag-reviewer reviewer init
uvx --from rag-reviewer reviewer install --all
uvx --from rag-reviewer reviewer check

# Build the base index (whole-repo context for RAG + graph)
uvx --from rag-reviewer reviewer index /path/to/repo --ref main --repo owner/name
uvx --from rag-reviewer reviewer index /path/to/repo --ref master --repo owner/name   # second tracked branch

# Diagnostics (no Voyage spend except `search`)
uvx --from rag-reviewer reviewer search "token verification" --branch master
uvx --from rag-reviewer reviewer status /path/to/repo --branch dev

# Web admin
uvx --from rag-reviewer reviewer serve --host 127.0.0.1 --port 8000

Reviewing works even without a prior index — context is then limited to the diff and the overlay
(RAG/graph are "thin"). For full whole-repo impact analysis, run index against the target branch.


Skills reference

Skills are the guided entry points for the workflow. With the plugin installed they are invoked as
/rag-reviewer:<name> in Claude Code (the leading /rag-reviewer: is the plugin namespace; on
other clients the skill name is the same). Arguments are passed as free text after the skill name
($ARGUMENTS).

reviewer_review-pr — full PR review

Orchestrates the three-stage pipeline (prepare_review → subagents → publish_review).

  • Arguments: the PR as owner/repo#N, owner/repo N, or a GitHub PR URL. Add --dry-run to
    assemble and return the full report without posting to GitHub.
  • MCP tools used: prepare_review, search_code, get_related_symbols, read_file,
    get_definition, find_callers, get_changed_file_diff, publish_review; plus
    index_task / get_task_context / search_tasks when a task board is wired up.
  • Flow: prepare (PR + policy + units + board config) → fan out one analysis subagent per file →
    parallel performance / maintainability dimensions (+ requirements if a TaskBrief
    exists) → verify pass (drops is_real=false findings) → publish (gate/grounding/dedup/assemble).
    If prepare_review returns status:"skipped" (target branch not tracked) it stops; draft PRs are
    skipped unless REVIEW_SKIP_DRAFTS=false.

reviewer_solve-task — gather context for a task, then hand off to dev

Reads a task (if a key + board), pulls related/similar tasks and relevant code, distills a brief,
and enters brainstorming. It disciplines context-gathering — it does not write the code.

  • Arguments: a task key (e.g. PRI-4, must match key_pattern) or a free-text description
    (e.g. "add a logout endpoint"). Board-less mode falls back to description + code search.
  • MCP tools used: get_board_config, index_task, get_task_context, search_tasks,
    search_codebase, related_symbols, callers, definition, get_pr_diff; plus the connected
    board MCP (mcp__<board>__*) to read the task.
  • Flow: resolve board config → identify task (key vs free text) → best-effort, fail-open context
    gathering (task graph, similar tasks, relevant code, lazy PR diffs of similar tasks) → distill a
    structured brief (Task / Related work / Relevant code / Constraints) → hand off to
    superpowers:brainstorming with the brief as seed.

reviewer_sync-codebase — build/update the base index

Thin wrapper over reviewer index (vector store + code graph) from a local clone.

  • Arguments (all optional): --path <path> (default: CWD), --ref <branch> (default: main),
    --repo <owner/name> (default: derived from git remote get-url origin),
    --backend <auto|scip|treesitter> (default: auto, sets GRAPH_BACKEND).
  • MCP tools used: none directly — it shells out to uvx --from rag-reviewer reviewer index.
  • Flow: resolve inputs → check prerequisites (uvx, git repo, reviewer check, Docker up) →
    run indexing → optional reviewer search to verify → report chunks/nodes/edges and which graph
    backend was used.

reviewer_sync-tasks — warm the task graph & vector store

A thin trigger over the server-side ETL tool sync_board — the reviewer enumerates the board over
REST itself, so the LLM passes no task text (O(1) tokens regardless of board size).

  • Arguments (all optional): --board <name> (limit to one board/project), --limit <N> (smoke
    run; disables purge and watermark advance), --purge-orphaned (remove tasks no longer on the
    board; off by default), --no-keep-with-prs (with purge, also remove tasks that have PR history —
    protected by default).
  • MCP tools used: sync_board (single call).
  • Flow: map args → one sync_board(...) call → print a counts summary (enumerated/changed/
    embedded/unchanged/failed, purge, warnings). On {"status":"error",...} the board is not
    configured server-side — set TASK_BOARD_* in ~/.config/rag-reviewer/.env and reconnect.

reviewer_performance-review — performance-only review

Reviews a diff only for performance/efficiency risks (N+1 queries, repeated work, bad asymptotics,
missing batching/caching, blocking I/O, memory growth).

  • Arguments (standalone): scope — staged, unstaged, uncommitted, branch-vs-base, a commit,
    a branch comparison, a file list, or a PR-like scope. If unclear, it asks. Inside
    reviewer_review-pr it runs as a dimension over the provided unit diffs.
  • MCP tools used (when run in the PR pipeline): search_code, read_file, find_callers,
    get_related_symbols, get_definition, get_changed_file_diff.
  • Output: JSON {"findings":[{category:"performance", severity, file, line, side, code_quote, message, suggestion, fix, confidence}]}.

reviewer_maintainability-review — maintainability-only review

Reviews a diff only for maintainability risks (unnecessary complexity, poor readability,
duplication, weak separation of concerns, convention drift).

  • Arguments (standalone): same scope options as the performance review. Inside
    reviewer_review-pr it runs as a dimension over the provided unit diffs.
  • MCP tools used (when run in the PR pipeline): search_code, get_related_symbols,
    read_file, get_definition, find_callers, get_changed_file_diff.
  • Output: JSON {"findings":[{category:"maintainability", severity, file, line, side, code_quote, message, suggestion, fix, confidence}]}.

reviewer_ask — grounded codebase Q&A

Answers a free-text question about the codebase with citations (path:line), using RAG + the code
graph. For onboarding / explaining a subsystem — not for reviewing PRs. Requires a built base
index.

  • Arguments: a free-text question (e.g. "where is authentication", "how does index freshness
    work", "explain the retrieval pipeline", "как устроено…").
  • MCP tools used: search_codebase, related_symbols, callers, definition; plus harness
    Read/Grep/Glob.
  • Flow: resolve repo/branch → search_codebase → optionally expand via the graph → answer with
    an Evidence list of path:line citations.

MCP tools reference

The reviewer-mcp server exposes 20 tools. PR-session tools require an active prepare_review for
that (repo, pr) in the same running server; the rest are session-less.

Review lifecycle

Tool Signature Returns / does
prepare_review (repo: str, pr: int) Open a PR session: sync base index, build the PR overlay, load policy, assemble per-file units. Returns PR meta + policy + units (or {"status":"skipped"} for an untracked target branch).
publish_review (repo, pr, summary, findings: list[dict], dry_run=False, task_key=None) Deterministic tail: gate → grounding → dedup → inline/summary split → post to GitHub → history → overlay cleanup. dry_run=true returns the report without posting; task_key links the PR to a task on real publish.

Each finding: {category, severity(low|medium|high|critical), file, line, side(RIGHT|LEFT), code_quote, message, suggestion, fix:{start_line,end_line,replacement}|null, confidence:0..1}.

PR-session analysis tools (require prepare_review)

Tool Signature Returns / does
search_code (repo, pr, query: str) Hybrid semantic+lexical search over base ∪ overlay.
get_related_symbols (repo, pr, node_id: str) Graph neighbors (calls/implementations) of node_id = path#fqn.
read_file (repo, pr, path, start=1, end=400) Source of a file at the PR HEAD (1-based, inclusive).
get_definition (repo, pr, symbol: str) Definition of a symbol (graph → index → semantic fallback).
find_callers (repo, pr, node_id: str) Direct callers of node_id path#fqn (impact analysis).
get_changed_file_diff (repo, pr, path: str) Unified diff of another changed file in the same PR.

Session-less tools (Q&A, solve-task)

Tool Signature Returns / does
search_codebase (repo, query, top_k=10, branch=None, include_tests=False) Hybrid search over a repo's base index; line-numbered, deduped, tests excluded by default.
related_symbols (repo, node_id, branch=None) Graph neighbors (calls/implements/tests) of a symbol.
callers (repo, node_id, branch=None) Incoming CALLS of node_id path#fqn.
definition (repo, symbol, branch=None) Symbol definition (graph → index → semantic fallback).
get_pr_diff (repo, number: int) Unified diff of any (historical) PR; capped, fail-soft.

Tasks / boards

Tool Signature Returns / does
sync_board (board=None, limit=None, purge_orphaned=False, keep_with_prs=True) Server-side ETL: enumerate the board over REST, normalize to TaskBrief, index. Incremental via a per-board watermark; O(1) tokens.
index_task (task: dict) Index one normalized TaskBrief into the task graph + vector store (idempotent).
index_tasks_batch (tasks: list[dict]) Same for a list, in one Voyage call.
search_tasks (query, top_k=5) Semantically similar tasks from the indexed corpus.
get_task_context (key: str) Graph context: the task, its PRs, linked tasks and their PRs, and the touched code.
purge_orphaned_tasks (active_keys: list[str], keep_with_prs=True) Remove tasks no longer on the board (PR-linked tasks protected by default).
get_board_config () Deploy-wide board config (TASK_BOARD_*); fallback for sync-tasks/solve-task. Credentials are not returned.

Plugin usage

With the plugin installed and Claude Code open at the repo root, call a skill:

/rag-reviewer:reviewer_review-pr owner/repo#42        # review a PR (prepare → subagents → publish)
/rag-reviewer:reviewer_review-pr owner/repo#42 --dry-run   # assemble the report without posting
/rag-reviewer:reviewer_sync-codebase --ref main      # build/update vector store + code graph
/rag-reviewer:reviewer_sync-tasks                    # warm the task graph (server-side ETL)
/rag-reviewer:reviewer_solve-task PRI-4              # gather task context, then hand off to dev
/rag-reviewer:reviewer_ask how does index freshness work   # grounded codebase Q&A

A typical end-to-end run:

git clone https://github.com/ORG/REPO /tmp/REPO
reviewer index /tmp/REPO --ref main       # build base index + graph for main
reviewer index /tmp/REPO --ref master     # optionally index a second branch (REVIEW_BRANCHES=main,master)
# in Claude Code (from the repo root):  /rag-reviewer:reviewer_review-pr ORG/REPO#42

Per-repo policy & task board

A .review.yml file in the target (base) branch overrides the env defaults (a PR cannot weaken
its own review — see Caveats):

categories: { correctness: true, security: true, performance: true, style: false, requirements: true }
severity_threshold: medium
min_confidence: 0.5
paths: { ignore: ["**/migrations/**", "vendor/**"] }
max_comments: 25

# Optional task context: read the task from a board and check requirement compliance.
# The board (MCP) is connected by the user on the Claude Code side; the plugin does not bundle it.
task_board:
  type: yougile          # yougile | jira — selects the skill playbook
  mcp: yougile           # name of the connected board MCP server (tools are mcp__<mcp>__*)
  key_pattern: "[A-Z]+-\\d+"   # optional; matches Yougile PRI-34/ID-34 and Jira PROJ-123

The task_board block is a deploy-wide default, not a per-repo requirement. A board connection
is the same for every repo of one team, so configure it once in the reviewer .env
(TASK_BOARD_TYPE / TASK_BOARD_MCP / TASK_BOARD_KEY_PATTERN / TASK_BOARD_URL_TEMPLATE) and
every repo inherits it — no .review.yml needed just for the board. A task_board block in a repo's
.review.yml overrides that default for that repo; an explicit empty task_board: disables
the board for it. review-pr reads this through the policy; solve-task reads it via the
get_board_config MCP tool (and the board-MCP, LLM-side) as a fallback when the local .review.yml
has no block.

Bulk task sync is server-side, not LLM (sync_board). The sync-tasks skill is a thin trigger:
it calls one MCP tool, sync_board(board, limit, purge_orphaned, keep_with_prs), and the reviewer
server enumerates the board over REST itself (reviewer/tasks/boards/, behind a
TaskBoardProvider interface — Yougile is the reference), normalizes each task into a TaskBrief
in Python, and indexes it via the existing batch indexer. The LLM passes no task text, so a sync
costs O(1) tokens regardless of board size. It is incremental via a per-board timestamp watermark in
index_meta (ref="tasks:<board>"): a repeat sync touches ~0 tasks; --limit disables purge and
the watermark advance. The board REST credentials live only in the reviewer-mcp environment
(TASK_BOARD_API_KEY / TASK_BOARD_API_BASE). This inverts the "reviewer Python never touches the
board" rule for bulk sync only — single-task reads in solve-task / review-pr still go through
the board-MCP on the LLM side. The task graph (:Task) is global, so one task can span PRs across
several microservice repos.


Observability web admin

Every publish_review records the run in Postgres (review_runs / review_findings): repo/PR,
model, timings, status, findings with verdicts and whether they were posted. The write is
fail-soft (a logging failure never breaks the review) and gated by REVIEW_HISTORY (default
true). The web admin (FastAPI + React/Vite SPA) shows run history, aggregates (gate filter rate,
trends over time, findings by category/severity) and per-run details with finding drill-down.

# On the host — build the frontend, then serve the SPA + FastAPI:
pip install -e ".[web]"
(cd web/frontend && npm install && npm run build)
reviewer serve                 # http://127.0.0.1:8000 (options: --host / --port)

API: GET /api/runs (filterable list), GET /api/runs/{id} (run + findings),
GET /api/runs/{id}/trace (step trace, forward-only — empty for pre-feature runs),
GET /api/stats?days=N (aggregates).


Known limitations & caveats

A factual list of what this does and does not do today.

  • No automatic trigger. A review is not started on PR open/update. It is a manual skill
    invocation inside Claude Code — there is no GitHub App / webhook / CI integration out of the box.
  • Graph auto-reindex is incremental, not full-precision. On prepare_review, when the base
    branch SHA drifts, the code graph is patched for the changed files (tree-sitter, repo-scoped) in
    the same step that self-heals vector chunks — incoming CALLS edges from unchanged callers are
    preserved. Not refreshed until the next manual reviewer index: IMPLEMENTS edges, outgoing
    CALLS into unchanged files, and new incoming CALLS from unchanged callers. Full SCIP precision
    is restored by reviewer index.
  • Multi-repo via a repo discriminator. One deployment hosts N repositories isolated by a
    repo (owner/name) column/property across Postgres and Neo4j; each review is scoped to its PR's
    repo (no cross-repo retrieval). Index a repo with reviewer index <path> --repo owner/name (or let
    it derive owner/name from the git origin remote, or set DEFAULT_REPO). The task graph
    (:Task) is intentionally global, so one task can span PRs across several microservice repos.
    Within a repo, each tracked branch has its own isolated index (ref="base:<branch>" in Postgres;
    branch property on Neo4j :Symbol nodes, unique constraint (repo, branch, id)).
  • Language scope: Python only. The chunker (tree-sitter) and the SCIP backend (scip-python)
    are Python-specific. Other languages would go behind the same chunker/GraphIndexer interfaces.
  • VCS scope: GitHub only. Only GitHub implements VCSProvider; GitLab/Bitbucket are not
    implemented (the abstraction exists, the providers do not).
  • Graph backend trade-off. A precise, type-aware graph (CALLS + IMPLEMENTS edges) requires
    scip-python in PATH. Without it, the tree-sitter fallback gives CALLS-by-name only (no
    IMPLEMENTS). Mode is chosen via GRAPH_BACKEND=auto|scip|treesitter; in auto, a SCIP failure
    silently falls back to tree-sitter with a warning, while scip propagates the error.
  • Review surface. Inline comments are only possible on diff lines (the changed/context lines of a
    hunk); everything else goes into the summary. An applyable suggestion block is emitted only under
    safe invariants (apply mode, an exact replacement, the whole range inside the RIGHT side of the
    diff, no overlap with other fixes); otherwise the advice is plain text.
  • MCP session is in-process. State between prepare_review and publish_review lives in the
    running reviewer-mcp process (_Session in MCPReviewService). Both calls for one PR must hit
    the same running server — a restart in between loses the session (mitigated by
    REVIEW_SESSION_PERSIST).
  • Voyage free tier = 3 RPM / 10K TPM; TPM is the main blocker — a full reviewer index of a
    large repo throttles (there is retry/backoff with jitter). A single PR review (overlay + query
    embeddings) fits within the limit.
  • LLM cost. A review fans out Claude subagents per file plus dimension passes — that is real
    token cost, not free.
  • Observability web admin auth is optional. Basic auth is enabled only if WEB_ADMIN_USER /
    WEB_ADMIN_PASSWORD are set; by default it is not hardened for public exposure (reviewer serve
    binds to loopback by default).
  • GitHub API caps. The PR file list is paginated by 100; the compare API used to re-sync the base
    index returns at most 300 files — very large diffs are truncated.
  • .review.yml comes from the base branch (by design — a PR cannot weaken its own review), not
    from the PR head.

Tests

.venv/bin/pytest -q                 # unit: fast, on fakes; never hit external APIs
.venv/bin/pytest -m integration     # integration: needs running Postgres/Neo4j + a Voyage key
.venv/bin/ruff check .              # lint (line-length 100, target py311)

pytest excludes integration tests by default (addopts = -m 'not integration'). External services
(GitHub, Voyage, Postgres, Neo4j) are isolated behind interfaces and mocked in unit tests; real calls
happen only in integration/E2E.

Project layout

reviewer/
  config/      Settings (pydantic-settings): env → review thresholds, stores, branches, board
  vcs/         VCSProvider + github.py (httpx) · diff.py (lines available for inline)
  index/       chunker(tree-sitter) · embeddings(Voyage) · reranker · store(pgvector+pg_search/RRF) · freshness
  graph/       builder(tree-sitter call-graph) · scip(SCIP parser) · backend(backend orchestrator) · store(Neo4j)
  retrieval/   Retriever: hybrid + graph expansion + rerank → ContextPack
  llm/         _retry.py (retry/backoff for Voyage)
  tools/       agent tools (search_code, get_related_symbols, read_file, get_definition, …)
  tasks/       TaskBrief normalization · boards/ (TaskBoardProvider REST: yougile) · TaskService.index_batch
  agent/       state (ReviewUnit) · assemble · dedup
  mcp/         MCPReviewService: prepare / tool calls / publish; session management
  services/    ReviewService.prepare: ingest PR, overlay, units
  policy/      ReviewPolicy: env defaults + .review.yml + gating
  entrypoints/ cli.py (Click) · mcp_server.py (FastMCP, 20 tools)
  install.py   reviewer init / install / install-skills (cross-platform client wiring)
  web/         FastAPI + React/Vite SPA — observability web admin
  app.py       dependency assembly from Settings
plugin/        Claude Code plugin (7 skills /rag-reviewer:reviewer_*)
docker-compose.yml   ParadeDB (pgvector+pg_search) + Neo4j

Contributing

Issues and PRs are welcome. To work on the project locally:

git clone https://github.com/mimfort/rag_for_git
cd rag_for_git
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
docker compose up -d            # Postgres/ParadeDB (:5433) + Neo4j (:7687)
.venv/bin/pytest -q             # unit tests — fast, on fakes, no external APIs
.venv/bin/ruff check .          # lint (line-length 100, target py311)

External services (GitHub, Voyage, Postgres, Neo4j) sit behind interfaces and are mocked in unit
tests; real calls happen only in integration/E2E. Commit messages follow Conventional Commits. The
architecture is documented in depth in README.ru.md (Russian) and CLAUDE.md.

License

MIT © rag_for_git contributors.

Reviews (0)

No results found