AgentStack
MCP verified Apache-2.0 Self-run

Engram Mcp

mcp-edg-l-engram-mcp · by edg-l

MCP server in Rust for AI agent persistent memory: branch-aware session handoffs, local ONNX embeddings, SQLite-backed semantic search.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add mcp-edg-l-engram-mcp

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Engram Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Engram

Git-aware session memory for coding agents.

Engram is an MCP server that gives coding agents persistent memory scoped to your git branches. Capture a session as a structured handoff, switch branches, and pick up later with the prior session's decisions, blockers, and todos surfaced automatically. Backed by local SQLite and ONNX embeddings; no cloud, no LLM calls for storage.

Why this exists

  • Coding agents lose context between sessions. Notes in scratch files don't surface at the right moment.
  • Git branches encode work-in-progress boundaries that prior memory tools ignore — context from feat/auth leaks into fix/billing.
  • Engineers resume work by re-reading their own structured notes (decisions, blockers, mental model). Handoffs match that workflow instead of dumping a chat transcript.

Quickstart: session handoffs

End of session, capture state on the current branch:

engram-cli handoff create
# Prompts for: summary, decisions, todos, blockers, mental_model, next_steps, notes

Or invoke the MCP prompt from inside Claude Code: /mcp__engram__handoff.

Next session (same or different branch), restore context:

engram-cli handoff resume
# Resuming `feat/auth`, 3 handoffs in chain, latest from mem_xyz
# Top sections (summary, blockers, todos)
# Linked decisions/patterns/debug memories

Or: /mcp__engram__resume from Claude Code.

Each new handoff sets continues_from to the previous one on the same branch, forming a chain. handoff_resume walks the chain (depth 5, cycle-detected) and returns the top-scoring sections via hybrid similarity + recency. Sections automatically link to existing decision / pattern / debug memories at cosine ≥ 0.75.

When a branch has only one handoff, handoff_resume supplements linked_memories with related decision / pattern / debug memories surfaced via vector search against the query — so even a fresh branch with a single capture comes back with cross-cutting context, not five slices of the same document.

Installation

cargo install engram_mcp

Installs engram (MCP server) and engram-cli (command-line tool).

From source:

git clone https://github.com/edg-l/engram-mcp.git
cd engram-mcp
cargo build --release

Setup

Claude Code

claude mcp add -s user engram $(which engram)

Allow all Engram tools without permission prompts:

{
  "permissions": {
    "allow": ["mcp__engram__*"]
  }
}

Claude Desktop

Add to your config file:

  • Linux: ~/.config/Claude/claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "engram": {
      "command": "/path/to/engram"
    }
  }
}

Auto-capture decisions and session summaries (Claude Code)

Passively capture decisions and session summaries into Engram without any explicit tool calls. One-liner install:

engram-cli hooks install

This registers handlers for three lifecycle events: UserPromptSubmit, SubagentStop, and SessionEnd. Stop, PreCompact, and PostToolUse are explicit no-ops (per-turn noise, mid-session duplicates of SessionEnd, and low-signal tool-call outcomes respectively); tool-call outcomes are never captured. All hook stores route through the same dedup path as memory_store, so near-identical captures are silently skipped (ENGRAM_HOOK_DEDUP_SKIP, default 0.95). A per-project daily cap (ENGRAM_HOOK_DAILY_CAP, default 50) prevents runaway logging. See [hooks/README.md](hooks/README.md) for the full per-event reference, env vars, and secret redaction details.

Auto-load context on session start (Claude Code)

A hook script loads relevant memories at the start of every conversation, building a semantic query from recent git activity so the LLM gets context without needing to call memory_context.

cp scripts/engram-hook.sh ~/.claude/hooks/engram-hook.sh

Add to ~/.claude/settings.json:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/engram-hook.sh" }
        ]
      }
    ]
  }
}

Works in non-git directories. Exits silently if engram-cli is not on PATH.

Handoff skills (Claude Code)

Two opinionated skills wrap the handoff tools:

  • handoff — gathers session state and calls handoff_create
  • read-handoffs — calls handoff_resume, summarizes, pairs with memory_context
scripts/install-skills.sh

Skip if you prefer the bundled MCP prompts (/mcp__engram__handoff and /mcp__engram__resume) — they cover the same flow.

Importing legacy markdown handoffs

scripts/port_md_handoffs.py ~/.claude/handoff /path/to/repo/.claude/handoff   # dry run
scripts/port_md_handoffs.py --apply ~/.claude/handoff /path/to/repo/.claude/handoff

Maps old section headings to the new schema; resolves Continues from: chains. Lossy mapping (Dead ends → blockers); originals stay on disk as backup.

Memory beyond handoffs

