Skip to main content

MCP server for persistent AI memory — MongoDB-backed with file fallback

Project description

Memory Map — MCP Server for Claude Code

CI Python PyPI License: MIT

An MCP server that gives Claude persistent memory and conversation history — so it understands your project from the very first message of every session, without you re-explaining anything.

What it does

  • Project structure — local directory tree or any GitHub repo, .gitignore-aware
  • Git history — recent commits in a compact format
  • Session memory — save context once, Claude loads it automatically at session start
  • Conversation history — saves each Q&A pair as its own document; Claude retrieves the most relevant chunks by tag and token budget at session start
  • Compression — memory output is token-optimized at 3 levels (raw / compact / dense)
  • Multi-project — browse memory and history across all your projects from a single tool call
  • Manual save/mem_save slash command to checkpoint the conversation any time

Quick Install

pip install memory-map-mcp

With OpenAI vector search:

pip install "memory-map-mcp[embed-openai]"

With local CPU vector search (no API key):

pip install "memory-map-mcp[embed-local]"

Then jump to Step 2 — Configure environment variables and Step 3 — Register the MCP server.

Developing or contributing? See the Development Setup section below for the git-clone path.


Prerequisites

  • Python 3.11+
  • Git installed and on your PATH
  • Claude Code CLI installed
  • MongoDB — local or Atlas — for persistent conversation history storage

Setup

Step 1 — Install

From PyPI (recommended):

pip install memory-map-mcp

From source (for development):

git clone https://github.com/kid-sid/memory_map.git
cd memory_map
pip install -e ".[dev]"

Development Setup

git clone https://github.com/kid-sid/memory_map.git
cd memory_map
python -m venv venv

# Windows:
venv\Scripts\activate
# Mac/Linux:
source venv/bin/activate

pip install -e ".[dev]"

Step 2 — Configure environment variables

Create a .env file in the repo root:

# MongoDB connection string — required for conversation history
# Local:  mongodb://localhost:27017
# Atlas:  mongodb+srv://<user>:<password>@<cluster>.mongodb.net
MEMORY_MAP_MONGO_URI=

# Embedding provider for vector search (optional — BM25-only if not set)
# MEMORY_MAP_EMBED_PROVIDER=openai   # OpenAI text-embedding-3-small (requires OPENAI_API_KEY)
# MEMORY_MAP_EMBED_PROVIDER=local    # sentence-transformers all-MiniLM-L6-v2 (CPU, no API key)
# OPENAI_API_KEY=

# GitHub token for higher API rate limits and private repos (optional)
# GITHUB_TOKEN=

If MEMORY_MAP_MONGO_URI is left blank, history tools (suggest_history, save_history, etc.) return an error. Key-value memory (save_memory / load_memory) works without MongoDB.


Step 2b — MongoDB setup (required for history)

Conversation history is stored in MongoDB. Without it, the key-value memory tools still work but all history tools (suggest_history, save_history, load_history) return an error. MongoDB gives you unlimited history, persistence across reinstalls, and indexed lookups.

Install MongoDB Community Server

Download from mongodb.com/try/download/community.

During installation on Windows, tick "Install MongoDB as a Windows Service" — this starts MongoDB automatically on boot. You will never need to open Compass or start it manually.

Add the URI to your .env file:

MEMORY_MAP_MONGO_URI=mongodb://localhost:27017

That's all. The server creates the database and collection automatically on first use — no migrations, no CREATE TABLE.

Where MongoDB stores data

Default path
Data files C:\Program Files\MongoDB\Server\<version>\data\
Log files C:\Program Files\MongoDB\Server\<version>\log\
Database memory_map (created automatically)
Collections memory_map.history and memory_map.memory (created automatically)

Step 3 — Register the MCP server with Claude Code

Run this once. The -s user flag makes it available in all projects.

claude mcp add -s user memory_map -- memory-map-mcp

Restart Claude Code after running this.


Step 4 — Verify the server is connected

