MCP Memory-mesh

An MCP server that gives Claude Code persistent memory across sessions (open source, SQLite)

MemoryMesh

PyPI License Python CI Tests v0.8.0

SQLite for AI memory. Persistent memory layer for MCP agents and coding copilots β€” local-first, zero cloud, works in 5 minutes.

See it in action: Claude Code remembering project decisions across sessions.

πŸ’» Coding copilotsπŸ€– MCP agentsπŸ“š Research assistants
Remember architecture decisions, bugs, and preferences across sessionsPersistent memory across any MCP-compatible clientSemantic recall over your notes, papers, and docs

Up and running in 5 minutes

pip install memorymesh-mcp
cp config.example.yaml ~/.memorymesh/config.yaml
# edit config.yaml β€” point at your folders
memorymesh index ~/Documents
memorymesh search "how did I configure the debounce"

Wire it into Claude Desktop. Find the config file at:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "memorymesh": {
      "command": "uv",
      "args": [
        "run",
        "--directory", "/absolute/path/to/memory-mesh",
        "memorymesh", "start"
      ]
    }
  }
}

Restart Claude Desktop. The 15 tools appear automatically.


Why it exists

Every AI conversation starts from zero. Claude doesn't know which architecture decision you made last week. Cursor doesn't remember the bug you fixed yesterday. The context dies when the session ends.

Mem0 requires a cloud account. Zep needs a running server and a database. LangMem ties you to the LangChain ecosystem. None of them speak MCP natively.

MemoryMesh runs entirely on your machine. It indexes your files into a local SQLite + ChromaDB store and exposes them through 15 MCP tools. It never touches the network unless you configure a connector. Any MCP client β€” Claude Desktop, Cursor, your own agent β€” gets persistent memory with one config change.


How it works

The indexer watches your files, chunks them with format-aware parsers, and stores embeddings locally. The search engine fuses dense and sparse results, then a cross-encoder reranker scores the candidates.

                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  MCP clients ───▢ β”‚         MemoryMesh           β”‚
(Claude Desktop,   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
 Cursor, agents)   β”‚  β”‚ MCP Tools (FastMCP):   β”‚  β”‚
                   β”‚  β”‚  search_memory         β”‚  β”‚
                   β”‚  β”‚  list_sources          β”‚  β”‚
                   β”‚  β”‚  get_document          β”‚  β”‚
                   β”‚  β”‚  index_now             β”‚  β”‚
                   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                   β”‚             β–Ό                 β”‚
                   β”‚     Search Engine             β”‚
                   β”‚   dense + BM25 β†’ RRF          β”‚
                   β”‚             β”‚                 β”‚
                   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
                   β”‚   β–Ό                    β–Ό      β”‚
                   β”‚ ChromaDB            BM25      β”‚
                   β”‚ (embeddings)     (sparse)     β”‚
                   β”‚   β–²                    β–²      β”‚
                   β”‚   └──────── Indexer β”€β”€β”€β”˜      β”‚
                   β”‚                β–²              β”‚
                   β”‚           Watchdog            β”‚
                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                             Your filesystem

Indexing: file watcher detects changes β†’ SHA-256 dedup skips unchanged files β†’ parser (txt/md/pdf/docx/code/obsidian/email/calendar/browser) β†’ chunker (tree-sitter for code, by-heading for markdown, recursive for text) β†’ sentence-transformers embeddings β†’ ChromaDB + BM25.

Search: query β†’ query expansion (lexical variants + HyDE) β†’ parallel dense + sparse search β†’ Reciprocal Rank Fusion (k=60) β†’ bge-reranker-v2-m3 reranker β†’ top-k results with path, preview, score, and metadata.

RAG (optional): ask_memory β†’ search_memory retrieval β†’ Ollama generate() β†’ grounded answer with cited sources.


What's included

MemoryMesh ships with hybrid search (dense embeddings + BM25 + RRF + cross-encoder reranker), hot/warm/cold memory tiers with configurable forgetting decay, and an episodic event timeline. 47 connectors pull data from Jira, Notion, GitHub, Slack, email, browser history, Spotify, and more. 15 MCP tools expose everything to any MCP-compatible client. A real-time file watcher re-indexes changed files within seconds, without a manual trigger.

