@vedtechsolutions/engram-mcp
v2.2.3
Published
Persistent memory for Claude Code — survives context compaction
Maintainers
Readme
Engram — Persistent Memory for Claude Code
An engram is a unit of cognitive information imprinted in neural tissue — the physical trace of a memory.
Why Engram?
Claude Code forgets everything when the context window compacts. Your decisions, your debugging breakthroughs, your "always use X instead of Y" — gone. You repeat the same mistakes, re-explain the same architecture, re-discover the same solutions.
Engram fixes this. After compaction, Claude continues working like it never happened — with your decisions, pitfalls, and project context intact.
You Don't Need Memory MCP
If you're using Memory MCP or similar knowledge-graph memory servers, Engram replaces them entirely:
| | Memory MCP | Engram |
|---|---|---|
| Encoding | Manual — Claude must decide to call create_entities | Automatic — hooks capture errors, corrections, decisions without tool calls |
| Recall | Manual — Claude must call search_nodes | Automatic — pitfalls injected before writes, corrections on session start |
| After compaction | Nothing — Claude doesn't know the memory server exists | Full recovery — briefing auto-injected with task, files, decisions, pitfalls |
| Context cost | Every tool call burns tokens | Zero-token hooks — hooks run outside the context window |
| Learning | Store and retrieve | Encode, decay, and surface — confidence scoring, relevance matching, natural forgetting |
| Noise | Grows forever, no curation | Self-maintaining — confidence decay, dedup, stale detection |
| Error prevention | None | Pitfall surfacing — warns before you repeat known mistakes |
The Compaction Problem (and Why Hooks Solve It)
When Claude Code's context window fills up, it compacts — summarizing the conversation to free space. This destroys:
- What you were doing and why
- Decisions you made and their rationale
- Errors you hit and how you fixed them
- Files you were working on
Tool-based memory servers can't help because after compaction, Claude doesn't remember the server exists until something reminds it to call a tool. There's no automatic trigger.
Engram's hooks fire automatically:
SessionStarthook injects a briefing with your active plan, recent pitfalls, and project context — Claude picks up exactly where it left offPreCompacthook saves a snapshot of what you were doing before compaction happensUserPromptSubmithook surfaces relevant memories on every prompt — no tool call neededPreToolUsehook warns about known pitfalls before every Write/Edit/Bash
The result: compaction becomes invisible. Claude continues working with full context of your decisions, your mistakes, and your project's pitfalls.
How Much Context Does Engram Use?
Engram's post-compaction injection is ~180 tokens — just task, domain, files, and critical decisions. Everything else is pulled on-demand per prompt. Compare this to the 2000+ tokens that narrative-style memory systems inject, displacing space you need for actual work.
How It Works
┌─────────────────────────────────────────────────────┐
│ Claude Code │
│ │
│ Hooks (automatic, zero-token): │
│ SessionStart → inject briefing + pitfalls │
│ PreCompact → save snapshot before compaction │
│ PreToolUse → warn on known pitfalls │
│ UserPrompt → surface relevant memories │
│ PostToolFail → learn from errors automatically │
│ PostToolUse → boost pitfalls you avoided │
│ SessionEnd → close session, promote pitfalls │
│ │
│ MCP Tools (discretionary): │
│ engram_recall → search memories │
│ engram_learn → store a lesson │
│ engram_plan → track multi-step tasks │
│ engram_remind → "when X, remind me Y" │
│ + correct, forget, strengthen, weaken │
│ │
│ StatusLine: │
│ Engram: normal | 42 mem 3 rem │
└────────────────────┬────────────────────────────────┘
│
┌──────┴──────┐
│ SQLite DB │
│ + FTS5 │
│ ~/.engram/ │
└─────────────┘Quick Start
1. Clone and build
git clone https://github.com/vedtechsolutions/engram-mcp.git
cd engram-mcp
pnpm install
npx tsup2. Configure MCP server
Add to your project's .mcp.json:
{
"mcpServers": {
"engram": {
"command": "node",
"args": ["/path/to/engram-mcp/dist/server.js"]
}
}
}3. Configure hooks
Add to your project's .claude/settings.json:
{
"hooks": {
"SessionStart": [{
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/session-start.js" }]
}],
"PreCompact": [{
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/pre-compact.js" }]
}],
"SessionEnd": [{
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/session-end.js" }]
}],
"PostToolUseFailure": [{
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/error-learning.js" }]
}],
"PreToolUse": [{
"matcher": "Write|Edit|Bash",
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/pitfall-check.js" }]
}],
"UserPromptSubmit": [{
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/prompt-check.js" }]
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/success-tracker.js", "async": true }]
}]
},
"statusLine": {
"type": "command",
"command": "NODE_PATH=/path/to/engram-mcp/node_modules node /path/to/engram-mcp/dist/hooks/statusline.js",
"padding": 0
}
}4. Add LLM instructions
Create .claude/rules/engram.md in your project:
## Engram Memory
Briefing auto-injected at session start. Act on it immediately.
- Before non-trivial work: `engram_recall(query)` for relevant pitfalls.
- User corrects you: `engram_learn(kind:"correction", content: one sentence, project: null)`.
- Something fails unexpectedly: `engram_learn(kind:"pitfall", content: what+why+fix)`.
- Design choice: `engram_plan(decide, chose, why)`.
- Memory wrong: `engram_weaken(id)`. Memory useful: `engram_strengthen(id)`.
- User says "always do X when Y": `engram_remind(trigger, action)`.That's it. Engram starts learning from your first session.
Tools (9)
| Tool | Description |
|---|---|
| engram_recall | Search memories by query, filtered by project/kind |
| engram_learn | Store a lesson (pitfall, decision, correction, fact) |
| engram_correct | Update or invalidate a wrong memory |
| engram_forget | Hard-delete a memory |
| engram_strengthen | Boost confidence of a useful memory |
| engram_weaken | Lower confidence of a wrong memory |
| engram_plan | Create/track multi-step plans with decisions |
| engram_remind | Set trigger-action reminders ("when X, do Y") |
| engram_list_reminders | List active reminders |
Hooks (8)
| Hook | Event | What Happens |
|---|---|---|
| session-start | Session begin | Injects briefing: plan status, pitfalls, interrupted session recovery |
| pre-compact | Before compaction | Saves snapshot: modified files, read files, commands, goal, context, approach |
| session-end | Session end | Closes session, promotes cross-project pitfalls to global |
| error-learning | Tool failure | Classifies error, encodes as pitfall, boosts on repeat |
| pitfall-check | Before Write/Edit/Bash | Surfaces relevant pitfalls for the file/command |
| prompt-check | User prompt | Detects corrections, surfaces relevant memories and reminders |
| success-tracker | After Write/Edit | Boosts pitfalls you successfully avoided |
| statusline | After response | Shows context mode, memory count, reminder count |
Context-Adaptive Modes
Engram monitors context window pressure and adjusts automatically:
| Mode | Context Free | MCP Recall | Hook Injection |
|---|---|---|---|
| normal | > 50% | Full (5 results) | 3 prompt pitfalls, 2 file pitfalls, 1 bash pitfall, 3 reminders |
| compact | 25–50% | Reduced (3 results) | 1 prompt pitfall, 1 file pitfall, 0 bash, 1 reminder (~200 tokens max) |
| minimal | 10–25% | Minimal (2 results) | Zero — all hook injection disabled |
| critical | < 10% | Silent | Zero — preserves remaining context |
Memory Types
| Kind | Purpose | Example |
|---|---|---|
| pitfall | Known mistakes to avoid | "Never use store=False computed fields in search domains" |
| decision | Architectural choices | "Chose SQLite over Postgres for single-user local storage" |
| correction | User corrections | "No, always use strict equality in TypeScript" |
| fact | Knowledge and conventions | "In Odoo 19, use <list> not <tree> in views" |
Self-Maintaining
Engram maintains itself automatically:
- Confidence decay: Memories not recalled in 30 days decay by 10%. Below 0.1 confidence, they're auto-deleted (corrections are exempt)
- Deduplication: New memories with >80% token overlap to existing ones are merged
- Stale project detection: Projects with no recall in 90 days are flagged
- Plan archival: Completed plans older than 6 months are cleaned up
- FTS5 integrity: Automatic index rebuild on corruption detection
- Cross-project promotion: Pitfalls recalled in 3+ sessions are promoted from project-scoped to global
Security
- All SQL queries use parameterized statements
- FTS5 input sanitized with allowlist pattern (
[^a-zA-Z0-9\s]→ strip) - File extension sanitization prevents LIKE injection
- Transcript path validation prevents path traversal
- 1MB stdin cap on all hook inputs
- State file mode validation
- Shell metacharacter stripping in error distillation
- Atomic confidence updates prevent race conditions
Development
pnpm install # Install dependencies
npx tsup # Build (ESM, node20 target)
npx vitest run # Run tests (271 tests across 15 files)Technology Stack
| Component | Technology | |---|---| | Runtime | Node.js 20+ / TypeScript (strict mode) | | Storage | SQLite (better-sqlite3) + WAL mode | | Search | FTS5 (built into SQLite) | | Interface | MCP Server (@modelcontextprotocol/sdk) | | Validation | Zod schemas | | Build | tsup (ESM output) | | Testing | Vitest |
Status
v2.2.1 — Schema migration fix for existing databases. 271 tests, 9 tools, 8 hooks.
License
MIT
