Skip to content

Repository files navigation

Engram

CI

An engram is the hypothetical physical trace of memory in neural tissue — the biochemical change that encodes what we've learned.

Engram Galaxy View — 3D knowledge graph visualization

Local-first cognitive memory system that transforms raw LLM conversation history into structured, consolidated knowledge. Unlike traditional conversation search (which treats sessions as documents to retrieve), Engram mimics human memory architecture: episodic memories are captured, consolidated into semantic knowledge during "dream state" processing, and emergent connections surface through graph analysis — much like how a Zettelkasten's backlinks reveal Maps of Content that no individual note anticipated.

Designed as an MCP server for Claude Code and other LLM agents, with CLI and web visualization interfaces.

Install & first run

Prerequisites

  • Node.js 22 or newer (node --version)
  • macOS or Linux (the optional launchd daemon is macOS-only; everything else is portable)
  • Claude Code if you want engram sync to ingest your conversation history from ~/.claude/projects
  • At least one LLM provider for extraction and dream consolidation (see Configuration). Search, remember, and the web visualizer work without one.
git clone https://github.com/devinmlowe/engram.git
cd engram
npm install          # also runs the TypeScript build via the "prepare" script
npm link             # puts `engram` on your PATH (or run `node dist/interfaces/cli/index.js` directly)

engram init          # creates ~/.local/share/engram/engram.db and downloads the embedding model
engram sync          # index conversations from ~/.claude/projects (optional)
engram search "what did I decide about caching"

Heads up: first run downloads models. engram init, the first search, and the test suite pull nomic-ai/nomic-embed-text-v1.5 (embeddings) and Xenova/bge-reranker-base (reranker) from Hugging Face — several hundred MB in total — into the @xenova/transformers cache under node_modules/. This happens once; later runs are offline. Set ENGRAM_RERANK_ENABLED=false to skip the reranker model.

Use it from Claude Code (MCP)

Add the server to your Claude Code MCP config (~/.claude.json, or a project-level .mcp.json), pointing at the compiled server with an absolute path:

{
  "mcpServers": {
    "engram": {
      "command": "node",
      "args": ["/absolute/path/to/engram/dist/interfaces/mcp/server.js"],
      "env": {}
    }
  }
}

The .mcp.json shipped in this repo does the same thing with a repo-relative path and is picked up automatically when you open the engram checkout itself in Claude Code.

Optional: background consolidation (macOS)

./scripts/install-daemon.sh install      # nightly `engram dream` at 02:00 via launchd
./scripts/install-visualizer.sh install  # keep the web visualizer running on http://127.0.0.1:3001

Core Principles

Memory is Not Search

Engram is a cognitive system — it extracts meaning, consolidates patterns, detects contradictions, and surfaces emergent connections. Raw conversations are the input, not the output.

Token Discipline

Memory injection must be surgical. Retrieved memories are capped within caller-specified token budgets, formatted for primacy placement, and delivered via progressive disclosure — pointers first, full content only on request.

Emergent Discovery

Like a Zettelkasten, the value is in the connections. Opportunistic bidirectional linking, Maps of Content emerging from graph density, and the dream state daemon acting as the librarian who notices patterns across the collection.

Local-First, Offline-Capable

All processing runs locally. No cloud dependencies except optional API calls for extraction/summarization (replaceable with local models via Ollama for true offline operation).

Architecture

Four domains with shared core infrastructure:

  • episodic/ — Conversation archive ingestion, indexing, and episodic search
  • semantic/ — Knowledge extraction, consolidation, adaptive chunking, and semantic search
  • graph/ — Entity/relationship graph, topic clusters, file structure indexing, and graph traversal
  • dream/ — Autonomous consolidation pipeline (ingest → extract → consolidate → reflect → prune)
  • interfaces/ — CLI, MCP server, and web visualization
  • _core/ — Shared infrastructure (config, db, types, embeddings, search, llm, cache)
  • decisions/ — Architecture Decision Records

MCP Server

14 tools for LLM agent memory operations:

Tool Purpose
recall Hybrid search (vector + FTS5 + graph) with token budget
remember Store a single memory (fact, decision, pattern, etc.)
show Retrieve full conversation or memory context
explore Fixed-depth graph traversal from an entity
reflect Graph analysis — communities, bridges, temporal patterns
recall_session Stateful iterative search with session tracking and budget
recall_drill Deep drill into a specific search result with budget deduction
explore_selective Model-directed selective graph traversal with relevance filtering
remember_batch Batch memory ingest with entity linking and adaptive chunking
fetch_snippets Multi-range file snippet fetching (up to 20 ranges)
index_file_structure Parse file structure into graph entities (multi-language)
scan_file Regex-based file scanning with function context detection
commitments List tracked commitments (promises, intentions, follow-ups owed by others) — overdue first
commitments_update Mark a commitment done, dropped, or superseded

Transports: stdio (default) and HTTP

dist/interfaces/mcp/server.js speaks stdio by default, which is what the .mcp.json example in "Install & first run" uses. Start it with --http to serve Streamable HTTP instead:

node dist/interfaces/mcp/server.js --http            # http://127.0.0.1:9907/mcp
node dist/interfaces/mcp/server.js --http --port 9910

HTTP mode exposes POST /mcp (one MCP session per client, routed by the Mcp-Session-Id header) plus GET /health, which returns JSON. It binds to 127.0.0.1 only. Point any Streamable-HTTP-capable client at it:

{ "mcpServers": { "engram": { "type": "http", "url": "http://127.0.0.1:9907/mcp" } } }

In HTTP mode every tool call runs on a node:worker_threads pool, so a multi-second recall never blocks /health, the handshake, or other clients. Each worker owns its own SQLite connection and embedding model. Stdio mode never spawns workers.

Variable Default Purpose
ENGRAM_HTTP_WORKERS 2 Worker count in HTTP mode (0 = run tool calls inline on the main thread)
ENGRAM_WORKER_TIMEOUT_MS 8000 Per-call timeout; remember, remember_batch, index_file_structure and reflect --refresh use higher floors. A worker still silent at 2x the timeout is killed and respawned

See the "MCP Server Transports" section of CLAUDE.md for the worker-pool internals (worker-pool.ts, dispatch.ts, worker.ts).

Integrating other agents (Codex CLI, Cursor, custom hosts)

docs/integrate-your-agent.md is written to be handed to an AI agent running in the host you want to connect. It states the public contract (endpoints, handshake, tools, scoping) and the three behaviors to implement (auto-recall before each turn, explicit MCP tools, capture via remember), with a verify ladder and a worked Codex CLI example. The Hermes Agent provider in interfaces/hermes-plugin/ is the reference implementation.

CLI

engram init            # Initialize database + download embedding model
engram sync            # Ingest conversations from Claude Code projects
engram search <query>  # Hybrid search across all memory layers
engram remember <text> # Store a memory
engram extract         # LLM-based fact extraction from a conversation
engram dream           # Run autonomous consolidation pipeline
engram reflect         # Show emergent graph patterns
engram explore <name>  # Explore entity connections
engram entities        # List/search entities
engram relationships   # Show relationships for an entity
engram stats           # Database statistics
engram health          # System health check
engram migrate         # Migrate data from legacy superpowers DB
engram validate        # Validate migration integrity
engram backfill-event-ts  # Backfill event-time timestamps (temporal recall)
engram commitments [status]        # List tracked commitments (same XML as the MCP tool)
engram commitment-done <id>        # Mark a commitment done (--status dropped|superseded)
engram commitments-extract <conv>  # Re-scan one conversation (no checkpoint; proves dedupe)
engram mcp             # Start the MCP server (stdio; see Transports section)

Web Visualization

Interactive knowledge graph visualization at localhost:3001:

Force Graph (/graph) Depth View (/graph/depth)
Obsidian-inspired 2D force-directed graph on Canvas. Nodes sized by mention count (sqrt scale), colored by entity type with degree-based brightness. Edges render with configurable center-dim gradients. Mention threshold slider, type filter pills, text search with neighbor highlighting, click-to-focus, and node dragging. Three.js 3D graph where the vertical axis encodes relevance — a weighted blend of recency (30%), mention frequency (25%), bridge score (20%), creation age (10%), and degree (15%). Older and less-connected nodes sink to the bottom; active hubs rise to the top. Includes gravity passes that pull satellites toward their hubs and a growth animation that replays the graph's history from first node to present.
Force Graph Depth View
Galaxy View (/graph/galaxy) Word Cloud (/words)
Hub nodes (high degree + bridge score + mentions) become gravitational centers, each defining a unique orbital plane in 3D space. Satellites orbit their hub based on accretion strength (edge weight), placed at angles determined by Jaccard similarity to neighbors. Six custom forces — hub repulsion, satellite attraction, disk flattening, orbital alignment, bridge pulling, and standard charge — create a living solar-system metaphor. Configurable hub threshold, disk flatness, and system spacing. D3 word cloud built from user messages in episodic memory. Words sized by sqrt-scaled frequency, filtered through an extensive stop-word list and hex-hash detector. Catppuccin Mocha 12-color palette, Archimedean spiral packing with mixed rotation (65% horizontal, 20% vertical, 15% angled). Hover shows mention count; live polling refreshes every 10 seconds with pulse animations on changes.
Galaxy View Word Cloud
  • Dream Control — Live pipeline phase tracking with progress bars via SSE
  • Real-time Updates — SSE watching SQLite WAL for instant graph changes

Start: npx tsx src/interfaces/web/server.ts

Search

Hybrid search combining three sources with Reciprocal Rank Fusion:

  • Vector — Semantic similarity via nomic-embed-text (384 dims) with MiniLM fallback
  • FTS5 — SQLite full-text search across exchanges, memories, and entities
  • Graph — Entity traversal and relationship-aware context expansion

All search responses respect caller-specified token budgets. Stateful sessions allow iterative refinement with budget tracking.

