cd /news/developer-tools/show-hn-amdb-local-code-context-mcp-… · home topics developer-tools article
[ARTICLE · art-71815] src=github.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

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.

read7 min views1 publishedJul 24, 2026
Show HN: Amdb – Local code context MCP server, single Rust binary
Image: source

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 — 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):

$ 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 against amdb's own source tree (31 files, 21,887 raw tokens). Full methodology and caveats in

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 modeamdb daemon

watches the project and incrementally re-indexes on save, keeping the MCP answers fresh.

Focus depthamdb generate --focus <query> --depth N

expands context N call-graph hops from the matched files (default 1).

Configuration — optional amdb.toml

in the project root:

db_path = ".database"
ignore_patterns = ["target", ".git", "node_modules", ".amdb", ".fastembed_cache", "__pycache__", ".database"]

AMDB_DB_PATH

overrides db_path

. Add .database/

and .amdb/

to your .gitignore

.

Verbose-v

/ --verbose

on any command for debug logs.

Docker — the repo Dockerfile

builds a slim image whose entrypoint is amdb serve

, so the container speaks MCP over stdio immediately:

docker build -t amdb .
docker run --rm -v "$PWD:/workspace" --entrypoint amdb amdb init .
docker run -i --rm -v "$PWD:/workspace" amdb

The published ghcr.io/betaer-08/amdb:1.0.0

image predates the serve entrypoint — it runs bare amdb

, so pass the subcommand explicitly: docker run -i --rm -v "$PWD:/workspace" -w /workspace ghcr.io/betaer-08/amdb:1.0.0 serve

. Images published from the next tag serve by default.

amdb follows semantic versioning. 1.0.0 freezes the contract below; anything listed as covered changes only in a 2.0 release, and contract tests in tests/contract_test.rs

fail loudly if it drifts.

Covered by the 1.0 promise:

CLI— subcommandsinit

,daemon

,generate

,serve

; flags--focus

/-f

,--depth

/-d

,--verbose

/-v

; the optional path argument toinit

anddaemon

. Exit codes: 0 on success, 1 on unrecoverable error.MCP tools— exactlyamdb_get_context

,amdb_focus

,amdb_get_symbol

with their current input parameters.amdb_get_symbol

responses keep every current field with its current type:file

,name

,kind

,line

,signature

,is_public

,callers[]

(name

,file

),callees[]

(name

,file

,resolution

same-file

|global-unique

|unresolved

). New fields and newresolution

values may beaddedin minor releases; existing ones are never renamed, removed, or retyped.Configamdb.toml

keysdb_path

andignore_patterns

, and theAMDB_DB_PATH

environment override. Unknown keys are ignored.Database upgrades— the index schema is versioned viaPRAGMA user_version

. Any database written by amdb ≥ 0.6 opens without error and migrates automatically; the nextamdb init

rebuilds whatever the migration invalidated. Deleting.database/

is a last-resort fallback, never a required upgrade step.Generated Markdown anchors— two things ingenerate

output are stable for scripts: each indexed file gets a heading line of exactly### <relative/path>

(forward slashes, relative to the project root), and the dependency graph is a single fenced```` mermaid`

block containinggraph TD;

with-->

edge lines.

Not covered (may change in any release):

  • Every other detail of the Markdown layout: bullet and signature formatting, section ordering, mermaid node-id sanitization, header text.
  • Log and progress text on stdout/stderr.
  • The SQLite table layout and the vector-store file format (only automatic migration is promised, not the bytes).
  • The benchmark harness ( benchmark.py

) and its output format. - Internal Rust APIs — amdb is a binary crate; depending on its modules as a library is unsupported.

MIT. Bug reports and inquiries: try.betaer@gmail.com

── more in #developer-tools 4 stories · sorted by recency
── more on @amdb 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-amdb-local-c…] indexed:0 read:7min 2026-07-24 ·