Open Claude Code and run:

/mcp

You should see memory_map listed with 21 tools. If it's not there, double-check the path in Step 3.


Step 5 — Enable session memory (global or per-project)

You have two options. Option A is recommended — it enables memory_map in every project without any per-project setup.

Option A — Global CLAUDE.md (works in all projects at once)

Claude Code reads ~/.claude/CLAUDE.md automatically at the start of every session in every project. Add the session setup block there once and you're done.

Open (or create) the file:

OS Path
Windows C:\Users\yourname\.claude\CLAUDE.md
Mac/Linux ~/.claude/CLAUDE.md

Paste this content:

## Session Setup (Required)
At the start of every session, before doing anything else:
1. Call `load_memory` with the current working directory
2. Call `suggest_history` with the current working directory and the user's first message
3. Read both outputs before exploring files or asking questions

Save or update memory entries whenever you learn something worth keeping across sessions.
Use short, lowercase keys: `stack`, `current_work`, `gotchas`, `key_files`. Keep values concise — one or two sentences max.
If something loaded from memory is no longer accurate, update it with `save_memory` using the same key.
Do not call `load_history` + `get_history_chunks` manually at session start — those are for inspection and the /mem_save flow only.

That's all. Every project now gets memory and history loaded automatically.

Option B — Per-project CLAUDE.md

If you only want memory_map active in specific projects, copy the file into each project root instead:

Windows:

copy C:\Users\yourname\memory_map\CLAUDE.md C:\Users\yourname\your-project\CLAUDE.md

Mac/Linux:

cp ~/memory_map/CLAUDE.md ~/your-project/CLAUDE.md

Claude Code reads any CLAUDE.md at the project root automatically.


Using memory_map in other projects

The MCP server and history hook are registered globally, so they work in every project automatically. The only per-project step is dropping a CLAUDE.md file.

What you do once per project

Copy the CLAUDE.md from this repo into your project root (see Step 5 above). That file instructs Claude to load memory and history at the start of every session.

You do not need to:

  • Re-register the MCP server
  • Change the hook configuration
  • Create any database or collection
  • Set up any project-specific config

How history is tracked per project

The hook receives the current working directory from Claude Code on every trigger. That path is used as the project namespace — so C:\projects\my-api and C:\projects\dashboard each get completely separate history, even though they share the same MCP server and the same MongoDB collection.

my-api session  → chunks stored under project: "C:/projects/my-api"
dashboard session → chunks stored under project: "C:/projects/dashboard"

Nothing bleeds between projects.

What gets saved automatically

Event What happens
UserPromptSubmit Each completed Q&A pair is saved as its own document
PreCompact All unsaved pairs are flushed before context compression
Stop All unsaved pairs are flushed when the session ends

No manual action needed. Each save extracts intent tags (bug-fix, database, feature, etc.) by local keyword matching — no LLM calls required. File edits and shell commands made during the response are also captured alongside the dialogue text.

If MEMORY_MAP_EMBED_PROVIDER=openai or local is set, embeddings are generated asynchronously in the background via backfill_history_embeddings — the hook always returns immediately regardless.

If a Q&A pair exceeds 4000 characters, it is automatically split into overlapping chunks linked by a shared group_id so context at chunk boundaries is never lost.

What Claude does at session start

When you open a project that has CLAUDE.md:

  1. Calls load_memory(project_path) — loads all saved key-value context for this project
  2. Calls suggest_history(project_path, first_user_message) — scores history chunks by relevance to your first message and returns the best fit within a token budget
  3. Has full project context before touching a single file

Where history and memory are stored

History lives in MongoDB (memory_map.history collection) and key-value memory in MongoDB (memory_map.memory collection), both filtered by the project field (the cwd). Each project gets its own isolated namespace — nothing bleeds between projects. When MongoDB is not configured, key-value memory falls back to .mcp_memory.json per project.

Per-project memory keys

Use short lowercase keys. Suggested starting set:

Key What to store
stack Languages, frameworks, databases in use
current_work What is actively being built or fixed
gotchas Non-obvious constraints, footguns, rules to never break
key_files The most important files and what they do

Claude saves these automatically as it learns your project. You can also save them manually:

save_memory("C:/projects/my-api", "stack", "FastAPI + Postgres + Redis")
save_memory("C:/projects/my-api", "gotchas", "never bypass the rate limiter middleware")

Step 6 — Enable automatic conversation history

This auto-saves each Q&A pair as it happens — no API key required.

Configure the hooks globally in ~/.claude/settings.json:

The memory-map-hook command is available after pip install memory-map-mcp. No path substitution needed.

~/.claude/settings.json (all platforms):

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "memory-map-hook",
            "timeout": 10
          }
        ]
      }
    ],
    "PreCompact": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "memory-map-hook --force",
            "timeout": 15
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "memory-map-hook --force",
            "timeout": 15,
            "async": true
          }
        ]
      }
    ]
  }
}

Restart Claude Code. History will now be saved automatically after every Q&A pair, on context compaction, and when the session ends.


How session memory works

First session — Claude explores your project and saves what matters:

save_memory(path, "stack", "Next.js frontend, FastAPI backend, Postgres")
save_memory(path, "gotchas", "never import db.py directly, always go through models/")

Every session after — Claude calls load_memory first and has full context instantly:

[stack] Next.js frontend, FastAPI backend, Postgres
[gotchas] never import db.py directly, always go through models/

No file reading. No re-explaining the codebase. Context in one tool call.


How conversation history works

After every Q&A exchange, the hook saves the dialogue to MongoDB (or a local JSON file). Each pair becomes its own document — no mixed-topic blobs. Tags are extracted by local keyword matching — no LLM calls, no API keys needed.

What gets captured per pair:

  • The user message (text)
  • The assistant's full response, including text commentary, file edits ([Edit: path]), writes ([Write: path]), and shell commands ([Bash: ...])

At session start, Claude calls suggest_history, which uses a hybrid retrieval strategy:

  1. Concurrent fetch — vector search and BM25/tag scoring run in parallel to minimise latency
  2. Vector search (when MEMORY_MAP_EMBED_PROVIDER=openai or local) — semantic similarity over all stored chunks using OpenAI text-embedding-3-small or local all-MiniLM-L6-v2
  3. BM25 scoring — Okapi BM25 keyword scoring over the last 50 chunks, with query expansion via tag-keyword synonyms
  4. Reciprocal Rank Fusion (RRF) — merges the vector and BM25 ranked lists; chunks in both lists outrank chunks in only one
  5. MMR re-ranking — Maximal Marginal Relevance penalises redundant chunks so the result set covers more distinct topics (configurable diversity 0.0–1.0, default 0.3)
  6. Anchor — the most recent chunk is always included for session continuity
  7. Token budget — results selected relevance-first until the budget is filled
=== Relevant History (3 chunks, 650 tokens) ===

[abc123] 2026-05-07T09:40:49Z tags:[bug-fix,database]
user: postgres migration failed — column already exists
assistant: added IF NOT EXISTS to the ALTER TABLE statement
...

This means Claude can surface a relevant chunk from 3 months ago if it matches your current task — not just whatever you worked on last.

Tag vocabulary (extracted automatically from dialogue content):

api-design · architecture · auth · bug-fix · configuration · data-pipeline · database · debugging · deployment · documentation · feature · memory · performance · refactor · testing · tooling

Storage backends:

Store Backend When used
Conversation history MongoDB memory_map.history MEMORY_MAP_MONGO_URI is set (required)
Key-value memory MongoDB memory_map.memory MEMORY_MAP_MONGO_URI is set (primary)
Key-value memory .mcp_memory.json per project MongoDB not configured (fallback)

Memory compression

Memory output is compressed at read time to save tokens. Three levels:

Level Format Example
0 (raw) key: value stack: Python server using fastmcp
1 (compact, default) [key] value [stack] Python server using fastmcp
2 (dense) abbreviated keys + values [stack] py srv using fastmcp
set_compression(project_path, 1)

Multi-project support

Browse and search memory across all your projects at once:

list_projects(base_path)                         # all projects with saved memory
get_project_summary(project_path)                # memory + recent history for one project
load_cross_project_memory(base_path, "stack")    # load a specific key from all projects
search_across_projects(base_path, "postgres")    # search memory values across all projects
save_global_memory("name", "Sidhartha")          # user-level facts available in all projects
load_global_memory()                             # load global facts

Manual history save — /mem_save

Type /mem_save in Claude Code at any time to immediately checkpoint the recent conversation. Claude summarizes what was discussed and calls save_history.

Useful when conversations get long, before switching topics, or before closing a session mid-task.


Tools reference

Structure & Git

Tool Args Description
get_local_structure path, max_depth=5 Directory tree of a local folder
get_github_structure repo, branch="main" File tree of a GitHub repo (owner/repo)
get_git_history path, count=5 Recent commits as hash | subject

Memory

Tool Args Description
save_memory project_path, key, content Save or update a context entry. Returns a warning if the new value is semantically similar (word Jaccard ≥ 0.7) to an existing entry — the save always succeeds
load_memory project_path, query="", top_k=10 Load saved context (compressed). Pass a query to get TF-IDF ranked results
delete_memory project_path, key Remove a specific entry
set_compression project_path, level Set compression level (0, 1, or 2) — persisted in MongoDB when configured
migrate_memory_to_mongo project_path, dry_run=False, force=False One-time migration of .mcp_memory.json into MongoDB. Pass project_path="__global__" to migrate global memory. Use dry_run=True to preview, force=True to overwrite existing entries

Conversation History

Tool Args Description
suggest_history project_path, user_message, token_budget=2000, diversity=0.3 Primary session-start tool. Hybrid retrieval: concurrent vector search + BM25, merged with RRF, re-ranked with MMR. Always includes the most recent chunk; fills remaining budget relevance-first
save_history project_path, dialogue, session_id, tags Save a raw conversation chunk with auto-extracted tags. Auto-summarises oldest chunks if total tokens exceed MCP_HISTORY_MAX_TOKENS
summarise_history project_path, n=10 Collapse the n oldest non-summary chunks into one summary chunk. Triggered automatically by save_history; call manually to compact immediately
load_history project_path, last_n=5 Load the tag index for recent chunks (id, timestamp, tags, preview, token cost) — use for inspection or /mem_save flow
get_history_chunks project_path, ids Fetch full dialogue for comma-separated chunk IDs + total token sum
backfill_history_embeddings project_path="", batch_size=20 Generate embeddings for chunks saved before MEMORY_MAP_EMBED_PROVIDER was configured. Run repeatedly until remaining=0
backfill_bm25_text project_path="", batch_size=100 Write the bm25_text field to chunks saved before this field was introduced. Run once after upgrading; repeat until remaining=0

Multi-project

Tool Args Description
list_projects base_path List all projects with saved memory under a directory
get_project_summary project_path Memory keys + recent history tag index for a project
load_cross_project_memory base_path, query_keys Aggregate memory across all projects, optionally filter by key
search_across_projects base_path, keyword Full-text search across all project memory values
save_global_memory key, content Save a user-level fact available in all projects
load_global_memory Load all global facts

Environment variables