Handoffs are the lead workflow, but Engram is a full memory system underneath:

  • Semantic search with hybrid scoring (cosine + recency + importance)
  • Local embeddings via mdbr-leaf-ir (256-dim MRL, quantized ONNX)
  • Memory decay with reinforcement on access and auto-pruning of dead memories
  • Pinned memories that never decay
  • Global memories visible across projects
  • Semantic deduplication at store time (≥ 0.90 auto-merge) plus periodic background dedup
  • Hierarchical clustering with centroid-based retrieval at scale
  • Relationship graphs (relates_to, supersedes, derived_from)
  • Contradiction detection flags conflicts at cosine > 0.85, scoped to the same non-handoff MemoryType (cross-type and handoff-touching matches are suppressed to avoid topical-overlap false positives)
  • Branch-aware queries filter by git branch scope
  • External artifacts: memories can declare referenced files / URLs / identifiers via external_artifacts. Retrieval lists them inline and tags local paths with [missing] if absent on the server's filesystem
  • Pre-filtered retrieval caps embedding scans for performance at scale
  • Import/export for backup and migration

Memory types

| Type | Description | Example | |------|-------------|---------| | fact | Objective information | "The API uses JWT authentication" | | decision | Architectural choices and rationale | "Chose SQLite over Postgres for simplicity" | | preference | User or project preferences | "Prefer explicit error handling over unwrap" | | pattern | Recurring approaches | "All handlers return Result, AppError>" | | debug | Past issues and solutions | "OOM was caused by unbounded channel buffer" | | entity | People, systems, services | "UserService handles all auth logic" | | handoff | Session snapshots with structured sections | Created via handoff_create; not available in memory_store | | adr | Architecture Decision Records (numbered, status-tracked) | Created via adr_create; not available in memory_store |

MCP tool reference

| Tool | Description | |------|-------------| | handoff_create | Capture a session handoff with structured sections (summary, decisions, todos, blockers, mentalmodel, nextsteps, notes) | | handoff_resume | Retrieve top sections from recent handoffs on the current branch, plus linked memories | | handoff_search | Search handoff sections by content; filter by branch or section name | | memory_store | Store a memory with embedding, auto-dedup, auto-cluster | | memory_query | Semantic search with hybrid scoring, pagination, branch filtering | | memory_context | Load relevant memories for a task (hierarchical retrieval via clusters) | | memory_update | Update content, tags, importance, pinned status | | memory_delete | Remove a memory and its relationships | | memory_link | Create typed relationships between memories | | memory_graph | Traverse relationship graph from a root memory | | memory_store_batch | Store up to 100 memories atomically | | memory_delete_batch | Delete multiple memories by ID | | memory_export | Export project memories to JSON | | memory_import | Import from JSON (merge or replace modes) | | memory_stats | Project statistics (counts, types, pinned, global, clusters) | | memory_prune | Remove low-relevance memories (dry run by default) | | memory_dedup | Find and merge duplicate memories (dry run by default) | | memory_promote | Promote a branch-local memory to global scope | | adr_create | Create a numbered, Nygard-style ADR; optionally supersede an existing ADR | | adr_update_status | Advance an ADR through its lifecycle (proposed/accepted/deprecated/rejected) | | adr_list | List the project's ADRs, optionally filtered by status | | adr_show | Show a single ADR by number | | adr_export | Export ADRs to Nygard-style Markdown files (dry run by default) |

Storing memories

{
  "content": "We chose PostgreSQL over SQLite for the API because of concurrent write requirements",
  "type": "decision",
  "tags": ["database", "api", "architecture"],
  "importance": 0.7,
  "pinned": true,
  "global": false,
  "external_artifacts": ["docs/adr/0007-postgres.md", "https://github.com/foo/bar/pull/42"]
}
  • pinned: true — never decays or gets pruned
  • global: true — visible in all projects (forces branch to null)
  • importance — 0.3 minor, 0.5 normal, 0.7 important, 0.9 critical
  • external_artifacts — optional list of file paths, URLs, or opaque IDs the memory references. Local-looking paths are existence-checked at retrieval and marked [missing] if absent. URLs and opaque IDs print unmarked (no network calls). Use memory_update with [] to clear; omit the field to preserve existing

Querying

{
  "query": "what database do we use and why",
  "limit": 10,
  "min_relevance": 0.3,
  "types": ["decision", "fact"],
  "branch_mode": "current"
}

Branch modes: current (global + current branch), global (global only), all, or a specific branch name.

CLI

# Handoffs
engram-cli handoff create                        # interactive section prompts
engram-cli handoff create --from-file session.md # ingest pre-written markdown
engram-cli handoff resume --branch feat/x        # load context from recent handoffs
engram-cli handoff search "auth refactor" --section blockers,todos

# Search
engram-cli query "how does authentication work"
engram-cli context "working on auth refactor"
engram-cli context "auth refactor" --global

# CRUD
engram-cli store "The API uses rate limiting" -t fact --tags api,security
engram-cli store "Always use snake_case" -t preference --pinned --global
engram-cli store "Bench results show BM25 wins" -t fact \
  --artifact benchmarks/longmemeval/RESULTS.md \
  --artifact https://github.com/edg-l/engram-mcp/pull/42
engram-cli show mem_abc123
engram-cli list
engram-cli update mem_abc123 -c "Updated content" --importance 0.9
engram-cli update mem_abc123 --artifact /new/path.md          # replace artifact list
engram-cli update mem_abc123 --clear-artifacts                # clear artifact list
engram-cli delete mem_abc123

