Persistent memory for AI agents. An MCP server that gives your AI assistant long-term memory across sessions.
curl -fsSL https://github.com/shetty4l/engram/releases/latest/download/install.sh | bashThis will:
- Download and extract the latest release to
~/srv/engram/<version>/ - Install dependencies and build the
engramCLI binary - Symlink the CLI to
~/.local/bin/engram - Manage a
latestsymlink and prune old versions (keeps last 5) - Print the MCP config to add to your client
Requirements: bun, curl, tar, jq
Add to your MCP client config:
{
"engram": {
"command": "bun",
"args": ["run", "~/srv/engram/latest/src/index.ts"]
}
}Clone the repo and run the setup script. Use this if you want to contribute or modify engram.
git clone https://github.com/shetty4l/engram.git
cd engram
./scripts/setup-local.shDeploy to your AWS account with one command. Requires AWS CLI configured.
git clone https://github.com/shetty4l/engram.git
cd engram
./scripts/deploy-aws.shThis will:
- Launch a t3.small EC2 instance with Amazon Linux 2023
- Install Bun and Engram automatically
- Configure SSM for secure access (no public ports)
- Output the MCP config to add to your client
Requirements:
- AWS CLI installed and configured (
aws configureoraws sso login) - IAM permissions: EC2, IAM, SSM
Cost: ~$15-20/month (t3.small + 10GB EBS). Stop the instance when not in use to save costs.
Cleanup:
./scripts/destroy-aws.shThe script creates ~/.engram/ with your key and instance info.
Add Engram as an MCP server in OpenCode.
buninstalledengramCLI on PATH (installed automatically byinstall.sh, or runbun linkfrom a local clone)
Create or update ~/.config/opencode/opencode.json:
bun run opencode:configThis prints a ready-to-paste config block with your local absolute path:
{
"mcp": {
"engram": {
"type": "local",
"enabled": true,
"command": ["bun", "run", "/path/to/engram/src/index.ts"]
}
}
}Restart OpenCode to load the MCP server.
engram: command not found: If installed from release, ensure~/.local/binis in your PATH. If running from a clone, runbun linkfrom the repo.- Daemon issues:
engram statusengram restartcurl http://127.0.0.1:7749/health
Store a memory for later retrieval.
remember({ content: "User prefers TypeScript over JavaScript", category: "preference" })
Parameters:
content(required): The memory contentcategory(optional):decision,pattern,fact,preference,insightscope_id,chat_id,thread_id,task_id(optional): Scope filters for isolationmetadata(optional): Structured metadata objectidempotency_key(optional): Stable identity key for retries/updates (recommended format:<scope>:<category>:<topic-slug>)upsert(optional): Prefertruewhen the memory has a stable identity; updates the existing memory matchingidempotency_keyinstead of creating a new one. Requiresidempotency_key.
Returns: { id: string, status: "created" | "updated" }
Guidance (concise):
- Prefer upsert for durable memories with deterministic keys (for example:
<scope>:fact:validation-gate,<scope>:decision:storage-engine). - For one-off memories without stable identity, use normal create (
upsertomitted orfalse).
Upsert behavior:
- When
upsert: trueand a memory with the sameidempotency_key(andscope_id) exists: overwritescontent,category,metadata, andembedding. Does not changecreated_at,access_count,strength, or scope fields. - Uses full-replace semantics: omitted optional fields (
category,metadata) are set tonull. - When no match exists: creates a new memory normally.
- When
upsertis omitted orfalse: standard idempotency replay (returns cached result, no mutation).
Retrieve relevant memories.
recall({ query: "coding preferences", limit: 5 })
Parameters:
query(required): What to search forlimit(optional): Max results (default: 10)category(optional): Filter by categorymin_strength(optional): Minimum strength threshold (0.0-1.0)scope_id,chat_id,thread_id,task_id(optional): Scope filters (feature-flagged)
Delete a stored memory by ID.
forget({ id: "memory-uuid" })
Parameters:
id(required): Memory ID to deletescope_id(optional): Scope guard for deletion (required whenENGRAM_ENABLE_SCOPES=1)
Returns:
id: Requested memory IDdeleted:trueif a memory was deleted,falseif it did not exist
Discover server version and feature flags for compatibility-safe client opt-in.
Retrieve contextual memories for assistant turns. Behavior mirrors recall, with query optional.
When users ask to forget by phrase (for example, "forget the memory about API keys"),
the assistant should first call recall to resolve candidates, then call forget
with the selected memory ID.
Memories decay in strength over time when not accessed, helping prioritize relevant knowledge:
- Decay rate: 0.95 per day (~50% strength after 14 days without access)
- Access boost: Accessing a memory resets its strength to 1.0
- Access count boost: Frequently-accessed memories get a log-scale bonus
# View decay status for all memories
engram decay
# Apply decayed strengths to database
engram decay --apply
# Preview what would be pruned (dry run)
engram prune --threshold=0.1 --dry-run
# Delete memories below threshold
engram prune --threshold=0.1Override defaults with environment variables:
ENGRAM_DECAY_RATE=0.95 # Daily decay multiplier (default: 0.95)
ENGRAM_ACCESS_BOOST_STRENGTH=1.0 # Strength after access (default: 1.0)Database location: ~/.local/share/engram/engram.db
Override with environment variable:
ENGRAM_DB_PATH=/custom/path/engram.dbFeature flags (all default to disabled):
ENGRAM_ENABLE_SCOPES=1
ENGRAM_ENABLE_IDEMPOTENCY=1
ENGRAM_ENABLE_CONTEXT_HYDRATION=1
ENGRAM_ENABLE_WORK_ITEMS=1- After any code change, run
bun run validatebefore moving to the next task. - If validation fails, fix issues and re-run validation before opening or updating a PR.
# Core test suite (fast + CI-safe)
bun run test:core
# Full test suite (includes embedding/WASM tests)
bun run test:full
# Type check
bun run typecheck
# Lint
bun run lint
# All validation
bun run validate
# Full validation (includes embedding/WASM tests)
bun run validate:fullvalidate intentionally runs the core suite (test:core) as the required CI gate.
CI also runs test:full on every push and pull request. If full-suite assertions pass
but Bun exits with the known transformers/WASM runtime crash (133), CI records a warning
and continues. Any real test failures still fail CI.
- CI workflow:
.github/workflows/ci.yml- Runs on every push and pull request
- Executes required
bun run validate - Executes
bun run test:fullwith special handling for known Bun exit133
- Release workflow:
.github/workflows/release.yml- Triggers automatically on CI success on
main - Auto-increments the patch version from the latest git tag
- Creates a source tarball and publishes a GitHub Release with
install.sh - Install:
curl -fsSL https://github.com/shetty4l/engram/releases/latest/download/install.sh | bash
- Triggers automatically on CI success on
- Slice 1 ✅: Basic CRUD with strength/recency ordering
- Slice 2 ✅: Full-text search with FTS5
- Slice 3 ✅: HTTP server and daemon
- Slice 4 ✅: Semantic search with local embeddings
- Slice 5 ✅: Memory decay algorithm
- Slice 6: Deduplication and conflict detection
- Slice 7: Export/import for portability
MIT