Install · Usage · MCP Server · How It Works · Integration Guide · Contributing
Context rot is empirically solved. Chroma's July 2025 research proved that even Claude Opus 4.6 scores only 76% on MRCR v2 8-needle at 1M tokens. Long context windows don't save you — they drown you. engram is the answer: a structural graph of your codebase that replaces file reads with ~300-token summaries before the agent sees them.
engram installs a Claude Code hook layer at the tool-call boundary. Every Read, Edit, Write, and Bash cat gets intercepted. When the graph has confident coverage of a file, the raw read never happens — the agent sees a structural summary instead.
Not a memory tool. Not a RAG layer. Not a context manager. A structural code graph with a Claude Code hook layer that turns it into the memory your agent can't forget to exist.
| What it is | What it isn't |
|---|---|
| Structural code graph (AST + git + session miners) | Prose memory like Anthropic's MEMORY.md |
| Local SQLite, zero cloud, zero native deps | Vector RAG that phones home |
| Hook-based interception at the tool boundary | A tool the agent has to remember to call |
| 82% measured token reduction on real code | Another LongMemEval chatbot benchmark |
| Complements native Claude memory | Competes with native Claude memory |
npm install -g engramx
cd ~/my-project
engram init # scan codebase → .engram/graph.db (~40 ms, 0 tokens)
engram install-hook # wire the Sentinel into Claude Codenpm install -g engramx
cd ~/my-project
engram init # scan codebase → .engram/graph.db
engram install-hook # wire into Claude Code (project-local)That's it. The next Claude Code session in that directory automatically:
- Replaces file reads with graph summaries (Read intercept, deny+reason)
- Warns before edits that hit known mistakes (Edit landmine injection)
- Pre-loads relevant context when you ask a question (UserPromptSubmit pre-query)
- Injects a project brief at session start (SessionStart additionalContext)
- Logs every decision for
engram hook-stats(PostToolUse observer)
An 11-page visual walkthrough of the full lifecycle — the four hook events, the Read handler's 9-branch decision tree (with a real JSON response), the six-layer ecosystem substrate, and measured numbers from engram's own code.
- 📄 View the PDF — A3 landscape, 11 pages, 1 MB. GitHub renders it inline when clicked.
- 🌐 HTML source — single self-contained file. Download raw and open in any browser for the interactive scroll-reveal version.
Every Claude Code session burns ~52,500 tokens on things you already told the agent yesterday. Reading the same files, re-exploring the same modules, re-discovering the same patterns. Even with a great CLAUDE.md, the agent still falls back to Read because Read is what it knows.
The ceiling isn't the graph's accuracy. It's that the agent has to remember to ask. v0.2 of engram was a tool the agent queried ~5 times per session. The other 25 Reads happened uninterrupted.
v0.3 flips this. The hook intercepts at the tool-call boundary, not at the agent's discretion.
v0.2: agent → (remembers to call query_graph) → engram returns summary
v0.3: agent → Read → Claude Code hook → engram intercepts → summary delivered
Projected savings: -42,500 tokens per session (~80% reduction vs v0.2.1 baseline). Every number is arithmetic on empirically verified hook mechanisms — not estimates.
npm install -g engramxRequires Node.js 20+. Zero native dependencies. No build tools needed.
cd ~/my-project
engram init # scan codebase, build knowledge graph
engram install-hook # install Sentinel hooks into .claude/settings.local.json
engram hook-preview src/auth.ts # dry-run: see what the hook would doOpen a Claude Code session in that project. When it reads a well-covered file, you'll see a system-reminder with engram's structural summary instead of the full file contents. Run engram hook-stats afterwards to see how many reads were intercepted.
engram hook-stats # summarize hook-log.jsonl
engram hook-disable # kill switch (keeps install, disables intercepts)
engram hook-enable # re-enable
engram uninstall-hook # surgical removal, preserves other hooksengram init [path] # Scan codebase, build knowledge graph
engram init --with-skills # Also index ~/.claude/skills/ (v0.2)
engram query "how does auth" # Query the graph (BFS, token-budgeted)
engram query "auth" --dfs # DFS traversal
engram gods # Show most connected entities
engram stats # Node/edge counts, token savings
engram bench # Token reduction benchmark
engram path "auth" "database" # Shortest path between concepts
engram learn "chose JWT..." # Teach a decision or pattern
engram mistakes # List known landmines
engram gen # Generate CLAUDE.md section from graph
engram gen --task bug-fix # Task-aware view (general|bug-fix|feature|refactor)
engram hooks install # Auto-rebuild graph on git commitengram intercept # Hook entry point (called by Claude Code, reads stdin)
engram install-hook [--scope <s>] # Install hooks into Claude Code settings
# --scope local (default, gitignored)
# --scope project (committed)
# --scope user (global ~/.claude/settings.json)
engram install-hook --dry-run # Preview changes without writing
engram uninstall-hook # Remove engram entries (preserves other hooks)
engram hook-stats # Summarize .engram/hook-log.jsonl
engram hook-stats --json # Machine-readable output
engram hook-preview <file> # Dry-run Read handler for a specific file
engram hook-disable # Kill switch (touch .engram/hook-disabled)
engram hook-enable # Remove kill switchSeven hook handlers compose the interception stack:
| Hook | Mechanism | What it does |
|---|---|---|
PreToolUse:Read |
deny + permissionDecisionReason |
If the file is in the graph with ≥0.7 confidence, blocks the Read and delivers a ~300-token structural summary as the block reason. Claude sees the reason as a system-reminder and uses it as context. The file is never actually read. |
PreToolUse:Edit |
allow + additionalContext |
Never blocks writes. If the file has known past mistakes, injects them as a landmine warning alongside the edit. |
PreToolUse:Write |
Same as Edit | Advisory landmine injection. |
PreToolUse:Bash |
Parse + delegate | Detects `cat |
SessionStart |
additionalContext |
Injects a compact project brief (god nodes + graph stats + top landmines + git branch) on source=startup/clear/compact. Passes through on resume. |
UserPromptSubmit |
additionalContext |
Extracts keywords from the user's message, runs a ≤500-token pre-query, injects results. Skipped for short or generic prompts. Raw prompt content is never logged. |
PostToolUse |
Observer | Pure logger. Writes tool/path/outputSize/success/decision to .engram/hook-log.jsonl for hook-stats and v0.3.1 self-tuning. |
- Any handler error → passthrough (never block Claude Code)
- 2-second per-handler timeout
- Kill switch (
.engram/hook-disabled) respected by every handler - Atomic settings.json writes with timestamped backups
- Never intercept outside the project root
- Never intercept binary files or secrets (.env, .pem, .key, credentials, id_rsa, ...)
- Never log user prompt content (privacy invariant asserted in tests)
- Never inject >8000 chars per hook response
- Stale graph detection (file mtime > graph mtime → passthrough)
- Partial-read bypass (Read with explicit
offsetorlimit→ passthrough)
Default scope is .claude/settings.local.json — gitignored, project-local, zero risk of committing hook config to a shared repo. Idempotent install. Non-destructive uninstall. --dry-run shows the diff before writing.
If anything goes wrong, engram hook-disable flips the kill switch without uninstalling.
engram runs three miners on your codebase. None of them use an LLM.
AST Miner — Extracts code structure (classes, functions, imports, exports, call patterns) using pattern matching across 10 languages: TypeScript, JavaScript, Python, Go, Rust, Java, C, C++, Ruby, PHP. Zero tokens, deterministic, cached.
Git Miner — Reads git log for co-change patterns (files that change together), hot files (most frequently modified), and authorship. Creates INFERRED edges between structurally coupled files.
Session Miner — Scans CLAUDE.md, .cursorrules, AGENTS.md, and .engram/sessions/ for decisions, patterns, and mistakes your team has documented. Stores these as queryable graph nodes.
Results are stored in a local SQLite database (.engram/graph.db) and queryable via CLI, MCP server, or programmatic API.
Connect engram to Claude Code, Windsurf, or any MCP client:
{
"mcpServers": {
"engram": {
"command": "npx",
"args": ["-y", "engramx", "serve", "/path/to/your/project"]
}
}
}Or if installed globally:
{
"mcpServers": {
"engram": {
"command": "engram-serve",
"args": ["/path/to/your/project"]
}
}
}MCP Tools (6 total):
query_graph— Search the knowledge graph with natural languagegod_nodes— Core abstractions (most connected entities)graph_stats— Node/edge counts, confidence breakdownshortest_path— Trace connections between two conceptsbenchmark— Token reduction measurementlist_mistakes— Known failure modes from past sessions (v0.2)
If your agent stack runs shell commands instead of JSON-RPC MCP, use the reference wrapper at scripts/mcp-engram. One command handles all projects via -p <path> — no per-project MCP server needed.
cp scripts/mcp-engram ~/bin/mcp-engram && chmod +x ~/bin/mcp-engram
mcp-engram query "how does auth work" -p ~/myrepoSee docs/INTEGRATION.md for multi-machine setups, rule-file integration, and gotchas.
After building a graph, run:
engram gen # Auto-detect CLAUDE.md / .cursorrules / AGENTS.md
engram gen --target claude # Write to CLAUDE.md
engram gen --target cursor # Write to .cursorrules
engram gen --target agents # Write to AGENTS.mdThis writes a structured codebase summary — god nodes, file structure, key dependencies, decisions — so your AI assistant navigates by structure instead of grepping.
engram gen --task <name> emits different content based on what you're about to do. The four preset views are defined in src/autogen.ts as a data table — no branching logic — so you can add your own task modes without touching the renderer.
engram gen --task general # default — balanced mix of sections
engram gen --task bug-fix # emphasizes hot files + past mistakes
engram gen --task feature # emphasizes architecture + decisions
engram gen --task refactor # emphasizes god nodes + dependency graphEach view picks a different set of sections with different limits. For example, bug-fix omits ## Decisions and ## Key dependencies entirely (they'd just be noise when you're chasing a regression) and leads with 🔥 Hot files and ⚠️ Past mistakes.
| engram | Mem0 | Graphify | aider repo-map | CLAUDE.md | |
|---|---|---|---|---|---|
| Code structure | AST extraction (10 langs) | No | Yes (tree-sitter) | Yes (tree-sitter) | No |
| Persistent memory | SQLite graph, survives sessions | Yes (vector + graph) | Static snapshot | Per-session only | Manual text file |
| Session learning | Mines decisions, patterns, mistakes | Generic facts | No | No | You write it by hand |
| Universal | MCP + CLI + auto-gen | API only | Claude Code only | aider only | Claude Code only |
| LLM cost | $0 | $0 (self-host) / paid cloud | Tokens for docs/images | Per-session | $0 |
| Code-specific | Built for codebases | Generic AI memory | Yes | Yes | No |
| Temporal | Git history mining | No | No | No | No |
The gap nobody fills: Code-structural understanding + persistent cross-session learning + temporal awareness + works with every AI tool. engram is the first to combine all four.
Every relationship in the graph is tagged:
| Tag | Meaning | Score |
|---|---|---|
| EXTRACTED | Found directly in source code (import, function definition) | 1.0 |
| INFERRED | Reasoned from patterns (git co-changes, session decisions) | 0.4-0.9 |
| AMBIGUOUS | Uncertain, flagged for review | 0.1-0.3 |
You always know what was found vs guessed.
engram reports two honest baselines:
- vs relevant files — compared to reading only the files that match your query. This is the fair comparison. Typical: 3-11x fewer tokens.
- vs full corpus — compared to sending your entire codebase. This is the worst case you're avoiding. Typical: 30-400x fewer tokens.
Both are reported transparently. No inflated claims.
Auto-rebuild the graph on every commit:
engram hooks install # Install post-commit + post-checkout hooks
engram hooks status # Check installation
engram hooks uninstall # Remove hooksCode changes trigger an instant AST rebuild (no LLM, <50ms). The graph stays fresh without manual re-runs.
import { init, query, godNodes, stats } from "engram";
// Build the graph
const result = await init("./my-project");
console.log(`${result.nodes} nodes, ${result.edges} edges`);
// Query it
const answer = await query("./my-project", "how does auth work");
console.log(answer.text);
// Get god nodes
const gods = await godNodes("./my-project");
for (const g of gods) {
console.log(`${g.label} — ${g.degree} connections`);
}src/
├── cli.ts CLI entry point
├── core.ts API surface (init, query, stats, learn)
├── serve.ts MCP server (5 tools, JSON-RPC stdio)
├── hooks.ts Git hook install/uninstall
├── autogen.ts CLAUDE.md / .cursorrules generation
├── graph/
│ ├── schema.ts Types: nodes, edges, confidence
│ ├── store.ts SQLite persistence (sql.js, zero native deps)
│ └── query.ts BFS/DFS traversal, shortest path
├── miners/
│ ├── ast-miner.ts Code structure extraction (10 languages)
│ ├── git-miner.ts Change patterns from git history
│ └── session-miner.ts Decisions/patterns from AI session docs
└── intelligence/
└── token-tracker.ts Cumulative token savings measurement
TypeScript, JavaScript, Python, Go, Rust, Java, C, C++, Ruby, PHP.
- ✅ Skills miner — index
~/.claude/skills/into the graph - ✅ Adaptive gen — task-aware views (
--task general|bug-fix|feature|refactor) - ✅ Regret buffer — surface past mistakes at the top of query results
- ✅
list_mistakesMCP tool - ✅ Atomic init lockfile
- ✅ Marker-safe
writeToFile+ surrogate-safe truncation
- Tree-sitter WASM (20+ languages with full call-graph precision)
- Cross-project graph (query patterns across all your projects)
- Temporal graph (commit-snapshot deltas — "what changed in auth this week?")
- Token enforcement PreToolUse hook for Claude Code
- LLM-free semantic search (locality-sensitive hashing over n-grams)
- Graph-as-IR experimental spike
- Team memory sync (paid tier)
Everything runs locally. No data leaves your machine. No telemetry. No cloud. The only network call is npm install.
Apache 2.0
Issues and PRs welcome. Run engram init on a real codebase and share what it got right and wrong.