Full feature list
FeatureStatus
Local file indexing (txt, md, code, pdf, docx)βœ…
Obsidian vault parser (frontmatter + wikilinks)βœ…
Notion HTML export parserβœ…
AI conversation exports (Claude, ChatGPT JSON)βœ…
Email indexing (.mbox via stdlib)βœ…
Calendar indexing (.ics / iCalendar)βœ…
Browser history (Chrome / Firefox / Brave SQLite)βœ…
Hybrid search β€” dense + BM25 + RRFβœ…
Cross-encoder reranker (bge-reranker-v2-m3)βœ…
Query expansion β€” lexical variants + HyDEβœ…
RAG with local LLM via Ollama (ask_memory tool)βœ…
Multi-vector summary indexing for abstract recallβœ…
MCP server β€” 15 tools, stdio + streamable-httpβœ…
Real-time incremental indexing (watchdog + debounce)βœ…
Tree-sitter code chunking (Python, JS, TS, Go, Rust…)βœ…
Parent Document Retriever (extended_preview)βœ…
Cross-platform β€” Windows / Linux / macOSβœ…
Post-crash reconciliationβœ…
Optional OCR for scanned PDFs (Tesseract / EasyOCR)βœ…
Privacy audit log (query hashes only, no cleartext)βœ…
GitHub Actions CI (Ubuntu / Windows / macOS)βœ…
Docker + docker-composeβœ…
Per-agent permission layer (ACL + rate limiting + revocation)βœ…
Hierarchical memory (hot / warm / cold tiers + forgetting policy)βœ…
Episodic memory timeline (query_timeline, record_event tools)βœ…
Memory control tools (pin_memory, forget_memory)βœ…
Embedding LRU cache (CachedEmbeddingProvider)βœ…
Health endpoint (GET /health on :8766)βœ…
Real CLIP image embeddings (memorymesh[multimodal])βœ…
Real Whisper audio transcription (memorymesh[multimodal])βœ…
Knowledge Graph β€” entity co-occurrence (/graph, graph_memory tool)βœ…
Encryption at rest (Fernet AES-128, memorymesh keygen)βœ…
REST API (11 endpoints at /api, OpenAPI docs at /api/docs)βœ…
VS Code extension (extensions/vscode/)βœ…
Browser extension β€” Manifest V3 (extensions/browser/)βœ…
47 data source connectors (Jira, Notion, GitHub, Slack, Spotify…)βœ…
Unit + integration test suiteβœ…

MCP Tools

Once running, these tools are available to any MCP-compatible client:

ToolDescription
search_memory(query, top_k, mode, source)Hybrid search over all indexed content. Returns path, preview, score, file type, source, and optional extended_preview for wider context.
list_sources()List all configured sources with file counts and index status.
get_document(path, max_bytes)Read the full content of an indexed file (up to 1 MB by default).
index_now(path)Force immediate re-index of a file or directory, bypassing the watcher.
ask_memory(question, top_k, model)RAG: retrieves relevant passages and sends them to a local Ollama model for a grounded answer. Requires Ollama running locally.
pin_memory(chunk_id)Pin a chunk to the hot tier β€” never demoted, never score-decayed.
forget_memory(chunk_id)Suppress a chunk from future search results without deleting the source file.
query_timeline(since_days, event_type, limit)Query the episodic event log: what was retrieved / indexed in the last N days?
sync_source(source_type, dry_run)Pull and index documents from a configured external connector (Jira, Notion, GitHub…).
get_entity(name, entity_type)Look up a named entity (person, project, concept) and its associated chunk IDs.
related_documents(path, top_k, exclude_self)Find documents semantically similar to the given file path.
search_by_date(since_days, until_days, source, limit)Search indexed chunks by last-modified date range.
forget_source(source, dry_run)Remove all indexed data for a named source from the index.
summarize_source(source, max_chunks)Generate a brief summary of the most recent content in a source (requires Ollama).
graph_memory(min_mentions, entity_type)Return the entity co-occurrence knowledge graph as nodes and edges.

All tools are backwards-compatible β€” new fields are added without changing existing signatures.


How MemoryMesh compares

How MemoryMesh compares to similar projects:

FeatureMemoryMeshLangChainLlamaIndexPrivateGPTAnythingLLMMemGPTHaystack
MCP nativeβœ…βŒβŒβŒβŒβŒβŒ
Hybrid search (dense + BM25 + RRF)βœ…PartialPartialβŒβŒβŒβœ…
Real-time watcher + SHA-256 dedupβœ…βŒβŒβŒβŒβŒβŒ
Post-crash reconciliationβœ…βŒβŒβŒβŒβŒβŒ
100% local, zero telemetryβœ…βœ…βœ…βœ…βœ…βœ…βœ…
Cross-platform (Win/Linux/Mac)βœ…βœ…βœ…PartialPartialβœ…βœ…
No framework dependencyβœ…β€”β€”βŒβŒβŒβ€”
Per-agent permissionsβœ…βŒβŒβŒβŒβŒβŒ

MCP native means it was built for MCP from day one β€” not bolted on after. The 15 tools follow additive versioning β€” new fields are added without removing existing ones.

