Memory MCP
A SQLite-backed MCP server for persistent memory storage, full-text retrieval, and relationship graph traversal.
Overview
Memory MCP provides a local, persistent memory layer for MCP-enabled assistants. It stores SHA-256-addressed memory items in SQLite with FTS5-powered full-text search, a directed relationship graph, BFS recall traversal, and token-budget-aware context retrieval — all accessible over stdio transport with no external dependencies.
Key Features
- 13 MCP tools for CRUD, batch operations, FTS5 search, BFS graph recall, token-budget context retrieval, relationships, and stats.
- Full-text search over content and tags via SQLite FTS5 with importance and type filters.
- Graph recall with BFS traversal, bounded frontier, and MCP progress notifications per hop.
- Token-budget retrieval (
retrieve_context) selects memories that fit a caller-specified token budget — no manual pagination needed. - Strict Zod input validation with typed output envelopes and SHA-256 hash addressing.
- Resource support with
internal://instructions(Markdown guide) andmemory://memories/{hash}URI template with hash auto-completion. - stdio transport with clean shutdown handling (
SIGINT,SIGTERM) and no HTTP endpoints. |
Requirements
- Node.js
>=24. - SQLite with FTS5 support (verified at startup).
- Any MCP client that supports stdio command servers.
Quick Start
Use the npm package directly with npx — no installation required:
{
"mcpServers": {
"memory-mcp": {
"command": "npx",
"args": ["-y", "@j0hanz/memory-mcp@latest"]
}
}
}
[!TIP] The server uses stdio transport only; no HTTP endpoint is exposed. Stdout must not be polluted by custom logging.
Or run with Docker:
docker run --rm -i ghcr.io/j0hanz/memory-mcp:latest
Client Configuration
Workspace file .vscode/mcp.json:
{
"servers": {
"memory-mcp": {
"command": "npx",
"args": ["-y", "@j0hanz/memory-mcp@latest"]
}
}
}
CLI:
code --add-mcp '{"name":"memory-mcp","command":"npx","args":["-y","@j0hanz/memory-mcp@latest"]}'
CLI:
code-insiders --add-mcp '{"name":"memory-mcp","command":"npx","args":["-y","@j0hanz/memory-mcp@latest"]}'
~/.cursor/mcp.json:
{
"mcpServers": {
"memory-mcp": {
"command": "npx",
"args": ["-y", "@j0hanz/memory-mcp@latest"]
}
}
}
claude_desktop_config.json:
{
"mcpServers": {
"memory-mcp": {
"command": "npx",
"args": ["-y", "@j0hanz/memory-mcp@latest"]
}
}
}
CLI:
claude mcp add memory-mcp -- npx -y @j0hanz/memory-mcp@latest
MCP config:
{
"mcpServers": {
"memory-mcp": {
"command": "npx",
"args": ["-y", "@j0hanz/memory-mcp@latest"]
}
}
}
# Pull and run (stdio mode)
docker run --rm -i \
-e MEMORY_DB_PATH=/data/memory.db \
-v memory-data:/data \
ghcr.io/j0hanz/memory-mcp:latest
MCP client config:
{
"mcpServers": {
"memory-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"MEMORY_DB_PATH=/data/memory.db",
"-v",
"memory-data:/data",
"ghcr.io/j0hanz/memory-mcp:latest"
]
}
}
}
Documentation Maintenance
- Owner: maintainers updating MCP behavior in
src/must updateREADME.mdand affectedmcp/mirror pages in the same PR. - Link/version policy: use pinned
https://modelcontextprotocol.io/specification/2025-11-25/...links for protocol references; avoidlatestand mixed legacy targets. - Drift-check checklist:
- Re-verify capability declarations in
src/server.ts. - Reconcile tool/resource/prompt docs with
src/tools/index.ts,src/resources/index.ts, andsrc/prompts/index.ts. - Confirm limitations/gotchas in
src/instructions.mdmatch runtime behavior.
- Re-verify capability declarations in
- Validation commands:
npm run type-check,npm run test:fast,npm run build.
MCP Surface
Tools Summary
store_memory
Store a new memory with content, tags, and optional type/importance. Idempotent — storing the same content+tags returns the existing hash with created: false.
Returns: { hash, created }
store_memories
Store multiple memories in one transaction (max 50 items).
Returns: { items, succeeded, failed }
get_memory
Retrieve one memory by its SHA-256 hash.
Returns: Memory or { ok: false, error } on E_NOT_FOUND.
update_memory
Update content and optionally tags for an existing memory. Returns both hashes.
Returns: { old_hash, new_hash }
delete_memory
Delete one memory by hash. Cascades to related relationship rows.
Returns: { hash, deleted }
delete_memories
Delete multiple memories by hash in one transaction.
Returns: { items, succeeded, failed }
search_memories
Full-text search over memory content and tags using FTS5. Supports importance and type filters with cursor pagination.
Returns: { memories, total_returned, nextCursor? }
create_relationship
Create a directed relationship edge between two memories. Idempotent.
Suggested relation_type values: related_to, causes, depends_on, parent_of, child_of, supersedes, contradicts, supports, references.
Returns: { created }
delete_relationship
Delete one directed relationship edge.
Returns: { deleted } or { ok: false, error } on E_NOT_FOUND.
get_relationships
Retrieve relationships for a memory, with optional direction filter.
Returns: { relationships, count }
Each relationship includes from_hash, to_hash, relation_type, created_at, linked_hash, linked_content, and linked_tags.
recall
Search memories by full-text query, then traverse the relationship graph up to depth hops via BFS. Emits MCP progress notifications per hop.
Returns: { memories, graph, depth_reached, aborted?, nextCursor? }
Each item in graph uses the shape:
{ "from_hash": "...", "to_hash": "...", "relation_type": "..." }
[!NOTE]
aborted: trueindicates the traversal hit a safety limit (RECALL_MAX_FRONTIER_SIZE,RECALL_MAX_EDGE_ROWS, orRECALL_MAX_VISITED_NODES). Partial results are still returned.
retrieve_context
Search memories and return relevance-ranked results that fit within a caller-specified token budget. Eliminates manual pagination and token counting for context window management.
Returns: { memories, estimated_tokens, truncated }
[!TIP] Token estimation is approximate (content length ÷ 4).
truncated: truemeans the budget was reached before all candidates were included.
memory_stats
Return aggregate memory and relationship stats. Takes no input.
Returns:
{
"memories": {
"total": 0,
"oldest": null,
"newest": null,
"avg_importance": null
},
"relationships": { "total": 0 },
"by_type": {}
}
Resources
Prompts
Configuration
Environment Variables
[!IMPORTANT] If
MEMORY_DB_PATHis relative (including the defaultmemory_db/memory.db), it resolves from the process working directory.
[!TIP] Add
memory_db/to your.gitignoreto keep the database out of version control — it contains local session data and should not be shared or committed.
Limits and Constraints
[!NOTE] Cursor values are opaque base64url-encoded tokens. Treat them as opaque and do not parse them.
Security
- Transport is stdio-only (
StdioServerTransport) — no HTTP endpoints. - Fatal process errors are written to
stderr; stdout must remain clean for the MCP protocol. - All inputs are validated with strict Zod schemas and bounded field constraints before any database access.
- Hashes are validated against a lowercase 64-char SHA-256 hex regex.
- Search input is tokenized to alphanumeric terms before FTS
MATCHexecution (non-alphanumeric characters act as delimiters, preventing FTS injection). - SQLite foreign keys are enabled; relationship rows cascade-delete when a memory is removed.
Development
Install dependencies:
npm install
Core scripts:
Inspect with MCP Inspector:
npx @modelcontextprotocol/inspector node dist/index.js
Build & Release
GitHub Actions release workflow (.github/workflows/release.yml) handles versioning, validation, and publishing via a single workflow_dispatch trigger:
workflow_dispatch (patch / minor / major / custom)
│
▼
release — bump package.json + server.json → lint → type-check → test → build → tag → GitHub Release
│
├──► publish-npm ──► publish-mcp (npm Trusted Publishing OIDC → MCP Registry)
│
└──► publish-docker (GHCR, linux/amd64 + linux/arm64)
Trigger a release:
gh workflow run release.yml -f bump=patch
Or use the GitHub UI: Actions → Release → Run workflow.
[!NOTE] npm publishing uses OIDC Trusted Publishing — no
NPM_TOKENsecret required. MCP Registry uses GitHub OIDC. Docker uses the built-inGITHUB_TOKEN.
Troubleshooting
License
MIT