recon is a local-first code intelligence MCP server for AI coding agents. A small Rust binary that replaces Read, Grep, and Glob with 20 symbol-aware tools. 15–30× fewer tokens on typical exploration.
code_activate_repo; code_list_repos shows what's loaded. Sessions persist across restarts.--features local-embed for offline inference.
recon init --mcp <ide> writes the IDE's MCP config and a strict-policy
agent rules file so the agent uses recon's code_* tools before Read/Grep/Glob by default.
Twenty tools — symbol-and-text primitives, graph-aware traversal for "how does X reach Y?" and "what breaks if I change this?", and telemetry so you can prove the savings.
…. About 10× compression vs. full read.type:rust !test.src to dst. Bidirectional BFS, capped at 8 hops.sym call (directly and transitively)? Same caps, same shape.code_subsystems. Skeleton-style summary within a token budget.RepoRouter; persists the loaded set across recon serve restarts.files, symbols, and an active flag. Pairs with code_activate_repo for discovery before switching.
Token-savings telemetry runs alongside every call — per-call measured against
the in-process Read/grep equivalent for the 8 direct file/grep tools, conservative
static estimates for the remaining 12 tools. Operator surfaces:
recon stats and recon savings show in the CLI; daily rollups
on the dashboard.
// agent wants to understand render_map Glob("crates/**/*.rs") → 312 paths · ~12,000 tokens Read("crates/recon-search/src/map.rs") → 412 lines · ~6,800 tokens Grep("render_map", "crates/**") + context → 34 matches × 3-line window · ~28,000 tokens Read("crates/recon-search/tests/map_test.rs") → 142 lines · ~2,300 tokens Read 4 callers (server.rs, handler.rs, …) → 1,847 lines · ~31,000 tokens Read("crates/recon-search/src/page_rank.rs") → 218 lines · ~3,600 tokens Read("crates/recon-search/src/lib.rs") → 312 lines · ~5,100 tokens Read 6 more files for orientation → 2,170 lines · ~27,600 tokens subtotal ≈ 116,400 tokens
// same question, symbol-first + graph-aware code_find_symbol("render_map") → exact match · ~90 tokens code_outline("crates/recon-search/src/map.rs") → 14 symbols, one line each · ~210 tokens code_read_symbol("render_map") → signature, body, every caller · ~860 tokens code_context("render_map", budget=2000) → callers, callees, types, tests · ~1,520 tokens code_impact("render_map", depth=3) → blast radius: 12 callers, 4 tests · ~450 tokens code_repo_map(focus="…/map.rs", budget=1500) → pageranked overview · ~1,100 tokens code_list("crates/**/*.rs") → 312 files, symbol counts per file · ~680 tokens code_context("render_map", budget=2000) → signature + body + callers + tests · ~1,300 tokens subtotal ≈ 6,210 tokens
Headline multiples like 35× are real for fresh input tokens. Anthropic's prompt caching already absorbs most of the obvious savings on warm sessions, so the number that actually hits your bill is smaller. Here's the honest breakdown from an independent third-party measurement (grepai vs Claude Code, 155K-LOC TypeScript repo, 5 questions × 5 runs):
The gap between −97% fresh-input and −27% billed cost is prompt caching doing its job. Savings dominate on cold sessions, large repos, and tasks where the agent would otherwise spawn subagents. They shrink on warm sessions and on repos small enough that the agent would read the whole thing anyway.
Everything tree-sitter can name is a first-class citizen. Everything else is noise the agent should never pay for.
Every tool response is one of five canonical shapes in recon-core::shapes. Predictable for the model, cheap to parse.
gix ColdStart skips reparse on unchanged HEAD. A blake3 Merkle tree reindexes only what moved. First keystroke to queryable: under a second.
Every tool response passes through secret redaction — AWS keys, PEM blocks, API tokens are stripped before they reach the agent. Per-key tenant isolation.
Signed with cosign. Only your license key touches the network.
curl -fsSL https://mcprecon.pages.dev/install.sh | bash
curl -fsSL https://mcprecon.pages.dev/install.sh | bash
iwr https://mcprecon.pages.dev/install.ps1 | iex
recon login sk-recon-xxx
recon init --mcp <ide> writes the IDE's MCP config and a strict agent-rules file so the agent uses code_* tools by default.
recon init --mcp cc # Claude Code recon init --mcp oc # OpenCode recon init --mcp cursor # Cursor recon init --mcp windsurf # Windsurf recon init --mcp kiro # Kiro recon init --mcp zed # Zed recon init --mcp vscode # VS Code recon init --mcp cline # Cline recon init --mcp roo # Roo Code recon init --mcp codex # OpenAI Codex
Free · 1 repo · 250 files · 10K LOC
Pro $3/mo · 10 repos · 5K files · 200K LOC
Team $7/mo · 25 repos · 50K files · 4M LOC
No. Indexing, search, and every tool response runs on your machine. The only outbound call is a short HTTPS check to validate your license key — no paths, no queries, no source, no metadata.
Yes, once activated. recon login caches a signed license locally; after that, the CLI runs with no network at all. Enterprise keys can be issued offline end-to-end.
Every release ships a SHA256SUMS.txt signed with cosign keyless sigstore, attested by our GitHub Actions release workflow. The installer verifies digest + signature before extracting. You can re-verify by hand with cosign verify-blob.
Any MCP-compatible client. recon init writes config for Claude Code, OpenCode, Cursor, Windsurf, Kiro, Zed, VS Code Copilot MCP, Cline, Roo Code, and OpenAI Codex out of the box. Anything that speaks the MCP stdio spec will work too.
Your on-disk indexes stay. The CLI declines new tool calls until you renew — nothing is uploaded, nothing is deleted. You can keep the binary; you just can't run it against a licensed tier until you re-login.
Only what's needed to issue and bill a license: your GitHub email, your tier, and a hashed key prefix. No repo names, no file paths, no symbols. Our worker is open to inspection on request for enterprise accounts.
“The agent should spend its tokens thinking, not reading. recon gives back the context window — and most of the wall-clock — that Read and Grep quietly took. And it does it without ever sending a line of your code over the wire.”