Per-agent permissions means per-client identity, ACL by source and operation, token-bucket rate limiting, and token revocation are built into the core β€” not added as middleware.


Configuration

Everything lives in config.yaml. See config.example.yaml for a fully commented reference. Key highlights:

sources:
  - name: documents
    path: ~/Documents
    recursive: true
    extensions: [.txt, .md, .pdf, .docx]

  - name: projects
    path: ~/Projects
    recursive: true
    extensions: [.py, .js, .ts, .go, .rs, .md]

  - name: obsidian
    path: ~/obsidian-vault
    source_type: obsidian     # activates wikilink + frontmatter parser

  - name: emails
    path: ~/Mail
    source_type: email        # parses .mbox files

embeddings:
  model: all-MiniLM-L6-v2    # swap to paraphrase-multilingual-MiniLM-L12-v2 for PT/EN

search:
  default_top_k: 10
  hybrid:
    enabled: true
  reranker:
    enabled: true             # cross-encoder reranker (recommended)
    model: BAAI/bge-reranker-v2-m3
  query_expansion:
    enabled: true
    n_lexical_variants: 1

# Optional: local LLM for ask_memory tool + HyDE query expansion
ollama:
  enabled: false              # set true after: ollama pull llama3
  model: llama3

server:
  transport: stdio            # stdio | streamable-http

Global ignore list protects sensitive paths by default: .env, *.key, id_rsa*, secrets/, .ssh/, .aws/, .git/, node_modules/.


Benchmarks

Benchmark results will be published here. Scripts are already in benchmarks/ and runnable locally β€” contributions with reproducible numbers are welcome.

  • bench_indexing.py β€” indexing throughput (chunks/s, MB/s) on a synthetic corpus
  • bench_search_latency.py β€” p50/p95/p99 search latency across hybrid/dense/sparse modes
  • bench_embedding_models.py β€” speed vs. quality comparison across three embedding models

Privacy & security

Three commitments that do not change across versions:

  1. No data leaves your machine. No telemetry. No external API calls unless you explicitly opt in β€” and even then, there is a WARNING in the log.
  2. HTTP listener binds to 127.0.0.1 only by default. Exposing to other interfaces requires an explicit config override.
  3. Logs never contain document content or queries in cleartext. The audit log records query hashes, not queries.

Encryption at rest is available as of v0.8.0. Run memorymesh keygen to generate a key, then enable encryption.enabled: true in config.yaml. The SQLite metadata store can be exported as an encrypted backup with memorymesh backup.


Roadmap

VersionFocusStatus
v0.1Core: hybrid search, 4 MCP tools, stdio transport, indexerβœ… shipped
v0.2CI/CD, Parent Document Retriever, Docker, security hardeningβœ… shipped
v0.3Reranker, query expansion + HyDE, RAG (Ollama), 6 new parsers, eval frameworkβœ… shipped
v0.5Per-agent permissions (ACL/rate-limit/revocation), hot/warm/cold tiers, episodic timeline, memory control tools, embedding cache, health endpoint, CLIP/Whisper stubsβœ… shipped
v0.8Real CLIP+Whisper, Knowledge Graph, Encryption at rest, REST API (11 endpoints), VS Code + browser extensions, 47 connectors, 15 MCP toolsβœ… shipped
v1.0Agent OS integration β€” memory layer for multi-agent systems~6 months
v2.0Hardware agents β€” ESP32/Arduino querying the hub over BLE/WiFi~12 months

Full details in ROADMAP.md.


Troubleshooting

  • UnicodeDecodeError on a text file β€” MemoryMesh tries UTF-8, UTF-8 BOM, cp1252, latin-1 in order. If a file still fails, it is logged and skipped.
  • Watcher doesn't fire on a network drive / WSL mount β€” set watcher.use_polling: true in config.yaml.
  • Tesseract not found β€” install it system-wide and ensure it is in PATH. Windows: UB-Mannheim installer.
  • Embedding model mismatch after changing config β€” run memorymesh reindex --all. The CLI refuses to start if the model ID stored in ChromaDB does not match the config.

Contributing

Contributions are welcome β€” bug reports, new connectors, integration examples, and documentation improvements all help. Open an issue to discuss before submitting a large PR.


Acknowledgements

Architecture informed by studying LlamaIndex, LangChain, PrivateGPT, AnythingLLM, MemGPT, and Haystack β€” understanding what each does well and what it does not. And to chroma-mcp and the MCP Python SDK for showing what MCP-native looks like in practice.


MIT. See LICENSE.

Related Servers

NotebookLM Web Importer

Import web pages and YouTube videos to NotebookLM with one click. Trusted by 200,000+ users.

Install Chrome Extension