Dream Pipeline

Autonomous consolidation mimicking human memory synthesis:

flowchart LR
    subgraph dream["Dream Daemon"]
        direction LR
        I[Ingest] --> E[Extract] --> C[Consolidate] --> R[Reflect] --> P[Prune]
    end

    subgraph episodic["Episodic"]
        sync[sync]
        store[store]
    end

    subgraph semantic["Semantic"]
        extractor[extractor]
        consolidator[consolidator]
        decay[decay]
    end

    subgraph graph["Graph"]
        gextractor[extractor]
        reflection[reflection]
    end

    subgraph core["_core"]
        llm[llm]
        db[db]
        embeddings[embeddings]
    end

    I -- "discover & index\nconversations" --> sync
    sync -- "persist\nexchanges" --> store
    E -- "extract facts" --> extractor
    E -- "extract entities\n& relationships" --> gextractor
    C -- "dedup, merge,\nconflict detect" --> consolidator
    R -- "communities, bridges,\ntemporal patterns" --> reflection
    P -- "FSRS decay,\nlow-value removal" --> decay

    extractor --> llm
    gextractor --> llm
    reflection --> llm
    store --> db
    consolidator --> embeddings
    extractor --> embeddings
Loading
  1. Ingest — Sync new conversation archives via the episodic layer
  2. Extract — LLM-based fact extraction (semantic) and entity/relationship extraction (graph)
  3. Consolidate — Deduplicate, merge, and resolve conflicts via semantic consolidator with embedding similarity
  4. Reflect — Detect communities, bridge entities, and temporal patterns via graph reflection
  5. Prune — Decay and remove low-value memories using FSRS-inspired retrievability scoring (semantic decay)

All phases use _core infrastructure: llm for LLM calls, db for persistence, embeddings for similarity.

Run via engram dream, web UI dream button, or scheduled via launchd.

Technology

Component Technology
Runtime Node.js ≥ 22 (TypeScript)
Database SQLite + WAL mode (single-file, local-first)
Vector Search sqlite-vec
Full-Text Search SQLite FTS5 (Porter stemming)
Embeddings nomic-embed-text via @xenova/transformers
Graph Analysis graphology (Louvain communities, betweenness centrality)
LLM Providers Anthropic, OpenRouter, Ollama (tiered cascade)
MCP Server @modelcontextprotocol/sdk
Daemon macOS launchd

Development

npm run build        # TypeScript compilation
npm run test:run     # Run tests (vitest, 56 test files)
npm run mcp          # Start MCP server
npm run dev          # Dev CLI via tsx
npm run dream        # Run dream consolidation
npm run lint         # Type-check without emit

Configuration

All settings are environment variables; nothing is read from a config file.

Variable Default Purpose
ANTHROPIC_API_KEY Enables the Anthropic provider (final tier of the LLM cascade)
OPENROUTER_API_KEY Enables the OpenRouter provider (middle tier)
OLLAMA_HOST http://localhost:11434 Ollama endpoint; used first if reachable
ENGRAM_LOCAL_MODEL qwen2.5:7b Ollama model name
ENGRAM_OPENROUTER_MODEL google/gemini-2.5-flash-lite OpenRouter model name
ENGRAM_DATA_DIR ~/.local/share/engram Root for database, archive, and logs
ENGRAM_DB_PATH $ENGRAM_DATA_DIR/engram.db SQLite database location
ENGRAM_ARCHIVE_DIR $ENGRAM_DATA_DIR/archive Conversation archive directory
ENGRAM_LOGS_DIR $ENGRAM_DATA_DIR/logs Log directory
ENGRAM_CLAUDE_PROJECTS_DIR ~/.claude/projects Where engram sync looks for Claude Code conversations
ENGRAM_EMBEDDING_DIMS 256 Matryoshka embedding dimensions (must match the existing DB)
ENGRAM_RERANK_ENABLED true Set to false or 0 to disable the cross-encoder reranker
ENGRAM_CHUNKING_STRATEGY fixed fixed or adaptive (content-aware boundaries)
ENGRAM_BIND 127.0.0.1 Web visualizer bind address (0.0.0.0 to expose on the network)
PORT 3001 Web visualizer port

LLM providers. Extraction and the dream pipeline try Ollama first (if OLLAMA_HOST answers), then OpenRouter (if OPENROUTER_API_KEY is set), then Anthropic (if ANTHROPIC_API_KEY is set). At least one must be configured for engram extract and engram dream; search, remember, remember_batch, and the web visualizer do not need an LLM.

References

  • SPEC.md — Full system specification with requirements and interface contract
  • SPEC-legacy.md — Original vision document with detailed design rationale
  • plans/ — Implementation plans (phases 1–4, phase 6 RLM, phase 7 extensions)
  • decisions/ — Architecture Decision Records

About

Cognitive memory system for Claude Code: episodic storage, semantic extraction, knowledge graph, and dream-state consolidation. TypeScript, MCP server, local-first.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages