Show HN: Amdb – Local code context MCP server, single Rust binary Amdb, a zero-runtime, single-binary code context MCP server that indexes codebases entirely on the local machine with combined graph and vector retrieval, has been released as an open-source tool. The Rust-based tool requires no Node or Python runtime and is designed for air-gapped environments, CI containers, and regulated industries where cloud-based codebase indexing is prohibited. In benchmarks against its own 31-file source tree, Amdb achieved 100% precision targeting, 91.5% global efficiency reduction, and 81.7% noise reduction. amdb turns your codebase into AI context — entirely on your machine. amdb is a zero-runtime, single-binary code context MCP server with combined graph + vector retrieval. No code leaves the machine and no Node/Python runtime is required. Built for air-gapped environments, CI containers, and regulated industries where cloud-based codebase indexing is prohibited. cargo install amdb Or download a static binary for Linux/macOS from the Releases page https://github.com/BETAER-08/amdb/releases — no toolchain required. amdb init . index the repo: AST parse + local embeddings, incremental amdb serve expose the index as an MCP server over stdio Done. Prefer a file instead of a server? amdb generate --focus "auth" writes a targeted context file to .amdb/ . VSCode / Cursor — add .vscode/mcp.json to your project: { "servers": { "amdb": { "command": "amdb", "args": "serve" } } } Claude Code : claude mcp add amdb -- amdb serve The server exposes three tools, all reading from the pre-built local index: | Tool | What it returns | |---|---| amdb get context | Full project overview: files, symbols, and the mermaid dependency graph | amdb focus | Context narrowed to a query via name match + semantic vector search, expanded by depth dependency hops | amdb get symbol | Every definition of a symbol name as JSON: file, kind, line, signature, callers, and callees — each callee carries its resolved file and a resolution value same-file , global-unique , or unresolved | If no index exists the tools respond with an error asking you to run amdb init — the server never indexes on its own. Real session, 1.0 seconds end-to-end scripts/demo.sh /BETAER-08/amdb/blob/main/scripts/demo.sh : bash $ amdb init . INFO Initializing amdb in: . INFO Scanning files in .... INFO Files: 35 unchanged, 0 changed, 0 added, 0 removed INFO Indexing 0 files using 12 threads... INFO Embedding calls: 0 INFO Project indexed successfully at . $ amdb serve MCP client calls amdb get symbol with {"name": "cosine similarity"} cosine similarity — src/core/vector store.rs:196 signature: fn cosine similarity a: & f32 , b: & f32 - f64 visibility: private called by: search src/core/vector store.rs calls: iter, map, sqrt, sum, zip Answer came from the local index. No network. No code left the machine. To record the cast on a host with asciinema: asciinema rec -c "AMDB BIN=./target/release/amdb ./scripts/demo.sh" demo.cast , then agg demo.cast demo.gif . Measured by benchmark.py /BETAER-08/amdb/blob/main/benchmark.py against amdb's own source tree 31 files, 21,887 raw tokens . Full methodology and caveats in benchmark.md /BETAER-08/amdb/blob/main/benchmark.md . | Metric | Score | Meaning | |---|---|---| | Precision targeting | 100% 28/28 indexed files | Query = exact file stem; the file's own section comes back. A retrieval-plumbing test, not a semantic-search-quality test | | Global efficiency | 91.5% reduction | Focus output tokens vs. a full-repo dump | | Noise reduction | 81.7% compression | Interface tokens vs. raw tokens, top-5 largest files | | Graph presence | 100% 28/28 | Output contains real -- dependency edges | 3 of 31 files are module-declaration files with no extractable symbols; they are not in the index and are excluded from the denominator, not silently counted. Symbols and the call graph are extracted for all 16 grammars, but is public and signature enrichment is AST-accurate for only three languages. The rest fall back to is public = true and no signature — honest table below, so you know what you get: | Language | Extensions | Symbols + call graph | is public / signature | |---|---|---|---| | Rust | .rs | ✅ | ✅ AST-accurate | | Python | .py | ✅ | ✅ AST-accurate | | TypeScript | .ts , .tsx | ✅ | ✅ AST-accurate | | JavaScript | .js , .jsx , .mjs | ✅ | fallback true / none | | C | .c , .h | ✅ | fallback true / none | | C++ | .cpp , .hpp , .cc , .cxx | ✅ | fallback true / none | | C | .cs | ✅ | fallback true / none | | Go | .go | ✅ | fallback true / none | | Java | .java | ✅ | fallback true / none | | Ruby | .rb | ✅ | fallback true / none | | PHP | .php | ✅ | fallback true / none | | HTML | .html , .htm | ✅ | fallback true / none | | CSS | .css | ✅ | fallback true / none | | JSON | .json | ✅ | fallback true / none | | Bash | .sh , .bash | ✅ | fallback true / none | amdb init parses every source file with Tree-sitter, extracts symbols and call edges, and embeds each symbol with a local fastembed model — content-hashed, so unchanged files are skipped entirely on re-runs. Everything lands in two SQLite files: a symbol/relationship store and a vector store. Retrieval combines exact name matching, cosine similarity over the vectors, and call-graph expansion, served over MCP stdio or written to a Markdown context file. Same fixture repo amdb's own source , same five questions "where is symbol X defined, and who calls it?" , all numbers actually measured by benchmark.py . We did not run competitor indexing tools, so none appear here; the baselines are a raw full-repo dump and a scripted grep-then-read-matched-files agent protocol. | Strategy | Avg tokens to model | Avg tool calls | |---|---|---| | Raw full-repo dump | 21,887 | 1 | | grep + read matched files | 4,180 | 2.4 | amdb --focus , depth 1 | 3,972 | 1 | On a 31-file repo, grep is genuinely competitive on tokens — amdb's edge at this scale is one structured call instead of 2–4, with signatures, visibility, and resolver-accurate caller/callee attribution instead of raw text. The token gap widens with repo size: the dump grows linearly, grep grows with match noise, amdb's focus output grows with the size of the relevant interface. Daemon mode — amdb daemon watches the project and incrementally re-indexes on save, keeping the MCP answers fresh. Focus depth — amdb generate --focus