Skip to content
MCP ThesaurusMCP Thesaurus

Memory MCP Server

CommunityGood69/100Claim

npm @j0hanz/memory-mcpstdioupdated 6mo ago

A SQLite-backed MCP server for persistent memory storage, full-text retrieval, and relationship graph traversal.

SourceWebsite

What can you do with Memory MCP Server?

Memory MCP

npm version License: MIT Node.js TypeScript

Install in VS Code Install in VS Code Insiders

Install in Cursor

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) and memory://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

Install in VS Code

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"]}'

Install in VS Code Insiders

CLI:

code-insiders --add-mcp '{"name":"memory-mcp","command":"npx","args":["-y","@j0hanz/memory-mcp@latest"]}'

Install in Cursor

~/.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 update README.md and affected mcp/ mirror pages in the same PR.
  • Link/version policy: use pinned https://modelcontextprotocol.io/specification/2025-11-25/... links for protocol references; avoid latest and 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, and src/prompts/index.ts.
    • Confirm limitations/gotchas in src/instructions.md match runtime behavior.
  • Validation commands: npm run type-check, npm run test:fast, npm run build.

MCP Surface

Tools Summary

Tool Category Notes
store_memory Write Idempotent by content+sorted tags hash
store_memories Write Batch (1โ€“50), transaction-wrapped
get_memory Read Hash lookup
update_memory Write Returns old_hash + new_hash
delete_memory Write Cascades relationship deletion
delete_memories Write Batch (1โ€“50), transaction-wrapped
search_memories Read FTS5 + importance/type filters + cursor
create_relationship Write Idempotent directed edge creation
delete_relationship Write Deletes exact directed edge
get_relationships Read Direction filter + linked memory fields
recall Read FTS5 seed + BFS traversal (depth 0โ€“3)
retrieve_context Read Token-budget-aware context retrieval
memory_stats Read Store aggregates and type breakdown

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.

Name Type Required Default Description
content string Yes โ€” Memory content (1โ€“100000 chars)
tags string[] Yes โ€” 1โ€“100 tags, each max 50 chars, no whitespace
memory_type enum No general general, fact, plan, decision, reflection, lesson, error, gradient
importance integer No 0 Priority 0โ€“10

Returns: { hash, created }


store_memories

Store multiple memories in one transaction (max 50 items).

Name Type Required Description
items Array<StoreMemoryItem> Yes 1โ€“50 items, each with content, tags, optional memory_type, optional importance

Returns: { items, succeeded, failed }


get_memory

Retrieve one memory by its SHA-256 hash.

Name Type Required Description
hash string Yes 64-char lowercase SHA-256 hex

Returns: Memory or { ok: false, error } on E_NOT_FOUND.


update_memory

Update content and optionally tags for an existing memory. Returns both hashes.

Name Type Required Default Description
hash string Yes โ€” Existing memory hash
content string Yes โ€” Replacement content
tags string[] No Existing tags Replacement tags

Returns: { old_hash, new_hash }


delete_memory

Delete one memory by hash. Cascades to related relationship rows.

Name Type Required Description
hash string Yes Memory hash

Returns: { hash, deleted }


delete_memories

Delete multiple memories by hash in one transaction.

Name Type Required Description
hashes string[] Yes 1โ€“50 memory hashes

Returns: { items, succeeded, failed }


search_memories

Full-text search over memory content and tags using FTS5. Supports importance and type filters with cursor pagination.

Name Type Required Default Description
query string Yes โ€” Search text (1โ€“1000 chars)
limit integer No 20 Results per page (1โ€“100)
cursor string No โ€” Pagination cursor from previous response
min_importance integer No โ€” Only return memories with importance >= this value (0โ€“10)
max_importance integer No โ€” Only return memories with importance <= this value (0โ€“10)
memory_type enum No โ€” Filter by memory type

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.

Name Type Required Description
from_hash string Yes Source memory hash
to_hash string Yes Target memory hash
relation_type string Yes Edge label (1โ€“50 chars, no whitespace, free-form)

Returns: { created }


delete_relationship

Delete one directed relationship edge.

Name Type Required Description
from_hash string Yes Source hash
to_hash string Yes Target hash
relation_type string Yes Relationship type

Returns: { deleted } or { ok: false, error } on E_NOT_FOUND.


get_relationships

Retrieve relationships for a memory, with optional direction filter.