Variable Default Description
MEMORY_MAP_MONGO_URI (unset) MongoDB connection string. Required for all history tools. Primary store for key-value memory when set.
MEMORY_MAP_AUTO_MIGRATE 1 When 1 (default), automatically migrates .mcp_memory.json into MongoDB on the first save_memory or load_memory call for each project. Set to 0 to disable.
MEMORY_MAP_EMBED_PROVIDER (unset) openai — vector search via OpenAI text-embedding-3-small (1536 dims); local — vector search via sentence-transformers all-MiniLM-L6-v2 (384 dims, CPU, no API key, ~90 MB first-run download); atlas — Atlas autoEmbed (Voyage-4). BM25-only if unset.
MEMORY_MAP_MIN_VECTOR_SCORE 0.65 Minimum Atlas vectorSearchScore threshold (below = noise).
OPENAI_API_KEY (unset) Required when MEMORY_MAP_EMBED_PROVIDER=openai.
GITHUB_TOKEN (unset) GitHub token for private repos / higher rate limits
MCP_MAX_ENTRY_KB 10 Max size per memory entry in KB
MCP_REDACT_PATTERNS (unset) |-delimited list of extra regex patterns to redact (e.g. MYCO-[A-Z0-9]{32}|Bearer [A-Za-z0-9._-]+). Invalid patterns are logged and skipped.
MCP_GIT_TIMEOUT 10 Timeout in seconds for git commands
MCP_HISTORY_MAX_TOKENS 50000 Total token threshold that triggers auto-summarisation in save_history
MCP_HISTORY_SUMMARISE_N 10 Number of oldest chunks to collapse per auto-summarise pass
MCP_MAX_TURN_CHARS 3000 Max characters captured per turn before truncation
MCP_MAX_CHUNK_CHARS 4000 Max characters per saved history chunk; larger Q&A pairs are split into overlapping chunks
MCP_OVERLAP_CHARS 100 Overlap between split chunks so context at boundaries is preserved
MCP_WORKSPACE_ROOT (unset) When set, all project_path / base_path / path arguments must resolve inside this directory. Recommended for shared or multi-project setups.

Running tests

python -m pytest tests/ -v

195 tests across 8 files:

File Coverage
test_compression.py 3-level compression, abbreviation, filler removal
test_history.py Save/load/fetch, stats, tag extraction, split chunks, BM25 scoring, RRF merge, MMR re-ranking, token counting, auto-summarise
test_e2e.py Full hook→storage→MCP retrieval journeys, per-pair saving, split chunks, token budget, suggest_history relevance
test_multi_project.py Cross-project tools, global memory
test_new_features.py load_memory query filtering, max_depth in multi-project tools, gitignore handling
test_validation.py Key validation, size limits, corrupted JSON recovery, TF-IDF ranking, save_memory similarity warning
test_memory_mongo.py MongoDB-backed save/load/delete, stale warning, TF-IDF, similarity warning
test_mongo_features.py MongoDB compression, global memory, migration tool, auto-migrate

Tests requiring a live MongoDB connection use the requires_mongodb fixture and are skipped automatically when MEMORY_MAP_MONGO_URI is unset.



Star History

Star History Chart


Built with FastMCP · Code of Conduct

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memory_map_mcp-0.1.0.tar.gz (61.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memory_map_mcp-0.1.0-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file memory_map_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: memory_map_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 61.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for memory_map_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 425773d6511ef3ada791ec7fc15b024af5e27331b846f39838afe09ecf6235c7
MD5 f9309d9376c0ee8378dc60c6db865cb3
BLAKE2b-256 3b87510939227071a0ef67429a5d296244e0e720ff202f2a2bc8e628bc3183de

See more details on using hashes here.

Provenance

The following attestation bundles were made for memory_map_mcp-0.1.0.tar.gz:

Publisher: publish.yml on kid-sid/memory_map

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file memory_map_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: memory_map_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 38.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for memory_map_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d3d5bc30a736a9e50aab49378d0c885c5d0dcbde574d2142ffbb885d64185cd0
MD5 5b253c8ad2f51caefbf64e12835c4a4d
BLAKE2b-256 5541a60283c8e7b1f91f1ba91ab014a88f2c32757bb93f4f3a28894264aa6ae2

See more details on using hashes here.

Provenance

The following attestation bundles were made for memory_map_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on kid-sid/memory_map

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page