The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the NervaPack listing page.
NervaPack is a privacy-first, offline knowledge graph for your codebase. It solves two fundamental problems with standard Vector RAG:
NervaPack runs 100% on your machine. It uses tree-sitter to parse your codebase into a deterministic Abstract Syntax Tree graph, then uses a local Ollama model to draw hard semantic edges between your documentation and your code. Queries traverse this graph with a K-Hop BFS, returning a hyper-targeted, token-efficient context window — no cloud required.
91.2% Average Token Reduction — independently verified on real-world codebases.
| Test Type | Tokens (Naive) | Tokens (NervaPack) | Reduction |
|---|---|---|---|
| Simple Query | 10,926 | 101 | 99.1% |
| Medium Query | 13,092 | 164 | 98.7% |
| Complex Query | 3,290 | 1,102 | 66.5% |
| Average | 52,037 | 2,459 | 91.2% |
Cost Savings: $181–$724 per developer per year (GPT-4o to Claude Sonnet)
📊 View Full Benchmarks · 🧪 Messy Code Performance
Code quality impact: 90–99% reduction on clean code, 50–75% on legacy/messy code. Even poorly structured codebases benefit significantly.
| Standard Vector RAG | NervaPack | |
|---|---|---|
| Parsing | Arbitrary text chunks | Deterministic AST nodes (class, function, import) |
| Retrieval | Nearest-neighbour blob | K-Hop BFS on a structural graph |
| Doc ↔ Code links | None | Hard EXPLAINS edges drawn by local LLM |
| Privacy | Cloud embeddings | 100% local (ChromaDB + ONNX + optional Ollama) |
| Incremental sync | Re-index everything | Surgical per-file update via GitPython diff |
| Token savings | No measurement | Built-in dashboard shows exact reduction per query |
| Graph visibility | Black box | Interactive HTML visualization of every node and edge |
| Duplicate-safe | Repeated ingest = duplicate data | upsert — re-ingest is idempotent |
| Agent memory | None | 17-tool MCP server for cross-session memory |
git init if not)(Optional for semantic code-doc binding) — an LLM provider. Structural graph indexing and basic queries work out-of-the-box with zero configuration and no cloud connection.
| Provider | Setup | Cost | Privacy |
|---|---|---|---|
| Ollama (default) | brew install ollama && ollama pull llama3 | Free | 100% local |
| Claude API | pip install "nervapack[claude]" + ANTHROPIC_API_KEY | ~$0.25/1k calls | Cloud |
| OpenAI API | pip install "nervapack[openai]" + OPENAI_API_KEY | ~$0.15/1k calls | Cloud |
| MCP (Claude Code) | Zero config | Included in subscription | Cloud |
On first run, ChromaDB downloads an ONNX embedding model (~30 MB) to
~/.cache/chroma/. This is a one-time download.
nervapack ingest [PATH] — Build the graphScans PATH (default: .) and builds the full knowledge graph.
What happens:
dist/, build/, node_modules/, venv/, site/, .tox/, and dozens of other build directories automatically..md files by header hierarchy.EXPLAINS edges..nervapack/graph.graphml.Re-ingesting is safe — upsert is used throughout, so running ingest twice does not duplicate data.
Supported languages (bundled): Python, JavaScript, JSX, TypeScript, TSX
Additional languages:
Exclude directories — create .nervapackignore in your project root (gitignore syntax):
nervapack query PROMPT — Query the graphRetrieves focused context for a natural-language prompt and prints a token savings dashboard.
What happens:
EXPLAINS edges and memory notes via TOUCHES edges — are collected.Example output:
nervapack sync [PATH] — Incremental updateUpdates only the files that changed since the last ingest. Uses GitPython to diff the working tree.
A full ingest on a large project can take minutes. sync turns that into a 2–5 second surgical update per file. Re-parses changed files, batch-upserts new vectors, and saves the graph once at the end.
nervapack clean [OPTIONS] — Remove ingested dataWipe graph data and start fresh. Use this when you have duplicate vectors, ingested the wrong directory, or need to reduce disk usage.
Never deleted by clean: memory.db — your agent memory is always safe.
Typical workflow after a bad ingest:
nervapack enrich [PATH] — Add semantic edgesRuns LLM doc-to-code binding on an already-ingested graph. Use this if you:
ingest without an LLM and want to add EXPLAINS edges now.nervapack status [--detailed] — Graph healthHealth score (0–100) factors in documentation coverage, node connectivity, graph density, and edge diversity. A structural-only graph typically scores 30–40; after enrich it rises to 70–90.
nervapack visualize [OPTIONS] — Interactive HTML graphProduces a standalone HTML file with no external dependencies — drag, zoom, search, find shortest paths between nodes.
nervapack explore TARGET [--hops N] — Focused subgraphExtract and visualize the N-hop neighbourhood of a specific file, class, or function.
nervapack dependencies [FILE] — Import dependency analysisAnalyze file-level import chains, detect circular dependencies, and visualize the dependency graph.
nervapack hotspots [OPTIONS] — Change frequency analysisShow which files change most often in git history — prime targets for documentation and review.
nervapack history [OPTIONS] — Query historynervapack serve [--port N] — Web dashboardRequires nervapack[dashboard]. Shows graph overview, language distribution, analytics, query history trends, and an interactive graph explorer.
nervapack doctor — Environment checkVerifies Python version, tree-sitter grammars, embedding backend, Ollama connectivity, and MCP config. Run this after installation or when troubleshooting.
Everything lives in .nervapack/ inside your project root:
Add .nervapack/ to .gitignore to keep it out of version control.
Disk usage guide:
chroma_db/ — typically 10–100 MB depending on project size. Run nervapack clean --vectors && nervapack ingest . if it grows unexpectedly.graph.graphml — typically 0.5–5 MB.memory.db — grows with agent usage; rarely exceeds a few MB.NervaPack ships two MCP servers in the same package. Drop this .mcp.json in your project root:
nervapack-mcp)| Tool | What it does |
|---|---|
query | Vector search → K-Hop BFS → focused Markdown context + token savings |
graph_status | Node/edge counts, language breakdown, unsynced file warnings |
explore | Browse all indexed classes, functions, imports, markdown docs |
impact | Reverse dependency analysis — find what depends on a given entity |
nervapack-memory-mcp) — 17 tools| Tool | Purpose |
|---|---|
memory_start_session | Open a named session |
memory_store | Persist a fact, decision, outcome, procedure, preference, or action |
memory_recall | FTS5 search → graph expansion → scored, budget-capped recall |
memory_about | Entity dossier: all facts/decisions linked to one entity |
memory_why | Explain a decision: rationale, rejected alternatives, outcomes |
memory_timeline | Chronological trace including superseded versions |
memory_end_session | Close session with an outcome summary |
memory_forget | Tombstone or hard-purge nodes |
memory_verify | Confirm (confidence +0.1) or refute (close + confidence ×0.5) |
memory_stats | Node counts, DB size, top entities, all namespaces |
memory_list_sessions | List all sessions with node counts |
memory_clear_session | Delete a session and all its nodes |
memory_for_code | Memories that TOUCH a source file or specific line |
memory_to_code | Code locations a memory node TOUCHES |
memory_import | Bulk-seed memory from a JSON array |
memory_switch_namespace | Switch the active namespace |
memory_verify_staleness | Flag memories whose source file changed since stored |
Add to your CLAUDE.md to wire NervaPack into every Claude Code session:
Key source modules:
| Module | Responsibility |
|---|---|
nervapack.parser.ast_parser | tree-sitter parsing → ParsedEntity; shared singleton parser instance |
nervapack.parser.md_chunker | Markdown → header-delimited chunks; prunes build dirs from os.walk |
nervapack.graph.builder | NetworkX DiGraph; O(1) file-index for sync; compiled regex for REFERENCES |
nervapack.graph.vector_store | ChromaDB upsert (idempotent); pluggable embedding function |
nervapack.graph.retrieval | K-Hop BFS with deque (O(n) not O(n²)) |
nervapack.graph.token_meter | tiktoken singleton; token savings panel |
nervapack.graph.query_history | Tail-read JSONL — O(limit) not O(total) |
nervapack.graph.analytics | Bulk graph.degree() — single call not per-node loop |
nervapack.llm.base | bind_docs_to_ast with keyword pre-filter (top-12 candidates) |
nervapack.llm.providers.ollama | ollama.list() cached 60 s |
nervapack.memory.store | SQLite + FTS5; bi-temporal; batch_neighbors for O(1) hop expansion |
nervapack.memory.recall | Batched hop expansion; audit trail on recall |
nervapack.mcp_server | FastMCP — query, graph_status, explore, impact |
nervapack.memory.mcp_server | FastMCP — 17 memory tools |
Stop re-pasting project context into every new chat.
Token efficiency:
| Approach | Tokens per session | After 20 sessions |
|---|---|---|
| Manual paste (architecture doc) | ~2,400 | ~48,000 |
memory_recall | ~171 | ~3,420 |
| Savings | 93% fewer tokens |
CLI:
Data model: 8 node kinds, 7 edge kinds, bi-temporal (valid_from/valid_until), never hard-deletes by default.
NervaPack is 100% offline by default:
localhost:11434 only..nervapack/ inside your project.Only if you explicitly pass --llm claude or --llm openai does any code leave your machine.
python3 -m pytest tests/memory/ -qpython3 -m mkdocs build --strictmaster.Bug reports and feature requests: issue tracker.
MIT — see LICENSE.