Name Type Required Default Description
hash string Yes โ€” Memory hash
direction enum No both outgoing, incoming, or both

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.

Name Type Required Default Description
query string Yes โ€” Seed search query (1โ€“1000 chars)
depth integer No 1 BFS hops (0โ€“3)
limit integer No 10 Seed memory count (1โ€“50)
cursor string No โ€” Pagination cursor from previous response
min_importance integer No โ€” Seed filter: only memories with importance >= value (0โ€“10)
max_importance integer No โ€” Seed filter: only memories with importance <= value (0โ€“10)
memory_type enum No โ€” Seed filter: only memories of this type

Returns: { memories, graph, depth_reached, aborted?, nextCursor? }

Each item in graph uses the shape:

{ "from_hash": "...", "to_hash": "...", "relation_type": "..." }

[!NOTE] aborted: true indicates the traversal hit a safety limit (RECALL_MAX_FRONTIER_SIZE, RECALL_MAX_EDGE_ROWS, or RECALL_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.

Name Type Required Default Description
query string Yes โ€” Search query (1โ€“1000 chars)
token_budget integer No 4000 Maximum estimated tokens to return (100โ€“200000)
strategy enum No relevance Sort order: relevance (FTS rank), importance (highest first), recency (newest first)

Returns: { memories, estimated_tokens, truncated }

[!TIP] Token estimation is approximate (content length รท 4). truncated: true means 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

URI MIME Description
internal://instructions text/markdown Markdown usage guide for all tools and workflows
memory://memories/{hash} application/json Returns one memory as JSON; hash completion supported

Prompts

Name Arguments Purpose
get-help none Returns full usage instructions for all tools

Configuration

Environment Variables

Variable Description Default Required
MEMORY_DB_PATH SQLite database file path memory_db/memory.db No
RECALL_MAX_FRONTIER_SIZE Max BFS frontier nodes per hop (100โ€“50000) 1000 No
RECALL_MAX_EDGE_ROWS Max relationship rows fetched per traversal (100โ€“50000) 5000 No
RECALL_MAX_VISITED_NODES Max visited nodes across entire traversal (100โ€“50000) 5000 No

[!IMPORTANT] If MEMORY_DB_PATH is relative (including the default memory_db/memory.db), it resolves from the process working directory.

[!TIP] Add memory_db/ to your .gitignore to keep the database out of version control โ€” it contains local session data and should not be shared or committed.

Limits and Constraints

Item Value
Content length 1โ€“100000 chars
Tag count 1โ€“100 per memory
Tag length 1โ€“50 chars, no whitespace
Hash format 64-char lowercase hex SHA-256
Search query length 1โ€“1000 chars
search_memories.limit 1โ€“100 (default 20)
recall.depth 0โ€“3 (default 1)
recall.limit 1โ€“50 (default 10)
retrieve_context.token_budget 100โ€“200000 (default 4000)
Batch size 1โ€“50 items (store_memories, delete_memories)
Recall frontier guard RECALL_MAX_FRONTIER_SIZE (default 1000 per hop)
SQLite busy timeout 5000 ms

[!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 MATCH execution (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:

Script Command Purpose
build npm run build Clean, compile, validate instructions, copy assets, chmod executable
dev npm run dev TypeScript watch mode
dev:run npm run dev:run Run built server with .env and file watch
start npm run start Start built server
test npm run test Full build + tests via task runner
test:fast npm run test:fast Run TS tests directly with Node test runner
lint npm run lint ESLint checks
lint:fix npm run lint:fix ESLint auto-fix
type-check npm run type-check Strict TypeScript checks
format npm run format Prettier format
inspector npm run inspector Build and open MCP Inspector against stdio server

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_TOKEN secret required. MCP Registry uses GitHub OIDC. Docker uses the built-in GITHUB_TOKEN.

Troubleshooting

Symptom Cause Fix
Startup fails with FTS5 error Node.js build without FTS5 Use Node.js 24+ with SQLite FTS5 support
E_NOT_FOUND on get_memory Hash doesn't exist Verify via search_memories first
E_INVALID_CURSOR Stale or malformed cursor Retry the request without the cursor parameter
MCP client can't connect Custom stdout logging added Ensure nothing writes to stdout in the server process
aborted: true in recall Traversal hit a safety limit Reduce depth, or tune RECALL_MAX_* env vars
Database locked errors High concurrent write load SQLite busy timeout is 5000 ms; reduce concurrent writes

License

MIT