rag-rat
This server is a repository-intelligence MCP backend for coding agents: it exposes indexed source, code-graph, git/GitHub history, repo memories, and maintenance tooling with provenance on every result.
Search & retrieval:
semantic_search(hybrid BM25+vector),symbol_lookup,read_chunk,docs_for_symbol,commit_search,commits_touching_query,git_history_for_path/git_history_for_symbol,git_blame_chunk.Code graph & impact analysis:
find_callers,trace_callees,impact_surface,important_symbols,compare_graph_to_text,compare_graph_to_scip,check_library_usage,ffi_surface.Clone detection:
find_clones(ranked duplicate classes),clones_for_symbolto locate near-miss duplicates and reuse candidates.Repo memories:
memory_create,memory_update,memory_rebind,memory_show,memory_search,memory_for_symbol/memory_for_path/memory_for_call_path,memory_validate,memory_doctor,memory_mark_obsolete, plus typed memory graph edges (memory_edge_add/remove/edges).Tracker/papertrail rationale:
papertrail_for_symbol/papertrail_for_chunk/papertrail_for_commit,papertrail_issue_search,papertrail_refs_for_path,rationale_search,papertrail_sync_status.Orientation & health:
repo_brief,repo_clusters,index_status,llm_status,heal_index.Self-maintenance loop:
dreamreturns the memory-maintenance worklist (coverage gaps, stale refs);dream_reviewaccepts/dismisses/resets findings.
rag-rat
What a repository knows about itself. rag-rat is a local repo-intelligence index and MCP server
for coding agents. It keeps source files read-only, writes only its own SQLite database, and answers
with provenance on every result — current source, the code graph, git/GitHub history, and durable,
source-anchored repo memories that persist across sessions and agents.
Explore the live VS Code Lens demo — no installation required.
It surfaces clone classes, repo memories, and issue/decision context alongside the code; press
Ctrl+Alt+R to reveal clone overlays.
Every coding harness already has grep and file reads. rag-rat adds the layer they do not provide:
source-anchored rationale. It connects the code an agent is about to touch to its callers, callees,
tests, git/GitHub history, prior decisions, invariants, risks, and duplicate-code signals — and
labels every result with confidence and coverage, so an agent can judge it instead of trusting it.
sequenceDiagram
participant Repo as Repository
participant Engine as rag-rat engine
participant Agent as Coding agent
Repo->>Engine: Source · git/GitHub · repo memories
Engine->>Engine: Index → graph → (opt) SCIP oracle → reconcile
Agent->>Engine: where / why / who-calls / impact?
Engine-->>Agent: source + call paths + papertrail + memories (with provenance)
Agent->>Engine: record a finding
Engine->>Repo: persist a source-anchored repo memoryWhy
Provenance, not guesses. Every result carries a confidence label, coverage warnings, and the raw evidence — so a partial index or an ambiguous edge reads as exactly that.
Repo memories. Typed, source-anchored notes (
Invariant,Decision,Risk, …) that survive refactors and surface automatically during future queries — the signal grep can't give you. They are not assistant memory: they are versioned, local, source-anchored facts about this repository that any future agent retrieves with evidence.A real code graph. tree-sitter callers/callees/imports across Rust, TypeScript/TSX, Kotlin, C/C++, Python, Swift, and Go — with an optional compiler-grade SCIP oracle for configured toolchains that upgrades edges to
Compilerconfidence and ranks the load-bearing symbols.History as evidence. Git history, lazy chunk blame, and cached GitHub issue/PR/review rationale, all queryable.
Issue distillation. Every closed issue and merged PR plus its fixing diff distilled into a typed decision record — root cause, the approach that landed (and the rejected alternatives), and the outcome — validated against the thread and surfaced as drive-by context on the anchored symbols.
Rides your existing grep. A grep-augmentation hook injects the memories and symbols behind whatever you just searched for.
Flags clones as you write them. A PreToolUse hook on Write/Edit/MultiEdit fingerprints the functions you're writing and warns when they're exact or near-duplicates of code already in the repo — so an agent reuses instead of re-implementing. Read-only, and a silent no-op when the index isn't ready, so it never blocks a write.
Related MCP server: agentmako
Quickstart
For Claude Code, Codex, and opencode, install the plugin. It registers the MCP server, adds the
hooks, and fetches a version-matched rag-rat binary on first run, which the MCP server exposes as
~/.local/bin/rag-rat when it starts — see Running the CLI (the Claude Code and
Codex bundles also add the skills; on opencode add them with npx @rag-rat/skills):
# Claude Code
claude plugin marketplace add cq27-dev/rag-rat
claude plugin install rag-rat@rag-rat
# Codex
codex plugin marketplace add cq27-dev/rag-rat
codex plugin add rag-rat@rag-rat
# opencode (add -g for a global install)
opencode plugin @rag-rat/plugin-opencodeAfter installing, approve the plugin so its tools and hooks run (opencode loads plugins without an approval step — nothing to do there):
Claude Code asks before each rag-rat MCP tool the first time it runs — choose "Yes, don't ask again," or pre-allow them in
~/.claude/settings.jsonwith"permissions": { "allow": ["mcp__plugin_rag-rat_rag-rat__*"] }(plugin tools are namedmcp__plugin_rag-rat_rag-rat__<tool>; a server added by hand withclaude mcp addusesmcp__rag-rat__*instead).Codex shows a "Hooks need review" prompt on the first
codexsession started inside the repo (the plugin ships grep-augmentation, clone-check, and session-digest hooks that run outside the sandbox). Choose "Trust all and continue" to enable them. For unattended commands such ascodex review, also allow the plugin's MCP tools in~/.codex/config.tomlso the run cannot stall on a per-tool approval prompt:[plugins."rag-rat@rag-rat".mcp_servers.rag-rat] default_tools_approval_mode = "approve"This trusts every current and future MCP tool exposed by the installed rag-rat plugin. Only enable it when you trust the plugin's source and installation origin, then restart Codex.
Then open the repository and ask:
Set up rag-rat in this repo.
The init-rag-rat skill scans the repo, explains the material choices, previews rag-rat.toml,
writes and indexes only after confirmation, and offers to set up the git hooks that keep the index
fresh. The MCP server starts dormant in an unconfigured repo; when setup finishes, reconnect it so it
restarts fully active against the new index — in Claude Code run /mcp and reconnect rag-rat; in
Codex and opencode, start a new session.
Then put it to work — the loop rag-rat is built for is in Try it.
Use this path for the standalone CLI, agents without plugin support, or building from source.
Install the CLI
The prebuilt package needs no Rust toolchain and supports Apple Silicon macOS, glibc ≥2.38 Linux (x86-64 and arm64), Windows x64, and Android/Termux arm64:
npm install -g @rag-rat/bin
# or run it without installing:
npx @rag-rat/bin --help@rag-rat/bin fetches the full binary from the matching GitHub release. FastEmbed's ONNX Runtime is
statically linked.
To build from source instead:
cargo install rag-rat
# or from a checkout:
cargo install --path crates/rag-rat-cli --bin rag-ratThe default source build needs glibc ≥2.38 and is unavailable for Intel macOS and musl/Alpine. On those platforms, including Ubuntu 22.04, use the pure-Rust embedder:
cargo install rag-rat --no-default-features --features model2vec--no-default-features alone produces a smaller hash-only build without real embeddings. SQLite is
bundled; see Platform support for toolchain details.
Initialize the repository
cd /path/to/your/repo
rag-rat initinit is an interactive terminal wizard: it scans the repo, guides language and embedding choices,
writes rag-rat.toml, and builds the initial index. For a non-interactive setup use
rag-rat init --yes, which takes the defaults and installs the git maintenance hooks (add
--no-hooks to skip them; --dry-run previews the config without writing). --yes never replaces
an existing rag-rat.toml unless you add --force — rerun the wizard to reconfigure instead.
Configuration reference: docs/config.md.
Add skills and connect MCP
Install the skills for Claude Code, Codex, Cursor, and 70+ other detected agents:
npx @rag-rat/skillsThat installs using-rag-rat, dream-review, init-rag-rat, and
configure-rag-rat-dream. See skills/README.md for per-agent flags and
update, list, and remove.
The MCP server uses STDIO: the client launches rag-rat mcp from the repository so it discovers the
correct rag-rat.toml and repository scope in the consolidated machine-global store.
claude mcp add --scope project rag-rat -- rag-rat mcp
codex mcp add rag-rat -- rag-rat mcpOr add the equivalent project configuration:
{
"mcpServers": {
"rag-rat": { "command": "rag-rat", "args": ["mcp"] }
}
}rag-rat init prints the registration command but does not register the server itself. Pass
rag-rat mcp --json if the client must parse JSON; tool text defaults to TOON. Full tool
schemas: docs/mcp-tools.md.
Claude Code asks once before each rag-rat MCP tool first runs. Choose "Yes, don't ask again," or
allow the tool namespace in ~/.claude/settings.json:
{ "permissions": { "allow": ["mcp__rag-rat__*"] } }Do not pin a global server to one repository's config. A user-scoped server with
--config /some/repo/rag-rat.tomlserves that repository everywhere. Register MCP per project and let the process discover the config from its working directory.
Try it
Once the repo is indexed, the code graph, symbols, git history, semantic search, and clone
detection are ready — these answer on the first query. Repo memories start empty: they accrue as
agents record findings with memory_create and then surface automatically in later answers.
(Tracker issue/PR rationale needs a rag-rat papertrail sync.)
Ask your MCP client:
"Run
impact_surfaceon the function I'm about to edit — its callers, callees, tests, and recent commits.""Where is config reload handled?" — hybrid
semantic_searchover source and docs."What are the most load-bearing symbols in this repo?" —
important_symbols."Does this helper duplicate anything already in the codebase?" —
find_clones(and the write-time hook warns as you write it)."Record an invariant on
parse_config: reload must not allocate after the scheduler starts." —memory_createwrites your first repo memory; it then rides along in futureimpact_surface/symbol_lookupresults.
Or from the CLI:
rag-rat query "where is config reload handled?"
rag-rat important-symbols --limit 20
rag-rat brief --mode spine
rag-rat clusters --limit 10
rag-rat tools impact-surface --symbol parse_configThe agent loop
The point isn't the tool catalog — it's the loop an agent runs around an edit, so it changes code with the callers, tests, rationale, and prior art in front of it instead of guessing:
Before editing a symbol, ask
impact_surface. One call returns the current source anchor, callers and callees, related tests, git/GitHub rationale, the repo memories bound to that symbol / path / call-path, and confidence + coverage warnings.Read the blast radius, then edit. The invariant a previous agent recorded, the caller three hops away, the test that pins the behavior — all surfaced before the change, not discovered after.
The clone hook catches duplication at write time. If the new function reimplements code that already exists, the Write/Edit hook says so, with the existing symbol to reuse.
Record what you learned. When the edit reveals a durable invariant, decision, or footgun,
memory_createstores it as a source-anchored repo memory — so the next agent (or the next session) gets it in one call instead of re-deriving it.
A trimmed impact_surface answer (TOON — the default output; abbreviated here) — every field is
evidence, not prose:
query:
ref: "crates/config/src/config.rs::parse_config"
resolution: syntactic
direct_semantic_callers[12]:
- from_symbol: "crates/runtime/src/boot.rs::start"
edge_kind: calls_name
confidence: syntactic
callsite:
path: "crates/runtime/src/boot.rs"
line: 88
importance:
label: local structural load
score: 6.8
bucket: high
tests_touching_symbol_path[4]:
- path: "crates/config/src/config_tests.rs"
reason: test_mentions_symbol_or_path
recent_commits_touching_symbol_path[1]:
- evidence[1]: "a1b2c3d touched crates/config/src/config.rs: fix reload race during startup (#141)"
repo_memories:
direct[2]:
- kind: Invariant
title: "Config reload must not allocate after the scheduler starts"
confidence: high
anchor_status: current
binding_kind: symbol
- kind: Decision
title: "TOML over JSON5 for the config surface (#88)"
anchor_status: current
binding_kind: path
completeness_and_caveats:
exact_graph_callers: 12
memory_status:
active: 2
stale: 0
caveats[1]: "Graph evidence is tree-sitter/syntactic, not compiler-grade name resolution."And the write-time clone warning an agent sees before it duplicates logic — verbatim hook output:
▶ rag-rat clone check — code you're writing duplicates existing functions:
• `normalize_path_for_lookup` (line 42) is ~91% similar to crates/index/src/paths.rs::canonicalize_lookup_path
Prefer reusing the existing function(s) over duplicating — impact_surface / symbol_lookup to inspect them.The tools
rag-rat's tool catalog is exposed through both MCP and native CLI commands. The full catalog
and JSON schemas are documented in docs/mcp-tools.md. Run
rag-rat tools --help to browse every tool or rag-rat tools <name> --help to inspect arguments
from the canonical schema. Existing curated commands such as query, brief, memory, and dream
stay unchanged. The ones you'll reach for most:
impact_surface— the coding preflight from the loop above: callers, callees, tests, git history, GitHub papertrail, and the repo memories crossing a symbol, in one call. Memories default to compact, scannable headers; passfull_memories: truefor full bodies + bindings.semantic_search— hybrid BM25 + vector recall over source and docs, validated against current source. Every hit reportsretrieval_mode;explain=truebreaks down the score.symbol_lookup— exact/fuzzy symbol resolution; cfg/overload variants grouped as one logical symbol.find_callers/trace_callees— reverse/forward call-graph traversal (low-signal std/macro noise filtered by default).important_symbols— the load-bearing symbols by (SCIP-aware) PageRank, seeded from your current diff by default; seedocs/oracle.md.find_clones— exact + near-miss duplicate functions ranked by refactor ROI (the candidate graph is precomputed in the background, so it scales to large repos).memory_create— record a source-anchored repo memory;dreamsurfaces the maintenance worklist that keeps them honest (below).
Beyond these: repo orientation (repo_brief, repo_clusters), history and rationale
(history_for a symbol, path, chunk or commit; history_search over commits, issues and review
discussion), memory recall (memory_search, memory_for_*) and index health (index_status).
Maintenance and diagnostics — dream, heal_index, memory_doctor, graph-vs-compiler audits,
the memory task graph — are in the opt-in admin and graph toolsets ([mcp] toolsets), so they
stay out of every agent's tool list until wanted. All documented in
docs/mcp-tools.md.
Repo memories
Repo memories are first-class local evidence — not chat memory, not cloud personalization. They
are versioned, local, source-anchored facts about this repository. Each is typed
(Invariant, Decision, RejectedAlternative, Risk, BugPattern, PerformanceNote, …) and
source-anchored: bound to a logical symbol, concrete symbol, chunk, path+span, graph edge,
call-path, commit, or GitHub ref. rag-rat tracks each anchor as current, relocated, stale,
gone, or unverified, and surfaces matching memories through the memory_* tools and inline in
read_chunk, symbol_lookup, find_callers, trace_callees, and impact_surface. They're how
hard-won context reaches the next agent in one call instead of evaporating.
Memories are also a typed graph, not just a flat list: memory_edge_add / memory_edges connect
them with relations (depends_on, relates_to, supersedes, derived_from, tracks) — a task DAG,
a mind-map link between decisions, or a task that tracks a GitHub issue. Full tool list:
docs/mcp-tools.md.
Self-maintaining memories
Memories rot: the code moves under them, an invariant gets superseded, a load-bearing function ships
with no memory at all. dream is the maintenance loop that keeps the layer honest. It recomputes
a ranked worklist of findings about the memories themselves — each with a stable id to review:
coverage gaps — load-bearing symbols (by the same PageRank as
important_symbols) that carry no memory, so the next agent editing them gets nothing.stale references — a memory citing a path or anchor that no longer resolves.
dream runs the deterministic findings on every call. Two opt-in model passes go deeper, running
a small model on an ephemeral remote GPU ([llm.dream.remote]) only when work is pending:
rag-rat dream --verify recomputes each memory's verdict against current source reality (has the
code drifted from what the memory claims?), and --compact rewrites a verbose memory to a tighter
summary. Findings those passes persist surface back through dream.
Nothing is deleted automatically. A human — or a strong agent over MCP — burns the worklist down with
dream_review (accept a real gap, dismiss noise, reset a prior verdict), and verdicts
survive future runs so settled findings don't come back. It's the same surface as the CLI
rag-rat dream / rag-rat dream <id> --accept|--dismiss|--reset.
Compiler-grade resolution & ranking
The graph is heuristic by default. The opt-in SCIP oracle (rag-rat oracle run) upgrades edges
to a Compiler tier from a real language tool, recovers calls tree-sitter missed, flags external
edges, and makes important_symbols surface the genuine god-modules. For C/C++ the scip-clang
oracle distinguishes declarations from definitions and sharpens call/type edges in macro-heavy or
multi-target code — the difference between usable and noisy graphs on firmware, kernels, drivers, and
SDKs. Turn on [oracle] auto_run and the MCP server keeps it fresh on its own (throttled,
watcher-safe). Full details: docs/oracle.md.
Freshness
rag-rat mcp runs a background file watcher (on by default; [watch] enabled = false or
RAG_RAT_NO_WATCH=1 to disable), so graph/symbol queries reflect uncommitted edits without a commit.
Indexed rows are git-context-aware: clean files are stored by commit_sha, dirty/untracked files in
a worktree overlay, so one database reuses rows across branch switches while reflecting local edits.
Optional git hooks (rag-rat hooks install) keep the index current on checkout/merge/rewrite/commit.
read_chunk and search validate hits against current source and heal stale entries before returning.
One watcher per worktree and one writer at a time are enforced with file locks (unreliable on
NFS / WSL2 /mnt mounts).
Editor Lens HTTP API
An active rag-rat mcp process also elects one authenticated Lens HTTP server per worktree. It
publishes the loopback URL and bearer token to .rag-rat/sockets/lens.json; the credential file is
owner-readable only on Unix. Set RAG_RAT_NO_LENS=1 to disable this embedded server, or set
RAG_RAT_LENS_ORIGINS to a comma-separated exact browser-origin allowlist.
Run rag-rat serve when the HTTP API needs its own lifecycle. Loopback serving generates a token;
clients read it from the discovery file. A non-loopback bind requires both an explicit token
environment variable and at least one trusted browser origin:
LENS_TOKEN="$(openssl rand -hex 32)" rag-rat serve \
--bind 0.0.0.0 --token-env LENS_TOKEN --allow-origin https://lens.example.comEvery non-preflight request uses Authorization: Bearer <token>. Allowed origins are matched
exactly; wildcard CORS is never emitted. The built-in listener is plain HTTP, so terminate TLS in a
trusted reverse proxy or tunnel before exposing a non-loopback server across an untrusted network.
By default every repo's index and memories live in one consolidated database per machine
($XDG_DATA_HOME/rag-rat/rag-rat.sqlite; override with RAG_RAT_DATA_DIR), so a deleted checkout or
git clean -fdx no longer loses your authored memories. Set an explicit [index] database to keep a
repo on its own file (deprecated), and run rag-rat consolidate to import a pre-existing
.rag-rat/index.sqlite into the global store — see docs/config/database.md.
Output format
The CLI and MCP results default to TOON (Token-Oriented Object Notation) — a token-efficient
encoding that renders uniform rows as a dense [N]{cols}: table (~30% smaller than compact JSON on
those payloads, never larger in practice). Pass --json (CLI, either position) or launch
rag-rat mcp --json (MCP) when a JSON parser must read the output.
Embedding backends
The default local embedder (FastEmbed) needs no setup, but a large repo or a stronger model is worth
offloading. rag-rat speaks the OpenAI-compatible /v1/embeddings API, so a [llm.embedding.remote]
block can serve embeddings from Ollama, vLLM, or michaelfeil/infinity — one client, one place to
audit and secure. Two modes:
Connect to a server you already run (set
endpoint).Ephemeral — let the bundled cookbook provision a GPU worker (Modal / RunPod) just for the backfill and tear it down afterward (set
cookbook); pick the backend and GPU class in config.
The init flow warns when a short-context model would truncate long code chunks and steers you to a
long-context code embedder, and rag-rat auto-tunes the client concurrency against the chosen
backend so the sweep finds its throughput knee. Setup and every knob: docs/config.md.
Retrieval quality
Search quality is measurable, not guesswork. rag-rat ships a commit-replay evaluation harness
(rag-rat eval --replay): each recent commit becomes a case — its message is the query, the files it
touched are the gold set — and search is scored on how well it recovers them. It reports recall@3
(did the right chunk land in the first three reads?), recall@10, and MRR@10, and CI tracks the trend
on Bencher on main so a regression is caught before it
ships.
Reach for it when comparing embedding models, changing chunking, enabling int8 vector storage
(smaller on disk), or tuning a remote backend — you can prove the change didn't cost recall instead
of hoping. (rag-rat eval requires a --features eval build; it is absent from the released binary.)
Benchmarks
The headline workload is indexing the whole Linux kernel (v7.0, ~63k C/H files, 9.14M graph edges).
Full numbers — wall-clock, throughput, peak RSS, on-disk size, unresolved-edge taxonomy — are in
docs/benchmarks.md. Performance is tracked per-push and gated per-PR; the live
history is at bencher.dev/perf/rag-rat/plots (wiring:
docs/bencher.md).
Security
The MCP server exposes read-only source tools. It never executes shell commands or writes your source
files. It writes only the configured SQLite index — during indexing, migration, maintenance,
reconciliation, repo-memory operations, and automatic stale-index healing. GitHub sync is explicit
and uses gh api; normal query tools read only the local cache.
Local vs remote embedding
With the default local embedder, nothing leaves the machine — indexing and querying are entirely
local. Configuring a [llm.embedding.remote] backend is what sends text off the box, in two places:
the chunk text selected at index time, and the query text of each semantic search (a search
embeds your query to compare it against the indexed vectors). A CONNECT backend embeds both against
the configured endpoint; an ephemeral backend embeds queries against the local query_endpoint.
What the endpoint is decides how much that matters:
Your own server (self-hosted Ollama / vLLM / infinity) — the text stays in infrastructure you control.
Ephemeral Modal / RunPod workers (the cookbook path) are ephemeral compute providers running your open-source embedder, not data services that train on inputs. Both are SOC 2 Type II, encrypt in transit and at rest, isolate tenants, and tear the box and its storage down after the backfill — a data-processor relationship, reasonable for proprietary code the same way a cloud VM is.
A third-party embedding API you don't control is the one to actually read the terms on (retention, training on inputs).
Sensible hygiene regardless of backend: exclude secrets, generated files, and vendor trees from the
indexed targets so they're never chunked or embedded, and keep secrets out of query text. Details:
docs/config.md.
Platform support
rag-rat builds and tests on Linux, macOS, and Windows. Linux is covered on every PR and on every
push to main; macOS and Windows are exercised on release, so cargo install rag-rat builds and
links on all three. Android (aarch64, bionic) is also a release target — a prebuilt binary is
attached to each release and published to @rag-rat/bin, so npx @rag-rat/bin works on Termux; see
Quickstart.
SQLite is bundled (compiled from source via rusqlite), so there's no system-library prerequisite,
but each platform needs a C toolchain: Linux ships one; on macOS install the Xcode Command Line
Tools (xcode-select --install); on Windows install the Visual Studio Build Tools with the C++
workload (MSVC). Requires Rust 1.98+; the workspace tracks that stable baseline for its
dependencies (the bundled SQLite build itself requires at least Rust 1.95 for cfg_select!).
A few maintenance conveniences are Unix- or Linux-only by design and degrade quietly elsewhere — no feature of the index, query, or MCP surface is affected:
Hot-upgrade of a running MCP server (the
SIGUSR1in-place re-exec) is Unix-only. On Windows, restartrag-rat mcpto pick up a new binary.Fleet auto-upgrade (signalling other running servers when a new binary lands) is Linux-only — it walks
/proc— and is a no-op elsewhere.The grep-augmentation hook uses a warm Unix-socket listener (with per-session dedupe) on Linux and macOS; on Windows it falls back to a per-call read-only query straight against the index, which works the same but without cross-call dedupe.
Commands
Running the CLI
Commands in this README and in docs/ are written as rag-rat <command>.
With the plugin, rag-rat is ~/.local/bin/rag-rat (Windows:
%USERPROFILE%\.local\bin\rag-rat.cmd): the MCP server keeps that shim pointing at the plugin's
version-matched binary from its first start, and moves it forward when the plugin updates. Like
Claude Code's installer, it does not edit your shell profile or PATH. If rag-rat is not found,
~/.local/bin is not on your PATH — add export PATH="$HOME/.local/bin:$PATH" to your shell
profile, or run ~/.local/bin/rag-rat doctor, whose cli section gives the exact fix for your
system. The shim never replaces a rag-rat there that it did not create; RAG_RAT_NO_PATH_SHIM=1
turns it off.
Without the plugin, install the CLI: npm install -g @rag-rat/bin or cargo install rag-rat.
Last resort, with neither, run it through npx pinned to the version your MCP server runs (the
version field of the index_status tool):
npx -y @rag-rat/bin@<version> <command>Keep the version: an unpinned npx @rag-rat/bin runs the newest release, which migrates the index
to a schema an older plugin's server then refuses to open. Git hooks pin themselves this way and
follow plugin updates on their own.
rag-rat init # guided first-run setup
rag-rat index [--changed|--discover|--full]
rag-rat doctor
rag-rat query "semantic recall" # add --json for JSON
rag-rat important-symbols --limit 20
rag-rat brief --mode spine|churn|god_modules|refactor_candidates
rag-rat clusters --limit 10
rag-rat oracle run | status # compiler-grade resolution (docs/oracle.md)
rag-rat models list | install <model>
rag-rat reconcile --changed-first --max-seconds 60 --batch-size 64
rag-rat papertrail sync # add --full to force a historical healing pass
rag-rat memory list | show <id> | doctor | rebind <id> # inspect / re-anchor repo memories
rag-rat dream [--verify|--compact] [<id> --accept|--dismiss|--reset] # memory-maintenance worklist
rag-rat consolidate # import a legacy per-repo index into the global store
rag-rat hooks install # git maintenance hooks
rag-rat gc # prune rows for dead git contexts
rag-rat eval [--json|--update-baseline] # CI search-quality gate; requires a `--features eval` build (absent from the released binary)
rag-rat serve # authenticated editor Lens HTTP API
rag-rat tools <name> # invoke any tool directly; see `tools --help`
rag-rat mcp # start the STDIO serverReleasing & license
Releases are automated by release-plz (the three crates ship in lockstep;
see docs/releasing.md). rag-rat is MIT-licensed — see LICENSE.
Prior art
rag-rat's clone-detection design is inspired by SourcererCC's scalable token-bag candidate generation, NiCad's normalized near-miss clone-detection framing, GumTree's move-aware AST differencing, and anti-unification / least-general generalization for template extraction. Planned fragment-level mining and copy-paste bug heuristics are inspired by CP-Miner.
Available Tools
47 toolscheck_library_usageA
Dependency-contract check for the code's EXTERNAL library calls, from the SCIP oracle's external symbol info. For each resolved-external call site it surfaces the dependency's CURRENT signature + docs as inline context (judge arity / misuse yourself) and ASSERTS a deprecated verdict when the docs mark it so. Filter by path, package, or deprecated_only. Requires an oracle run; returns a NoOracleRun / NoExternalSymbols status otherwise. Does NOT assert arity or removed/renamed drift (not instrumented / needs a cross-version baseline) — those stay context.
Inputs: path, limit, package, worktree, +1 more.
clones_for_symbolB
The clone class containing a symbol (by id / ref / path+line). Returns the candidate class if the symbol is fingerprinted and has clone siblings; null if it is unique or not fingerprinted.
Inputs: id, ref, line, path, +1 more.
commit_searchB
Full-text search over historical commit subjects and bodies — find when/why something changed by keyword.
Inputs: query (required), limit, worktree.
commits_touching_queryC
Combine commit-message matches with current file-change evidence for a query — "what work relates to X?" across both messages and the files that changed.
Inputs: query (required), limit, worktree.
compare_graph_to_scipA
Cross-check the tree-sitter graph against the SCIP compiler oracle — report the edges where they DISAGREE on a callee's resolution (the compiler contradicts tree-sitter). A resolver-debugging diagnostic; requires rag-rat oracle run first to populate compiler verdicts. Reports nothing when no oracle data exists for this checkout.
Inputs: worktree.
compare_graph_to_textA
Cross-check a symbol's graph caller edges against a regex text search of indexed source — surfaces call sites the tree-sitter graph missed and flags likely false edges. Use when you suspect graph coverage gaps.
Inputs: pattern (required), id, ref, limit, +5 more.
docs_for_symbolC
Find documentation related to a symbol — markdown chunks and doc comments, preferring local context before broad docs.
Inputs: id, ref, limit, symbol, +5 more.
dreamA
Return the deterministic memory-maintenance worklist: coverage gaps (load-bearing symbols with no memory) + stale references (a memory citing a path that no longer resolves), ranked, each with a stable id to review. This is the pull surface for a strong agent to burn down the worklist. Recomputes the deterministic findings on each call (like rag-rat dream); it does NOT run the opt-in model verdict/compaction passes — those stay on the CLI/cron rag-rat dream --verify|--compact, and the findings they persist (e.g. memory_divergence) still surface here. Review a finding with dream_review.
Inputs: all, limit.
dream_reviewA
Apply a human verdict to ONE dream finding by id (a full id or unambiguous prefix): accept (a real gap to act on), dismiss (noise), or reset (clear a prior verdict, back to open). Dream only proposes; this is how the reviewer confirms. The verdict survives future dream runs. Mirrors rag-rat dream <id> --accept|--dismiss|--reset.
Inputs: finding (required), verdict (required).
ffi_surfaceA
Find the FFI surface: #[uniffi::export] items, exported impl members, and generated binding artifacts (detected by path). Empty in repos without FFI.
Inputs: limit, worktree.
find_callersA
Find what calls a symbol (reverse call graph), instead of grepping for call sites. Returns call sites with confidence + target verification, a completeness / false-positive risk summary, and repo memories crossing the call path. Includes synthesized dispatches edges for message/enum (actor-channel) dispatch — the sender that constructs the variant a handler's match arm handles. Resolve the symbol with symbol_lookup first when a name is ambiguous.
Inputs: id, ref, limit, symbol, +5 more.
find_clonesA
Ranked candidate clone classes (unrefined; exact overlap metrics). Returns classes sorted by ROI (cross-module spread × member count × token length × load-bearing factor × cohesion), with a completeness provenance block. min_similarity (if set) must be in [0.5, 1.0] (default 0.7). A LIMITED query (limit: N) is capped at the refine budget (currently 50) — it returns at most 50 classes, all refined; pass limit: null/omit it to retrieve all classes (only the top 50 refined). completeness.refine_budget_clamped is true when a supplied limit hit that cap.
Inputs: limit, worktree, min_copies, min_similarity.
git_blame_chunkA
Hash-bound git blame for one chunk: who last touched its lines, computed lazily and cached against the chunk hash.
Inputs: chunk_id (required), worktree.
git_history_for_pathA
List commits that touched a current path, newest first, with additions/deletions and subjects.
Inputs: path (required), limit, worktree.
git_history_for_symbolB
Resolve a symbol, then list commits touching its file — symbol-scoped history without needing the path.
Inputs: id, ref, lang, limit, +3 more.
heal_indexA
Re-index stale already-indexed files and refresh FTS — repair when reads report drift. Writes only to the index, never to source.
Inputs: limit.
impact_surfaceA
Pre-edit blast radius for a symbol or path: graph callers/callees, tests, docs, git history, tracker papertrail, and the repo memories crossing it, with a completeness / risk summary. Run this before changing anything non-trivial. Distilled decision records for the symbol ride along as distilled_records (labeled unreviewed, capped at 2; the cap is signalled in completeness_and_caveats.truncated_sections when more exist).
Inputs: id, ref, limit, query, +6 more.
important_symbolsA
Rank the most load-bearing symbols by weighted PageRank over the call/type/import edge graph — what the rest of the code most depends on. Run before editing to see the spine you shouldn't reinvent or break. By DEFAULT (no personalize) it auto-seeds from your current git diff, returning importance relative to your current changes; pass personalize (names, refs, or sym_<hex> handles you're working on) to seed it explicitly, or a single "global" to force whole-repo PageRank. The result is a labeled object: mode (which scale), seed_source (seed provenance), and symbols.
Inputs: limit, worktree, personalize.
index_statusB
Index freshness vs HEAD: git/indexed head, per-language file counts, parser failures, FTS sync state, and schema version.
Inputs: worktree.
llm_statusA
Embedding status (local or remote/Ollama-served): model, install state, and how many chunks are embedded / missing / skipped.
Inputs: worktree.
memory_createA
Record a durable, source-anchored repo memory (Invariant / Decision / Risk / BugPattern / …) bound to a symbol, chunk, path, edge/call-path, commit, or tracker ref — so the rationale resurfaces for the next agent editing that code. Capture non-obvious invariants and decisions as you discover them.
Inputs: body (required), kind (required), title (required), confidence (required), +5 more.
memory_doctorA
List repo memories whose anchor is stale, gone, or pending, each with suggested re-anchor targets (qualified names) — the actionable companion to memory_validate. A pending anchor is alive on an in-flight worktree branch: informational only — do NOT rebind or mark it obsolete; it re-anchors when that branch lands. Read-only; reports the last-validated status, so run memory_validate first for a fresh check. Rebind stale/gone entries with memory_rebind.
Inputs: worktree.
memory_edge_addA
Add a typed graph edge from a source node to another node or a GitHub issue. Relations: depends_on (task DAG), relates_to (mind-map link), supersedes, derived_from, tracks (issue <- task). Give exactly ONE target: a target_node_id (with an optional target_repo_id for a cross-repo edge) or a full github ref (owner + repo + number).
Inputs: relation (required), source_node_id (required), github_repo, github_owner, +3 more.
memory_edge_removeB
Remove a graph edge by its stable edge_key.
Inputs: edge_key (required).
memory_edgesA
List a node's typed edges: direction=from returns its outgoing edges (deps / links / tracks); direction=into is the reverse traversal (e.g. tasks that track an issue, or nodes that depend on this one).
Inputs: direction (required), node_id, worktree, github_repo, +2 more.
memory_for_call_pathC
Return repo memories bound to a specific call-path edge sequence.
Inputs: edge_sequence_hash (required), limit, worktree.
memory_for_pathB
Return repo memories bound to a path.
Inputs: path (required), limit, worktree.
memory_for_symbolC
Return repo memories bound to a symbol (or its logical-symbol group).
Inputs: id, ref, limit, symbol, +2 more.
memory_mark_obsoleteA
Mark a repo memory obsolete — kept for audit, hidden from active recall.
Inputs: memory_id (required).
memory_rebindA
Re-anchor an existing repo memory to a different symbol, chunk, path, or other source location — use this after a symbol moves or is renamed rather than obsoleting and recreating the memory. Replaces the binding and refreshes the source_text_hash so the memory stays current.
Inputs: bind (required), memory_id (required).
memory_searchB
Full-text search across active (or stale) repo memories by keyword.
Inputs: query (required), limit, worktree.
memory_showA
Expand ONE repo memory to its FULL body by memory_id — the expand path for a compact summary. When [memory] surface = "summary" renders drive-by attachments (e.g. impact_surface) as the dream-compacted summary, call this with the attachment's memory_id to get the complete original. Surface-independent: always the full body.
Inputs: memory_id (required), worktree.
memory_updateC
Update a repo memory's text, status, confidence, kind, or tags by id.
Inputs: memory_id (required), body, kind, tags, +4 more.
memory_validateA
Re-anchor every repo memory against current source and mark each current / relocated / stale / gone / pending. Runs automatically after indexing.
papertrail_for_chunkB
The 'why' behind a chunk: its current text plus the cached tracker items (issues / change requests) and review comments that reference it.
Inputs: chunk_id (required), limit, worktree.
papertrail_for_commitB
Cached tracker items (issues / change requests / reviews) related to a historical commit.
Inputs: commit_hash (required), limit, include, worktree.
papertrail_for_symbolB
Resolve a symbol, then return its current context plus the cached tracker rationale (issues / change requests / reviews) referencing it.
Inputs: id, ref, lang, limit, +3 more.
papertrail_issue_searchA
Full-text search across cached tracker issue and change-request titles and bodies. A hit whose thread has a distilled decision record carries it as record (the model's root-cause / decision / outcome over the whole thread); coalesced issue↔PR pairs answer as one result.
Inputs: query (required), limit, worktree.
papertrail_refs_for_pathC
List cached tracker items discovered to reference a current path.
Inputs: path (required), limit, worktree.
papertrail_sync_statusA
Papertrail cache status: counts of issues, change requests, comments, and refs, plus last sync time.
Inputs: worktree.
rationale_searchC
Search cached tracker rationale snippets (review comments, issue / change-request discussion) by keyword. A hit whose thread has a distilled decision record carries it as record (the model's root-cause / decision / outcome over the whole thread).
Inputs: query (required), limit, include, worktree.
read_chunkA
Read the current source text for one chunk id, validated against HEAD (relocates or flags stale/gone), with compact call-graph context and bound repo memories. Use to read exact text after a search returns a chunk_id. When the chunk's symbol has distilled decision records they attach as distilled_records (labeled unreviewed, capped at 2).
Inputs: chunk_id (required), include, worktree, graph_limit, +1 more.
repo_briefA
Orientation for an unfamiliar repo: ranked files by mode — spine (central coupling), churn, god_modules, or refactor_candidates — with size/coupling/churn/memory signals and suggested next tools. Start here when you don't know the codebase.
Inputs: mode, limit, include, worktree.
repo_clustersC
Map the repo into ownership clusters from path proximity, graph edges, and git co-touch — a cheap overview of subsystems and their representative files.
Inputs: limit, include, worktree, min_cluster_size.
semantic_searchA
Search indexed source and docs. score is a blended relevance score combining BM25 lexical rank and (when an embedding model is installed) vector cosine similarity; pass explain=true for the per-component breakdown. Each hit carries retrieval_mode ('lexical', 'vector', or 'hybrid') so you can tell whether embeddings contributed without explain. Hits are validated against current source. Falls back to BM25-only (every hit 'lexical') when no embedding model is present. When a hit's symbol has a distilled decision record (the model's resolved root-cause / decision / outcome over the tracker thread that shaped it), it rides along as distilled_records — labeled unreviewed, capped at 2; empty for almost every hit.
Inputs: query (required), limit, explain, include, +3 more.
symbol_lookupA
Resolve a symbol name (or ref/id) to its definition(s) in Rust, TypeScript, Kotlin, C, C++, Python, or Swift — exact or fuzzy. Returns candidates with signatures, locations, logical-symbol grouping (cfg variants), and any bound repo memories. Use to disambiguate before a graph or read call. Generated bindings (codegen, ubrn FFI output) are excluded by default; pass include: ["generated"] to see them. A candidate whose symbol has distilled decision records carries them as distilled_records (labeled unreviewed, capped at 2; empty for almost every symbol).
Inputs: id, ref, lang, limit, +4 more.
trace_calleesA
Find what a symbol calls (forward call graph). Same evidence shape as find_callers; unresolved std/common-method noise is filtered out by default (add common_methods / unresolved to the include array to keep it).
Inputs: id, ref, limit, symbol, +5 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 47 tools
Most tools target a distinct anchor or data source, and the search family is cleanly partitioned across source/docs, commits, tracker issues, rationale, and memories. A few near-overlaps exist—commit_search vs commits_touching_query and dream vs memory_doctor both touch stale-memory work—but explicit descriptions make misselection unlikely for most calls.
Names are uniformly snake_case and generally follow a readable pattern: verb_noun for operations like memory_create and find_callers, and domain_for_target for retrievals like papertrail_for_symbol and memory_for_path. Odd phrasings like commits_touching_query, compare_graph_to_text, and repo_clusters deviate from a strict verb_noun rhythm but remain predictable.
47 tools is a very large MCP surface, well beyond the 25-tool threshold the rubric flags as too many. The count is inflated by narrow query variants—papertrail_for_chunk/symbol/commit/path and memory_for_symbol/path/call_path could reasonably be parameterized anchors—so the set feels over-fragmented rather than tightly scoped.
The server covers the domain well: source/symbol/graph/history/tracker retrieval, a full memory lifecycle with edges, index maintenance, and a reviewable maintenance worklist. Minor gaps exist where required supporting actions are CLI-only, such as oracle run for SCIP comparisons and dream --verify/--compact, but core workflows have workarounds and do not dead-end.
Maintenance
Related MCP Connectors
Shared memory for coding agents. Stop re-explaining your codebase every session.
Repo intel for AI coding agents: overview, PRs, contributors, hot files, CI, deps. Remote MCP.
Team memory for AI coding agents and code reviews, reviewed by humans and served over MCP.
Codebase intelligence for AI coding agents: graph, git history, docs, decisions, code health.
Related MCP Servers
- AlicenseAqualityCmaintenanceGraph-based tool retrieval for LLM agents. Builds a tool graph from OpenAPI/MCP specs and retrieves multi-step workflows via hybrid search (BM25 + graph traversal + embedding), recovering accuracy from 12% to 82% with 79% fewer tokens. Also works as an MCP Proxy to aggregate multiple servers behind 3 meta-tools.618MIT
- AlicenseCqualityCmaintenanceLocal-first codebase intelligence engine providing AI coding agents with a typed MCP toolset for understanding and navigating code repositories.10054Apache 2.0
- AlicenseAqualityBmaintenanceProvides AI coding agents with five intelligence layers (dependency graph, git history, documentation, architectural decisions, code health) via nine MCP tools, enabling deep codebase understanding and reducing exploration cost.56,510 PyPI8,132AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceLocal-first repository memory for AI coding agents that indexes codebases into SQLite and exposes it through MCP tools, with a browser dashboard for architecture inspection.13 npmMIT