Engram Mem — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Engram Mem (Agent Skill) and scored it 91/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} is the classic direct prompt-injection phrasing. Placed in a skill body that the agent reads as trusted instructions, it tries to make the agent abandon its prior rules and follow whatever comes next — a full system-prompt override.
ignore/disregard/forget … previous instructions sentence.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<p align="center"> <img src="docs/landing/assets/engram-logo.png" alt="engram" width="300"> </p>
<p align="center"> <strong>Persistent memory for AI agents</strong> </p>
Dual-memory AI system combining episodic (vector) + semantic (graph) memory with LLM reasoning. Entity-gated ingestion ensures only meaningful data is stored. Enterprise-ready with multi-tenancy, auth, caching, observability, and Docker deployment.
Works with any AI agent or IDE — Claude Code, OpenClaw, Cursor, and any MCP-compatible client. Federates with external knowledge systems (mem0, LightRAG, Graphiti) via auto-discovery. Exposes CLI, MCP (stdio), HTTP API (/api/v1/), and WebSocket (/ws) interfaces.
pip install engram-mem[preference]/[fact]/[lesson] for structured LLM context~/.claude/, ~/.cursor/) to find providersfail_open optionflowchart TD
subgraph Agents["Agents & IDEs"]
CC["Claude Code"]
OC["OpenClaw"]
CU["Cursor"]
ANY["Any MCP Client"]
end
subgraph Interfaces
CLI["CLI (Typer)"]
MCP["MCP (stdio)"]
HTTP["HTTP API /api/v1/"]
WS["WebSocket /ws"]
end
CC & OC & CU & ANY --> MCP
CLI & MCP & HTTP & WS --> Auth["Auth Middleware\n(JWT + RBAC, optional)"]
Auth --> Tenant["TenantContext (ContextVar)"]
Tenant --> Recall["Recall Pipeline\n(decision > resolve > search > feedback)"]
Recall --> Episodic["EpisodicStore\n(Qdrant)"]
Recall --> Semantic["SemanticGraph\n(NetworkX + SQLite/PG)"]
Recall --> Fed["Federated Providers"]
Episodic & Semantic --> Reasoning["Reasoning Engine\n(Gemini via litellm)"]
Episodic --> Cache["Redis Cache (optional)"]
WS --> EventBus["Event Bus\n(push events)"]
subgraph Fed["Federated Knowledge"]
M0["mem0"]
LR["LightRAG"]
GR["Graphiti"]
REST["REST / File / PG / MCP"]
end# Install from PyPI
pip install engram-mem
# Or from source
git clone https://github.com/docaohieu2808/Engram-Mem.git
cd engram && pip install -e .
# Initialize config
engram init
# Set API key
export GEMINI_API_KEY="your-key"
# Start daemon (background HTTP server + watcher)
engram start
# Store a memory
engram remember "Deployed v2.1 to production at 14:00 - caused 503 spike"
# Search memories
engram recall "production incidents"
# Browse all data (episodic + semantic)
engram dump
# Reason across all memory
engram think "What deployment issues have we had?"Requirements: Python 3.11+, GEMINI_API_KEY for LLM reasoning and embeddings. Basic storage works without it.
Add to ~/.claude.json:
{
"mcpServers": {
"engram": {
"command": "engram-mcp",
"env": { "GEMINI_API_KEY": "your-key" }
}
}
}Add to Cursor's MCP settings — engram auto-discovers Cursor's config at ~/.cursor/settings.json:
{
"mcpServers": {
"engram": {
"command": "engram-mcp",
"env": { "GEMINI_API_KEY": "your-key" }
}
}
}Install the engram skill, then enable session watcher in ~/.engram/config.yaml:
capture:
openclaw:
enabled: true
sessions_dir: ~/.openclaw/workspace/sessionsEngram auto-discovers and federates with external memory systems. Supported providers:
| Provider | Type | Auto-Discovery |
|---|---|---|
| mem0 | REST | Port 8080, /v1/memories |
| LightRAG | REST | Port 9520, /query |
| Graphiti | REST | Port 8000, /search |
| OpenClaw | File | ~/.openclaw/workspace/memory/*.md |
| Custom REST | REST | Manual config |
| PostgreSQL | SQL | Manual config |
| MCP servers | MCP | Scans ~/.claude/settings.json, ~/.cursor/settings.json |
# Auto-discovery (enabled by default)
discovery:
local: true
hosts: ["10.10.0.2"] # additional hosts to scan
# Or manual provider config
providers:
- name: my-mem0
type: rest
url: http://localhost:8080
search_endpoint: /v1/memories/search
search_method: POST
search_body: '{"query": "{query}", "limit": {limit}}'
result_path: "results[].memory"# Start server
engram serve --port 8765
# Store memory
curl -X POST http://localhost:8765/api/v1/remember \
-H "Content-Type: application/json" \
-d '{"content": "Deployed v1.0", "memory_type": "fact", "priority": 8}'
# Search
curl "http://localhost:8765/api/v1/recall?query=deployment&limit=5"
# Reason
curl -X POST http://localhost:8765/api/v1/think \
-H "Content-Type: application/json" \
-d '{"question": "What deployment issues have we had?"}'
# Meeting ledger
curl -X POST http://localhost:8765/api/v1/meeting-ledger \
-H "Content-Type: application/json" \
-d '{"title": "Sprint Review", "decisions": ["Ship v2"], "action_items": ["Update docs"]}'engram remember <content> [--type fact|decision|...] [--priority 1-10]
[--tags tag1,tag2] [--expires 7d] [--topic-key key]
engram recall <query> [--limit 5] [--type <type>] [--tags tag1,tag2]
engram ask <question> # Smart query (auto-routes)
engram think <question> # LLM reasoning
engram summarize [--count 20] [--save]
engram decay [--limit 20] # Ebbinghaus retention curveengram add node <name> --type <type>
engram add edge <from> <to> --relation <relation>
engram remove node <key>
engram remove edge <key>
engram query [keyword] [--type X] [--related-to Y] [--format table|json]
engram autolink-orphans [--apply] [--min-co-mentions 3]engram status # Memory counts
engram dump [--format table|json] # All memories + graph
engram health # Full system health check
engram tui # Terminal UI (interactive browser)
engram graph [--port 8100] # Open visualization browserengram cleanup # Delete expired memories
engram consolidate [--limit 50] # LLM clustering + summarization
engram ingest <file.json> [--dry-run] # Extract entities + remember
engram backup # Export snapshot
engram restore <file> # Import snapshot
engram migrate <file> # Import legacy JSONengram session-start
engram session-end
engram feedback <id> --positive|--negative
engram resolve <query> # Pronoun + temporal resolution
engram audit [--limit 50] # Retrieval audit logengram init # Zero-config setup
engram start # Start daemon (HTTP server + watcher)
engram stop # Stop daemon
engram logs [--tail 50] # Show logs
engram serve [--host 0.0.0.0] [--port 8765] # Foreground HTTP server
engram watch [--daemon] # Watch inbox + OpenClaw/Claude Code sessionsengram setup # Interactive IDE connector wizard
engram config show|get <key>|set <key> <value>
engram auth # API key management
engram providers discover # Auto-discover external providers
engram providers list|add|remove # Manage providers
engram schema # Manage semantic schemasengram queue-status # Embedding queue health
engram resource-status # LLM tier (FULL/STANDARD/BASIC/READONLY)
engram constitution-status # 3-law governance + SHA-256
engram scheduler-status # Background task schedule
engram benchmark [--quick] # Run recall accuracy benchmarkengram autostart # Install systemd user services
engram sync [--direction] # Git-friendly memory sharing| Tool | Description |
|---|---|
engram_remember | Store episodic memory with type, priority, tags, expires, topic-key |
engram_recall | Search episodic memories (compact or full) with filtering |
engram_get_memory | Retrieve full memory content by ID or 8-char prefix |
engram_timeline | Get chronological context around a memory (±window minutes) |
engram_cleanup | Delete all expired memories |
engram_cleanup_dedup | Deduplicate similar memories by cosine similarity threshold |
engram_ingest | Dual ingest: extract entities + store memories from chat |
engram_feedback | Record positive/negative feedback (adjusts confidence) |
engram_auto_feedback | Auto-detect feedback sentiment from text |
engram_think | Reason across episodic + semantic memory via LLM |
engram_ask | Smart query — auto-routes to recall or think based on intent |
engram_summarize | Summarize recent N memories into insights via LLM |
engram_add_entity | Add/update entity node to knowledge graph |
engram_add_relation | Add/update relationship edge between entities |
engram_query_graph | Query knowledge graph (keyword, type, related-to) |
engram_meeting_ledger | Record structured meeting (decisions, action items, attendees) |
engram_status | Show memory statistics (episodic count, semantic nodes/edges) |
engram_session_start | Begin new conversation session |
engram_session_end | End active session |
engram_session_summary | Get summary of completed session |
engram_session_context | Retrieve memories from active session |
Config file: ~/.engram/config.yaml — Priority: CLI flags > env vars > YAML > defaults
episodic:
mode: embedded # embedded (Qdrant in-process) or server
path: ~/.engram/qdrant
namespace: default
embedding:
provider: gemini
model: gemini-embedding-001
key_strategy: failover # failover or round-robin
semantic:
provider: sqlite # or postgresql
path: ~/.engram/semantic.db
llm:
provider: gemini
model: gemini/gemini-2.0-flash
api_key: ${GEMINI_API_KEY}
serve:
host: 127.0.0.1
port: 8765
capture:
openclaw:
enabled: false
sessions_dir: ~/.openclaw/workspace/sessions
claude_code:
enabled: false
sessions_dir: ~/.claude/projects
auth:
enabled: false
cache:
enabled: false
redis_url: redis://localhost:6379/0
rate_limit:
enabled: false
audit:
enabled: false
path: ~/.engram/audit.jsonlStart server: engram serve [--host 0.0.0.0] [--port 8765]
Health & Info:
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /health | Liveness check |
| GET | /health/ready | Readiness probe |
| GET | /graph | Interactive graph UI |
Core Operations (/api/v1/):
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /remember | Store episodic memory |
| GET | /recall | Search memories (?query=X&limit=5) |
| POST | /think | LLM reasoning across episodic + semantic |
| GET | /query | Graph search (?keyword=X&node_type=Y&related_to=Z) |
| POST | /ingest | Extract entities + store memories |
| POST | /meeting-ledger | Record structured meeting |
| POST | /feedback | Record memory feedback |
Memory Management (/api/v1/):
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /memories | List/filter with pagination |
| GET | /memories/{id} | Get single memory |
| PUT | /memories/{id} | Update memory |
| DELETE | /memories/{id} | Delete memory |
| GET | /memories/export | Export all as JSON |
| POST | /memories/bulk-delete | Batch delete |
Semantic Graph (/api/v1/):
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /graph/data | Graph data (nodes + edges) for vis.js |
| POST | /graph/nodes | Add/update node |
| PUT | /graph/nodes/{key} | Update node |
| DELETE | /graph/nodes/{key} | Delete node |
| POST | /graph/edges | Add/update edge |
| DELETE | /graph/edges | Delete edge |
| GET | /feedback/history | Feedback history |
Admin (/api/v1/):
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /cleanup | Delete expired memories |
| POST | /cleanup/dedup | Deduplicate memories |
| POST | /auth/token | Get JWT token |
| GET | /providers | List active providers |
| GET | /audit/log | Retrieval audit log |
| GET | /scheduler/tasks | Scheduler status |
| POST | /scheduler/tasks/{name}/run | Run task now |
| POST | /benchmark/run | Run benchmark |
| GET | /config | Get config |
| PUT | /config | Update config |
| GET | /status | Memory statistics |
Connect via ws://host:8765/ws?token=JWT (token optional when auth disabled).
Commands:
| Command | Payload |
|---|---|
remember | {"content": "...", "priority": 7} |
recall | {"query": "...", "limit": 5} |
think | {"question": "..."} |
feedback | {"memory_id": "abc123", "feedback": "positive"} |
query | {"keyword": "PostgreSQL"} |
ingest | {"messages": [...]} |
status | {} |
Push Events: memory_created, memory_updated, memory_deleted, feedback_recorded
| Variable | Purpose |
|---|---|
GEMINI_API_KEY | LLM + embeddings (primary key) |
GEMINI_API_KEY_FALLBACK | Secondary key for key rotation |
ENGRAM_NAMESPACE | Memory namespace isolation |
ENGRAM_AUTH_ENABLED | Enable JWT auth |
ENGRAM_SEMANTIC_PROVIDER | sqlite or postgresql |
ENGRAM_CACHE_ENABLED | Enable Redis caching |
ENGRAM_AUDIT_ENABLED | Enable audit logs |
ENGRAM_TELEMETRY_ENABLED | Enable OpenTelemetry |
# Quick start
docker build -t engram:latest .
docker run -e GEMINI_API_KEY="your-key" -p 8765:8765 engram:latest
# Production with PostgreSQL + Redis
ENGRAM_AUTH_ENABLED=true \
ENGRAM_SEMANTIC_PROVIDER=postgresql \
ENGRAM_SEMANTIC_DSN=postgresql://user:pass@postgres:5432/engram \
ENGRAM_CACHE_ENABLED=true \
ENGRAM_CACHE_REDIS_URL=redis://redis:6379/0 \
docker compose uppytest tests/ -v # All tests
pytest tests/ --cov=src/engram # With coverage
pytest tests/ -k "recall or feedback" # Specific suites894+ tests, 61%+ code coverage, CI/CD via GitHub Actions.
MIT — Copyright (c) Do Cao Hieu
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.