Persistent memory for AI agents. In-process. No infra.
Give your AI agent the memory of a colleague who's worked with you for years β without cloud, API keys, or Docker.
npm install -g @hbarefoot/engram
engram startYour AI agent now has long-term memory. Two minutes, no setup, no cloud.
- π§ In-process β runs inside your agent's stack. No separate server to deploy, no IPC overhead, nothing to fork.
- π΄ Offline β local SQLite + bundled embeddings (~23 MB). No API keys, no data leaving your machine.
- π MCP-native β first-class Model Context Protocol integration with Claude Desktop, Claude Code, Cursor, Windsurf, and Cline.
- π Safety by default β automatic secret detection on every write. API keys, private keys, connection strings, JWTs blocked before they hit the database.
Most agent-memory products are services you run alongside your agent β Postgres, Docker, cloud accounts, API keys. Engram embeds inside your agent's process: a focused, stable npm package with practical guardrails.
| Engram | Lodis | Mem0 / OpenMemory | Zep | Letta | |
|---|---|---|---|---|---|
| Maturity | v1.4.x, stable | v0.5.x, early | mature / SaaS | v0.x | v0.x |
| Infra to operate | None (npm package) | None (npx package) | Cloud account or multi-container Docker | Docker + Postgres + Graphiti | Docker + Postgres |
| Install footprint | ~23 MB | ~22 MB | Hundreds of MB containers (self-hosted) | Hundreds of MB | Hundreds of MB |
| Works offline | β | β | β Cloud / β if self-hosted | β External embed provider | β External LLM provider |
| MCP-native | β Primary | β Primary | π‘ OpenMemory ships an MCP server | β REST/SDK | β REST/SDK |
| REST API alongside MCP | β | β MCP-only | β Cloud | β | β |
| Surface area | 6 tools, 5 categories | 40 tools, 14 entity types + 4 permanence tiers + temporal supersession | varies | varies | varies |
| Automatic secret detection | β Blocks on every write | π‘ memory_scrub opt-in tool |
π‘ Not first-class | π‘ Not first-class | π‘ Not first-class |
| Agent auto-discovery | β Dashboard Integration Wizard | β Manual config | β | β | β |
| Desktop app | β macOS Tauri menu bar | β | β | β | β |
| LLM-powered extraction | β Rule-based (Layer 1 hook documented) | β LLM-free read/write | β Built-in | β Built-in | β Built-in |
| Feedback / contradiction workflow | β Side-by-side conflict-resolution UI + feedback loop | π‘ Programmatic correct/confirm/supersede tools | π‘ No first-class feedback | π‘ | π‘ |
Sources: @sunriselabs/lodis, Sunrise-Labs-Dot-AI/engrams, mem0.ai, github.com/getzep/zep, github.com/letta-ai/letta. See docs/competitive-intel.md for the full breakdown. Where competitors lead β LLM-powered extraction in Mem0/Zep/Letta, broader feature surface in Lodis β we list it honestly. Engram's llm.* config block is the documented hook for opt-in LLM extraction; the default zero-config path uses rule-based extraction so the package stays offline and infra-free.
TL;DR β when each one fits. Pick Engram if you want a focused, stable memory layer with practical guardrails (secret detection, agent auto-discovery, desktop app) and a simple 5-category mental model. Pick Lodis if you want a knowledge-graph-style memory with 14 entity types and temporal supersession. Pick Mem0/Zep/Letta if you need LLM-powered extraction and don't mind operating infrastructure for it.
npm install -g @hbarefoot/engramengram start # MCP + REST + Dashboard on localhost:3838
engram start --mcp-only # MCP server only, stdio mode (for agent integration)Claude Code:
claude mcp add engram -- engram start --mcp-onlyClaude Desktop β add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"engram": {
"command": "engram",
"args": ["start", "--mcp-only"]
}
}
}Cline / Cursor / Windsurf β add the same mcpServers block to your editor's MCP config. The built-in dashboard at http://localhost:3838 has an Integration Wizard that auto-detects your installed agents and generates the config for you.
You: "Remember that our API uses JWT tokens with 24-hour expiry."
Claude: (stores via engram_remember)
You: (next day) "What authentication approach are we using?"
Claude: (recalls via engram_recall) β "JWT tokens, 24-hour expiry."
Memories persist across sessions, machine restarts, and even between different AI clients sharing the same Engram instance.
Most memory systems are append-only stores: write once, retrieve forever, hope for the best. Engram learns.
- Feedback loop (
engram_feedback) β when an agent recalls a memory, you or the agent can vote it helpful or unhelpful. Memories accumulate a score in[-1, 1]; consistently-unhelpful memories see their confidence decay automatically. - Contradiction detection β when two memories conflict ("prefers Fastify" vs "switched to Express"), the consolidation engine flags them. The dashboard's Conflicts tab shows them side-by-side with four resolution actions: keep A, keep B, keep both, or dismiss.
- Deduplication on insert β identical memories (β₯0.95 cosine similarity) are rejected. Near-duplicates (0.92β0.95) absorb the new content into the existing record. The store stays clean without manual pruning.
- Decay β memories that aren't recalled lose confidence over time and stop polluting future results.
The longer you use Engram, the sharper its recall gets.
Engram exposes 6 tools to AI agents over stdio:
| Tool | Description |
|---|---|
engram_remember |
Store a memory with category, entity, confidence, namespace, tags. Auto-runs secret detection. |
engram_recall |
Hybrid semantic + FTS5 search. Supports category, namespace, threshold, and time_filter. |
engram_forget |
Delete a specific memory by ID. |
engram_feedback |
Vote a memory helpful/unhelpful. Drives the feedback loop above. |
engram_context |
Pre-formatted context block (markdown / xml / json / plain) with a token budget for system-prompt injection. |
engram_status |
Health check: memory count, model status, configuration. |
- fact β Objective truths about setup, architecture, or configuration.
- preference β User likes, dislikes, style choices.
- pattern β Recurring workflows and habits.
- decision β Choices made and the reasoning behind them.
- outcome β Results of actions taken.
engram start # Start MCP + REST + dashboard
engram start --mcp-only # MCP server only (stdio mode)
engram start --port 3838 # Custom REST port
engram remember "<content>" # Store a memory (-c category -e entity -n namespace --confidence)
engram recall "<query>" # Search memories (-l limit -c category -n namespace --threshold)
engram forget <id> # Delete by ID
engram list # List memories (-l limit --offset -c category -n namespace)
engram status # Health check
engram consolidate # Deduplicate, detect contradictions, decay
# (--no-duplicates / --no-contradictions / --no-decay / --cleanup-stale)
engram conflicts # List unresolved contradictions
engram export-context # Export curated context block
# (-o file -f markdown|claude|txt|json -c categories --min-confidence ...)
engram import # Import from local sources
# (-s cursorrules|claude|package|git|ssh|shell|obsidian|env --dry-run)Run engram --help for the full flag list.
The REST API runs on http://localhost:3838 by default.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Liveness check |
| GET | /api/status |
System status + stats |
| GET | /api/installation-info |
Detected agents, runtime, install location |
| POST | /api/memories |
Create a memory |
| GET | /api/memories |
List with pagination + filters |
| POST | /api/memories/search |
Semantic search |
| GET | /api/memories/:id |
Read a single memory |
| DELETE | /api/memories/:id |
Delete by ID |
| POST | /api/memories/bulk-delete |
Bulk-delete by ID list |
| POST | /api/consolidate |
Run consolidation pipeline |
| GET | /api/conflicts |
Legacy tag-based conflict view |
| GET | /api/contradictions |
Unresolved contradictions |
| POST | /api/contradictions/:id/resolve |
Resolve (keep_first / keep_second / keep_both / dismiss) |
| GET | /api/contradictions/count |
Unresolved count (for badge) |
| GET | /api/analytics/overview |
Memory health dashboard data |
| GET | /api/analytics/stale |
Memories with no recent recall |
| GET | /api/analytics/never-recalled |
Memories never returned by any query |
| GET | /api/analytics/duplicates |
Detected near-duplicates |
| GET | /api/analytics/trends |
Time-series creation/recall trends |
| POST | /api/export/static |
Export context block as a static file |
| GET | /api/import/sources |
List importable local sources |
| POST | /api/import/scan |
Two-phase import: preview extracted memories |
| POST | /api/import/commit |
Two-phase import: commit selected memories |
A built-in React dashboard at http://localhost:3838:
- Dashboard β Memory stats, recent activity, health gauge.
- Memories β Browse, filter, inline-edit, bulk-delete.
- Search β Semantic search with score breakdown.
- Statistics β Charts by category, namespace, and time.
- Health β Stale, never-recalled, low-feedback memories with one-click cleanup.
- Conflicts β Side-by-side contradiction resolution.
- Agents β Integration wizard that auto-detects installed AI clients and writes their MCP configs (with timestamped backups).
- Import β Wizard for cursorrules, .claude files, package.json, git config, SSH config, shell history, Obsidian, and .env.
- Store:
engram_rememberruns content through secret detection, then embeds it locally using all-MiniLM-L6-v2 (~23 MB, CPU-only, downloaded once and cached at~/.engram/models/). The embedding and metadata land in SQLite at~/.engram/memory.db. - Recall:
engram_recallembeds the query, fetches candidates via FTS5 + in-namespace embeddings, and scores them as(similarity Γ 0.45) + (recency Γ 0.15) + (confidence Γ 0.15) + (access Γ 0.05) + (feedback Γ 0.10) + fts_boost. Top results are returned and their access stats updated. - Deduplicate: on insert, identical memories (β₯0.95 similarity) are rejected; near-duplicates (0.92β0.95) absorb new content into the existing row.
- Learn:
engram_feedbackadjusts a memory'sfeedback_scoreand β after 5+ votes β bumps the confidence score up or down. - Protect: every write passes through pattern-based secret detection (OpenAI/Stripe/AWS/GitHub/Slack/Google keys, private keys, connection strings, JWTs, high-entropy strings). Detected secrets either reject the memory or redact the secret portion.
Engram stores everything under ~/.engram/:
~/.engram/
βββ memory.db # SQLite database (memories + embeddings + FTS5 index)
βββ config.json # Server configuration
βββ models/ # Cached embedding model
Defaults work out of the box. To customize:
{
"port": 3838,
"dataDir": "~/.engram",
"defaults": {
"namespace": "default",
"recallLimit": 5,
"confidenceThreshold": 0.3,
"tokenBudget": 500,
"maxRecallResults": 20
},
"embedding": {
"provider": "local",
"model": "Xenova/all-MiniLM-L6-v2"
},
"consolidation": {
"enabled": true,
"intervalHours": 24,
"duplicateThreshold": 0.92,
"decayEnabled": true
},
"security": {
"secretDetection": true,
"auditLog": false
}
}An llm.* block is reserved for opt-in Layer 1 LLM enhancement (Ollama, LM Studio, OpenAI-compatible endpoints) β unused by the default zero-config path.
Redirect Engram's data directory to a throwaway location so it doesn't touch ~/.engram/memory.db. Useful for first-time evaluators, CI runs, or testing the desktop sidecar against a fresh DB:
# Via CLI flag (highest priority)
engram start --data-dir /tmp/engram-eval
# Or via env var
ENGRAM_DATA_DIR=/tmp/engram-eval engram start
# Works on every Engram command that touches the DB:
ENGRAM_DATA_DIR=/tmp/engram-eval engram remember "test memory" -c fact
ENGRAM_DATA_DIR=/tmp/engram-eval engram recall "test"
ENGRAM_DATA_DIR=/tmp/engram-eval engram statusOverride priority: --data-dir flag > ENGRAM_DATA_DIR env var > dataDir in ~/.engram/config.json > default (~/.engram).
engram remember "Uses Next.js 14 app router" -n my-saas
engram remember "WordPress multisite + Redis" -n client-site
engram recall "what framework?" -n my-saasTime-range filtering is available via MCP and REST. Agents pass a time_filter object to engram_recall:
{
"query": "deployment changes",
"time_filter": { "after": "last week" }
}{
"query": "API decisions",
"time_filter": { "after": "2026-01-01", "before": "2026-06-01" }
}Supported shapes: after / before (ISO date or relative string like "3 days ago"), or period shorthand (today, yesterday, this_week, last_week, this_month, last_month, this_year, last_year).
engram export-context -f markdown -n my-project -o PROJECT_CONTEXT.md
engram export-context -f claude -o CLAUDE.mdEngram also works as a library inside your Node.js app:
import {
loadConfig,
getDatabasePath,
getModelsPath,
initDatabase,
createMemory,
recallMemories
} from '@hbarefoot/engram';
const config = loadConfig();
const db = initDatabase(getDatabasePath(config));
createMemory(db, {
content: 'User prefers Fastify over Express',
category: 'preference',
confidence: 0.9
});
const results = await recallMemories(
db,
'preferred web framework',
{ limit: 5 },
getModelsPath(config)
);See CONTRIBUTING.md for development setup, the versioning policy (npm + desktop bump together), and the release checklist. The project's licensing and sustainability stance is in BUSINESS_MODEL.md β short version: pure OSS, MIT forever, no paywalls.
git clone https://github.com/HBarefoot/engram.git
cd engram
npm install
npm run devIf Engram is useful to you, here's how to help:
- β Star the repo β the loudest signal that this is worth continuing.
- π Open an issue β bug, feature request, or "we use Engram at <company> for <thing>" stories all welcome.
- π¬ Start a discussion β design questions, integration ideas, "how would Iβ¦" β all good.
- β€οΈ Sponsor on GitHub β low-pressure way to support continued development. No tier-locked features; sponsorship goes straight to keeping the project shipping.
MIT Β© 2026 HBarefoot

