Contextual Memory MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Contextual Memory MCPRemember that I like pizza."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Contextual Memory MCP
A local-first persistent contextual-memory engine with an MCP adapter for AI models such as Qwen.
The project is being developed incrementally. The first ingestion target is a directory of reusable Markdown prompt material, but the storage and retrieval layers are general-purpose.
Architecture
Text, images, audio, and video
|
v
Modality-specific semantic distillation
|
+--> SQLite semantic capsules and sparse concepts
|
+--> packed int8 latent parameter bank
|
v
Hybrid retrieval and context assembly
|
v
Thin MCP adapter used by QwenThe CLI performs administrative work. The MCP server exposes memory operations that are useful to the model.
Related MCP server: contextgit
Install with uv
uv venv --python 3.12
uv pip install -e .
cp .env.example .envPython 3.12 or 3.13 is recommended for broad compatibility with the current machine-learning dependencies.
Index files and directories
The CLI accepts either one file or an entire directory. With no --name, the
content is added to the normal writable main store:
uv run contextual-memory-index scan /path/to/character.md
uv run contextual-memory-index scan /path/to/saved/promptsProvide --name to add the target to a named database. If that database does
not exist, it is created automatically:
uv run contextual-memory-index scan /path/to/character.md --name roleplayNew named databases are immutable after indexing by default. Use --mutable
when the named database should remain writable:
uv run contextual-memory-index scan /path/to/saved/prompts --name prompt-library --mutableA later explicit scan can update an existing named database. Locked databases
are reopened only for that update and then returned to their previous mode.
Use --replace when the entire named database should be rebuilt instead:
uv run contextual-memory-index scan /path/to/saved/prompts --name prompt-library --replaceDirectory scans support exclusions, and either kind of scan can force unchanged content to be indexed again:
uv run contextual-memory-index scan /path/to/saved/prompts --exclude archive --forceClear stored data
Interactive confirmation:
uv run contextual-memory-index clear --store mainNon-interactive confirmation:
uv run contextual-memory-index clear --store main --yesScanning and clearing are deliberately CLI-only maintenance operations. They are not exposed to the model through MCP.
Run the MCP server
uv run contextual-memory-mcpThe MCP server exposes model-facing recall, ingestion, lifecycle, and maintenance tools:
recall_memory
Retrieves semantically, lexically, and graph-related memory and returns clean, source-attributed Markdown that Qwen can use in its active context.
Typical model call:
recall_memory(
query="Create a gender-swapped character reference sheet while preserving identity, colors, and species traits"
)store_memory
Automatically captures durable information directly stated by the user. The model is instructed to call it before drafting its response whenever the current message contains durable information, including during ordinary conversation. The user does not need to say “remember this,” and routine storage must not trigger a permission question or an announcement. The model supplies an integer memory type and a normalized importance score from 0.0 to 2.0. The server validates those values and assigns lifecycle state, origin, confidence, source quality, and conservative server-owned lifecycle policy.
store_memory_candidate
Stores model-generated hypotheses and interpretations as candidate inferences.
It is not a substitute for store_memory when the user directly stated the
information, whenever that statement is durable. The
model supplies semantic type and importance, while the server assigns lifecycle
state, origin, confidence, source quality, and conservative retention policy.
explore_memory
Traverses the knowledge graph around a concept and returns related concepts plus supporting memory excerpts.
The MCP does not expose scan, clear, stats, or database-deletion tools. Those are administrative concerns and remain under direct user control.
LM Studio configuration
Add the server as a stdio MCP using the repository's virtual environment. A typical configuration resembles:
{
"mcpServers": {
"contextual-memory": {
"command": "/absolute/path/to/contextual-memory-mcp/.venv/bin/contextual-memory-mcp",
"args": [],
"cwd": "/absolute/path/to/contextual-memory-mcp"
}
}
}Alternatively, invoke it through uv:
{
"mcpServers": {
"contextual-memory": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/contextual-memory-mcp",
"contextual-memory-mcp"
]
}
}
}Use absolute paths when LM Studio is launched outside a terminal, because GUI applications may not inherit the same shell PATH.
Storage
Persistent data is stored beneath CM_DATA_DIR, which defaults to ./data:
contextual_memory.sqlite3vectors/latent_vectors.sqlite3(compact int8 parameter bank)store_overlays.sqlite3(local ranking overlays for immutable stores)stores/<name>/manifest.jsonplus each scanned store database
The embedding model is stored in the application's own model directory and normal server/index runs load it with network access disabled. Install it once before the first scan or recall:
uv run contextual-memory-index model installCheck the local installation without contacting Hugging Face:
uv run contextual-memory-index model statusThe default location is CM_DATA_DIR/models. Override it with CM_MODELS_DIR.
After installation, deleting the global Hugging Face cache does not affect this
project. A missing model produces an explicit error instead of downloading during
an MCP or indexing operation.
Current retrieval path
recall_memory currently combines:
semantic similarity from the packed int8 parameter bank
SQLite full-text relevance
graph relationships
segment importance
per-source diversity
a configurable context-size budget
The returned value is Markdown rather than an embedding blob or database record, so the model receives reusable source material directly.
Memory importance and lifecycle
Memory importance is persistent and evolves through an explicit maintenance pass:
new recall accesses
+
configured access gain
-
elapsed inactivity decay
|
v
updated importance
|
v
promotion / archival policyRun run_memory_maintenance through MCP to reinforce accessed memories, decay
inactive unpinned memories, synchronize vector metadata, and then evaluate
candidate promotion or active-memory archival. Pass dry_run=true to inspect
all proposed changes without mutating storage.
All state, type, origin, lifecycle-reason, and importance-reason enums are
stored as SQLite integers and exposed in Python as IntEnum values.
Multiple memory stores
The server provides a writable main store. Scanned databases live beneath
data/stores/<name>/ and contain their own manifest.json. The filesystem is
the source of truth: there is no separate store registry, registration step,
mount operation, or startup fixture.
list_memory_stores discovers manifests directly from disk. A named store is
opened lazily when recall or another operation addresses it. Returned memory
IDs are globally qualified, for example ghidra-core:seg_abcd.
Store modes are SQLite integers exposed through StoreMode:
0 READ_WRITE
1 READ_ONLY
2 IMMUTABLEWrites require an explicit target_store; they are never broadcast. Before a
write, clients must call list_memory_stores whenever the destination is not
already established in the current context. Store IDs must not be guessed or
discovered by intentionally causing a failed write.
Maintenance runs only against writable stores. Read-only and immutable SQLite
databases are opened with SQLite read-only URI modes and are never migrated
automatically. Their recall access counts and user-specific ranking choices are
kept in store_overlays.sqlite3 instead of changing canonical content.
Creating a scanned database is sufficient to make it discoverable:
uv run contextual-memory-index scan ./project --name project-memoryThis creates:
data/stores/project-memory/
├── manifest.json
├── project-memory.sqlite3
└── vectors/No registration or mounting command is required.
Web search providers
Automatic web acquisition can use multiple search providers in priority order. Providers that need credentials are skipped unless configured, and failures automatically fall through to the next provider.
CM_WEB_SEARCH_PROVIDERS=exa,brave,tavily,searxng,duckduckgo
CM_WEB_SEARCH_TIMEOUT=12
CM_EXA_API_KEY=
CM_BRAVE_SEARCH_API_KEY=
CM_TAVILY_API_KEY=
CM_SEARXNG_URL=http://localhost:8080With no API keys or SearXNG URL, DuckDuckGo is used as the zero-configuration fallback. For a self-hosted setup, place searxng first and set CM_SEARXNG_URL. The configured SearXNG instance must permit JSON search responses.
Web acquisition and indexing
By default, indexed memory is authoritative over the web. recall_memory only triggers web discovery, page ingestion, and a second local recall when local retrieval returns no hits. Search providers are attempted in configured priority order; unconfigured providers are skipped and failures fall through to the next provider.
CM_MEMORY_AUTHORITY_OVER_WEB=true
CM_WEB_SEARCH_PROVIDERS=exa,brave,tavily,searxng,duckduckgo
CM_WEB_SEARCH_CACHE_DAYS=7
CM_WEB_ACQUISITION_RETRY_DAYS=7
CM_WEB_ACQUISITION_REFRESH_DAYS=90Search results are cached in data/web_acquisition.sqlite3. Acquisition history suppresses repeated searches for unavailable topics and schedules successful topics for a later refresh.
The index CLI accepts directories, individual files, direct URLs, and search queries:
python main.py scan ./prompts
python main.py scan ./character.md --name roleplay
python main.py scan https://example.org/wiki/Character --name roleplay
python main.py scan --search "Character franchise personality dialogue" --name roleplayWhen --name is omitted, content is indexed into the writable main store. Missing named stores are created automatically and are immutable after indexing unless --mutable is supplied. MediaWiki pages use their API when available, and GitHub blob URLs are fetched through their raw-content endpoint.
Visual memory
scan now discovers common image formats and sends them to an OpenAI-compatible
vision model. LM Studio's local server is the default endpoint.
contextual-memory-index scan ./reference-images \
--name visual-reference \
--vision-model qwen2.5-vl-7b-instructThe extractor stores a searchable visual summary plus independently classified text regions. Its general-purpose taxonomy distinguishes speech and thought bubbles, captions/overlays, clothing text, text attached to physical surfaces, documents, UI/HUD text, sound effects, watermarks, and uncategorized text. Every region includes normalized bounding coordinates and separate OCR and classification confidence values. This lets retrieval distinguish, for example, a caption saying "red coat" from the words printed on the coat itself.
Configuration:
CM_VISION_MODEL: default vision model name (required when images are found)CM_VISION_BASE_URL: compatible/v1endpoint; defaults to LM Studio athttp://127.0.0.1:1234/v1CM_VISION_API_KEY: optional bearer tokenCM_VISION_TIMEOUT: request timeout in secondsCM_VISUAL_GLOBS: comma-separated image globs
Use --no-vision to skip image files during a directory scan. Scanning a single
image with --no-vision is rejected rather than silently doing nothing.
Latent multimodal memory
This branch stores learned external-memory representations rather than copies of source training material. The scanner reads a source only during ingestion, distills it into a lossy semantic capsule, embeds that capsule, quantizes the normalized embedding to signed int8, and persists the compact parameter record. Raw image, audio, and video bytes are never copied into the memory store.
Supported inputs:
Text: works immediately through the built-in heuristic semantic provider. Configure
CM_SEMANTIC_MODELlater for higher-quality local-LLM distillation.Images: analyzed only when
CM_VISION_MODELis configured, including classified text regions. Otherwise directory scans skip images and report the count.Audio: transcribed only when
CM_AUDIO_MODELis configured, then semantically distilled. Otherwise directory scans skip audio and report the count.Video: enabled only when both vision and audio providers are configured. It is sampled with ffmpeg, frames are analyzed, audio is transcribed, and both channels become a compact temporal capsule.
Optional local services are enabled per modality:
CM_SEMANTIC_PROVIDER=auto
# CM_SEMANTIC_MODEL=your-local-instruct-model
# CM_VISION_MODEL=your-local-vision-model
# CM_AUDIO_MODEL=your-local-whisper-modelConfigured endpoints use the OpenAI-compatible API and default to LM Studio's
local http://127.0.0.1:1234/v1. Unconfigured modalities do not prevent the
server or text scanner from running. Audio/video ingestion requires ffmpeg on
PATH only when those modalities are actually processed. The original wording or media cannot be reconstructed from the stored
capsules and quantized vectors; retain source files separately when exact
reproduction or citation is required.
Parameter storage
The former vector collection has been replaced by
latent_vectors.sqlite3. Each row contains only a stable memory ID, dimensions,
a scalar quantization scale, and a packed int8 vector. Retrieval uses exact
integer-vector scanning and SQLite remains authoritative for semantic capsules,
concept weights, and lifecycle state.
Hierarchical latent distillation
Large text files are distilled hierarchically rather than sent to the semantic model in one request. Source text is split into bounded input chunks, chunk capsules are merged into section capsules, and section capsules are merged into a document capsule. The stored latent document contains the compact document capsule and section capsules; original source wording and transient leaf capsules are not retained.
Configuration:
CM_SEMANTIC_MAX_TOKENS=512
CM_SEMANTIC_INPUT_CHUNK_CHARS=12000
CM_SEMANTIC_MERGE_FAN_IN=6
CM_SEMANTIC_CONCURRENCY=1 # 1 = sequential; 2+ enables bounded parallel requestsCM_SEMANTIC_MAX_TOKENS limits each generated capsule, not the source file.
CM_SEMANTIC_INPUT_CHUNK_CHARS is an approximate input-size guard chosen to
remain comfortable within an 8192-token model context. CM_SEMANTIC_MERGE_FAN_IN
controls how many lower-level capsules are combined per hierarchy request.
Interactive memory-store console
The MCP server starts a small localhost-only TCP console by default. It changes
which stores are searched when recall_memory omits its stores argument.
Explicit tool arguments still take precedence.
Start the MCP server normally, then connect from another terminal:
nc 127.0.0.1 8765Available commands:
stores
use prompts
use main prompts
use all
status
help
exituse all restores federated retrieval across every enabled store. Configure or
disable the console in .env:
CM_CONSOLE_ENABLED=true
CM_CONSOLE_HOST=127.0.0.1
CM_CONSOLE_PORT=8765Console without a TCP port (recommended with LM Studio)
LM Studio can keep the MCP process and its stderr hidden. The separate console
command writes the active-store selection into the same CM_DATA_DIR used by
the server, and the server reloads it on every recall:
contextual-memory-console
memory> stores
memory> use prompts
memory> statusA one-shot form is also available:
contextual-memory-console use prompts
contextual-memory-console statusNo nc connection or listening port is required. Both LM Studio and the
console command must use the same CM_DATA_DIR.
Media ingestion concurrency
Image analysis, audio transcription/distillation, and sampled video-frame analysis can use bounded concurrency:
CM_MEDIA_CONCURRENCY=1 # sequential; use 2+ for bounded parallel media requestsA one-off scan can override it with --media-concurrency N. Images and audio files are processed concurrently across a directory scan. Video files remain sequential at the file level, while each video's sampled frames are analyzed concurrently, preventing concurrency from multiplying across multiple videos.
Guaranteed automatic chat capture (two-pass proxy)
MCP servers do not automatically receive the user's raw chat messages. They only see tool calls that the host model elects to make, so MCP instructions alone cannot guarantee that every durable statement is stored.
This project includes an optional OpenAI-compatible chat proxy that observes the
actual request and response. It forwards the normal completion to LM Studio and
then runs a dedicated memory-extraction pass. The extraction pass writes direct
user statements to the configured writable memory store without requiring the
chat model to call store_memory.
Start the proxy:
uv run contextual-memory-chat-proxyThen change the chat application's OpenAI-compatible base URL from LM Studio's
usual http://127.0.0.1:1234/v1 to:
http://127.0.0.1:1235/v1Same model, two passes
This mode sends the normal reply first, then asks the same requested model to extract durable memories from the latest exchange:
CM_CHAT_CAPTURE_MODE=same-model
CM_CHAT_UPSTREAM_BASE_URL=http://127.0.0.1:1234/v1
CM_CHAT_CAPTURE_STORE=mainOnly one model needs to be loaded. It performs two sequential inference calls. The second pass runs after the response has been returned by the upstream model and is scheduled independently from the client response.
Separate extractor model
This mode keeps the main chat model and memory extractor independently configurable:
CM_CHAT_CAPTURE_MODE=separate-model
CM_CHAT_UPSTREAM_BASE_URL=http://127.0.0.1:1234/v1
CM_CHAT_CAPTURE_BASE_URL=http://127.0.0.1:1234/v1
CM_CHAT_CAPTURE_MODEL=qwen2.5-7b-instruct
CM_CHAT_CAPTURE_STORE=mainCM_CHAT_CAPTURE_BASE_URL may point to a second LM Studio/Ollama/OpenAI-compatible
server on another machine or port. When it is omitted, the extractor uses the
same upstream endpoint but requests CM_CHAT_CAPTURE_MODEL.
Verify that capture is actually happening
The proxy exposes a local diagnostics endpoint:
http://127.0.0.1:1235/v1/contextual-memory/statusIts counters distinguish the common failure cases:
observed_requests: requests that reached a capture-aware endpoint.scheduled_passes: extraction jobs accepted.completed_passes: successful extractor responses.stored_memories: memories actually written.failed_passesandlast_error: endpoint, JSON, or storage failures.last_endpoint: either/v1/chat/completionsor/v1/responses.
The proxy captures both OpenAI-compatible APIs. Earlier builds only captured
/v1/chat/completions, so clients using /v1/responses silently bypassed
automatic retention.
Available settings:
CM_CHAT_CAPTURE_MODE:off,same-model, orseparate-model.CM_CHAT_CAPTURE_STORE: explicit writable destination store; defaults tomain.CM_CHAT_CAPTURE_MODEL: required only forseparate-model.CM_CHAT_CAPTURE_BASE_URL: optional extractor endpoint.CM_CHAT_CAPTURE_MAX_MEMORIES: maximum atomic memories stored per exchange.CM_CHAT_CAPTURE_MAX_TOKENS: extractor output budget.CM_CHAT_CAPTURE_TIMEOUT: extractor request timeout.
The proxy currently buffers streamed upstream responses before relaying them, so clients receive valid streaming data but not token-by-token low-latency delivery. Use non-streaming chat completion requests when response latency matters most.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DaCodeChick/contextual-memory-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server