# Pinning
engram-cli pin mem_abc123
engram-cli unpin mem_abc123

# Relationships
engram-cli link mem_abc123 mem_def456 -r relates_to

# Import/Export
engram-cli export -o backup.json
engram-cli import backup.json

# Maintenance
engram-cli stats
engram-cli decay
engram-cli prune -t 0.2 --confirm
engram-cli dedup -t 0.90
engram-cli dedup -t 0.90 --confirm
engram-cli wipe --confirm

# Observability
engram-cli insights
engram-cli health

Configuration

| Variable | Description | Default | |----------|-------------|---------| | ENGRAM_DB | SQLite database path | ~/.local/share/engram/memories.db | | ENGRAM_PROJECT | Project scope identifier | Git root directory name | | ENGRAM_DECAY_INTERVAL | Decay job interval (seconds) | 3600 (1 hour) | | ENGRAM_RECLUSTER_INTERVAL | Re-clustering job interval (seconds) | 21600 (6 hours) | | ENGRAM_MAX_CANDIDATES | Max candidate embeddings to score during context retrieval | 200 | | ENGRAM_ADR_DIR | Target directory for adr_export Markdown files | docs/adr | | ENGRAM_MCP_TOOL_PROFILE | Advertised MCP tool surface: full (23 tools), core (14), or minimal (3: memory_context, memory_store, handoff_resume). Dispatch stays permissive — non-advertised tools still execute with a one-time [engram] warning per process | full | | ENGRAM_HOOK_DEDUP_SKIP | Similarity threshold above which hook captures are silently dropped (clamped to [0.5, 1.0]) | 0.95 | | ENGRAM_HOOK_DAILY_CAP | Max hook-captured memories per project per UTC day; 0 = unlimited | 50 |

Retrieval benchmark

Retrieval quality on a 30-question seeded slice of LongMemEval-S (cleaned), full haystack ingested (~225–275 turn-pairs per question). See [benchmarks/longmemeval/RESULTS.md](benchmarks/longmemeval/RESULTS.md) for the full table, methodology, and caveats.

| Mode | partial-R@5 | full-R@5 | MRR | |---|---:|---:|---:| | Vector | 50.0% | 23.3% | 0.326 | | BM25 | 93.3% | 73.3% | 0.883 | | Hybrid (RRF k=60, default) | 93.3% | 70.0% | 0.828 |

LongMemEval queries reference specific entities, dates, and numbers in the haystack; FTS5 catches them exactly, which is why BM25 leads on this slice. Hybrid (Reciprocal Rank Fusion) is the published-best baseline and remains the default; flipping defaults on a 30-question slice would over-fit. The headline finding: embedder tuning is the highest-leverage retrieval improvement on this workload, not the fusion algorithm. Full 500-question run is future work.

How it compares

| Tool | Branch-aware | Structured handoffs | Per-section embeddings | Local-only | Storage | |------|:---:|:---:|:---:|:---:|---| | Engram | ✓ | ✓ | ✓ | ✓ | SQLite + ONNX | | mcp-memory-service | — | — | — | ✓ | SQLite-vec | | Mem0 | — | — | — | partial | Vector DB + LLM extraction | | Zep / Graphiti | — | — | — | — | Neo4j | | Letta (MemGPT) | — | OS-style blocks | — | partial | Pluggable |

Engram is opinionated for coding agents using git; the others target broader assistant memory. Comparison as of 2026-05.

Why not just use X?

Why not Mem0? Mem0 is cloud-default, runs LLM extraction per write, and has no branch model. Great for chat personalization; not aimed at coding agents who switch git contexts mid-day.

Why not vanilla mcp-memory-service? Solid generic memory MCP, but no handoff structure, no branch awareness. Engram trades breadth for opinionation around coding-agent workflows.

Why not a vector DB directly? A vector DB is one component. Engram adds decay, dedup, clustering, and the MCP layer — none of which a raw Qdrant/Chroma instance gives you.

Why SQLite over Postgres/libSQL? Zero-ops local-first. Embeddings are 256-dim MRL (quantized ONNX), small enough that SQLite's row size and query plan are fine for the corpus sizes a single developer accumulates. If you need multi-tenant, this isn't the tool.

How it works

Hybrid scoring

memory_context scores memories using three signals:

score = 0.6 * cosine_similarity + 0.2 * recency + 0.2 * importance

Where recency = exp(-0.02 * days_since_access). A recently accessed, important memory can outrank a slightly more similar but old, low-importance one.

Memory decay

relevance = (time_decay * importance_factor) + usage_boost

  time_decay        = exp(-decay_rate * days_since_access)
  importance_factor = 0.5 + (importance * 0.5)
  usage_boost       = ln(1 + access_count) * 0.1
  • Accessing a memory boo

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

  • Author: edg-l
  • Source: edg-l/engram-mcp
  • License: Apache-2.0
  • Homepage: https://crates.io/crates/engram_mcp

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.