Persistent memory, semantic retrieval, and evaluation tooling for building assistants that remember users over time.
If you want the fastest path from zero to Claude Desktop integration, use this.
-
Install prerequisites: Docker Desktop, Node.js 18+, and Claude Desktop.
-
From this project root, start everything:
docker compose up -dThis launches NeuroMem, Qdrant, and Ollama. On first run, it also auto-pulls the configured Ollama chat and embedding models.
- Install the MCP bridge once:
npm install -g mcp-remote- Add this to Claude Desktop config:
{
"mcpServers": {
"neuro-mem": {
"command": "mcp-remote",
"args": ["http://localhost:8000/mcp"]
}
}
}Windows fallback if mcp-remote is not on PATH:
{
"mcpServers": {
"neuro-mem": {
"command": "C:\\Users\\ADMIN\\AppData\\Roaming\\npm\\mcp-remote.cmd",
"args": ["http://localhost:8000/mcp"]
}
}
}-
Restart Claude Desktop.
-
Optional quick check:
try { (Invoke-WebRequest -Uri "http://localhost:8000/mcp" -Method GET -UseBasicParsing -TimeoutSec 10).StatusCode } catch { $_.Exception.Response.StatusCode.value__ }Expected result: 406 means the MCP endpoint is reachable.
NeuroMem gives your assistant a practical long-term memory stack:
- Store user facts and events as structured memories.
- Retrieve relevant memories with semantic search + ranking.
- Use memory in chat responses automatically.
- Evaluate retrieval quality with reproducible test cases.
- Convert Label Studio annotations into evaluation-ready datasets.
| Capability | What it does |
|---|---|
| Memory storage | Stores episodic and semantic memories with metadata |
| Smart retrieval | Combines similarity with importance and recency signals |
| Chat integration | Runs retrieve -> respond -> extract -> store loop |
| Provider flexibility | Ollama and Gemini embedding/LLM options |
| Evaluation suite | Retrieval, deduplication, and performance evaluation |
| Dataset tooling | Label Studio conversion and dataset exploration scripts |
flowchart TB
U[User Message] --> C[ChatManager]
C --> B[Brain]
B --> R[MemoryRetriever]
B --> S[MemoryStore]
R --> V[(Qdrant)]
S --> V
C --> L[LLMClient]
C --> E[MemoryExtractor]
E --> S
- Docker Compose runs
neuromem,ollama, andqdrantas persistent services. neuromemexposes MCP over HTTP athttp://localhost:8000/mcp.- Claude Desktop launches
mcp-remote(stdio) which proxies to that HTTP endpoint.
This avoids stdio lifecycle problems inside detached Docker containers while keeping Claude's expected stdio model.
NeuroMem/
|- app/ # CLI entrypoints
|- ai/ # Chat and LLM integration
|- core/ # Brain orchestrator
|- memory/ # Store/retrieve/extraction/embeddings
|- intelligence/ # Ranking, scoring, decay
|- db/ # Qdrant vector store
|- models/ # Memory/user models
|- evaluation/ # Eval runners, evaluators, converters, data
|- config/ # Runtime settings
|- mcp_server/ # MCP server and tool wrappers
|- utils/ # Debug and validation scripts
|- docker-compose.yml # NeuroMem + Ollama + Qdrant + Label Studio
Install these before starting:
- Docker Desktop 4.x+ (recommended for runtime)
- Python 3.9+ (for local CLI/dev workflows)
- Node.js 18+ (for
mcp-remotebridge) - Claude Desktop (if you want MCP integration)
Choose one path based on your goal:
- Path A: Docker + Claude (recommended for using NeuroMem as an MCP service)
- Path B: Local Python development (recommended for coding and evaluation)
If you prefer a prebuilt image, pull from Docker Hub:
docker pull azizmbk/neuromem:latestRun NeuroMem directly (expects Ollama and Qdrant reachable by network/DNS):
docker run --rm -p 8000:8000 \
-e LLM_PROVIDER=ollama \
-e EMBEDDING_PROVIDER=ollama \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434/v1 \
-e QDRANT_HOST=host.docker.internal \
-e QDRANT_PORT=6333 \
-e MCP_ENABLED=true \
azizmbk/neuromem:latestdocker compose up -dOn the first run, Compose also waits for Ollama and pulls the configured chat and embedding models automatically, so Claude can connect without a manual ollama pull step.
This starts:
neuromemon8000ollamaon11434qdranton6333label-studioon8080
The neuromem MCP service runs as a persistent HTTP endpoint on port 8000 and exposes MCP at:
http://localhost:8000/mcp
Install once:
npm install -g mcp-remoteThen use this Claude config:
{
"mcpServers": {
"neuro-mem": {
"command": "mcp-remote",
"args": ["http://localhost:8000/mcp"]
}
}
}Windows note: if mcp-remote is not on PATH, use the absolute command path:
{
"mcpServers": {
"neuro-mem": {
"command": "C:\\Users\\ADMIN\\AppData\\Roaming\\npm\\mcp-remote.cmd",
"args": ["http://localhost:8000/mcp"]
}
}
}try { (Invoke-WebRequest -Uri "http://localhost:8000/mcp" -Method GET -UseBasicParsing -TimeoutSec 10).StatusCode } catch { $_.Exception.Response.StatusCode.value__ }Expected result: 406 is OK for GET on this endpoint (it confirms service reachability).
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txtStart with this local setup:
llm_provider=ollama
ollama_base_url=http://localhost:11434/v1
ollama_model=qwen2.5:3b-instruct
embedding_provider=ollama
ollama_embedding_model=mxbai-embed-large
qdrant_host=localhost
qdrant_port=6333
qdrant_collection_name=ai_brain_memoriesIf you want Gemini instead, switch llm_provider and embedding_provider to gemini and add gemini_api_key.
The CLI is the fastest way to store, search, delete, and inspect memories.
Store a memory:
python -m app.cli remember "User likes Ethiopian food" -u demo -t semantic -g food -g preferenceSearch memories:
python -m app.cli recall "what food does the user like?" -u demo -k 5Delete a memory:
python -m app.cli forget mem_abc123 -u demoBuild LLM-ready context:
python -m app.cli context "What are my preferences?" -u demoOpen an interactive memory chat:
python -m app.cli chat -u demoShow quick stats:
python -m app.cli stats -u demofrom core.brain import Brain
from models.memory import MemoryType
brain = Brain(user_id="alice")
brain.remember(
content="Alice likes long-distance running",
memory_type=MemoryType.SEMANTIC,
importance_score=0.8,
tags=["fitness"]
)
results = brain.recall("What sports does Alice do?", top_k=5)
for r in results:
print(r.final_score, r.memory.content)Use the Python API when you want to embed NeuroMem inside another service or workflow.
The MCP server exposes the same memory capabilities as tools for agent runtimes.
python -m app.cli mcpTo run the HTTP server locally:
python -m app.cli mcp --transport streamable-http --host 0.0.0.0 --port 8000Available MCP tools:
store_memoryretrieve_memoriesget_contextdelete_memorychatextract_memories
Run the full suite:
python -m evaluation.run_evalOutputs include retrieval metrics (Precision@3, Recall@5, nDCG, MRR, MAP), deduplication metrics, and performance benchmarks.
Use custom test cases:
python -c "from evaluation.run_eval import run_all; run_all('evaluation/data/test_cases_from_label_studio.json')"Convert a Label Studio export into the test-case format:
python -m evaluation.converters.from_label_studio \
--input-path evaluation/data/project-1-at-2026-03-18-02-30-cc045d7f.json \
--output-path evaluation/data/test_cases_from_label_studio.jsonCreate Label Studio tasks from unlabeled scenarios:
python -m evaluation.converters.to_label_studioEvaluation inputs and outputs live under evaluation/data/ and evaluation/data/results/.
Useful local checks:
The utils/ folder contains helper scripts for debugging embeddings, retrieval scores, and deduplication experiments.
python -m app.cli remember "User likes Ethiopian food" -u smoke -t semantic -g food
python -m app.cli recall "what food does the user like?" -u smoke -k 3
python -m app.cli context "What are the user's food preferences?" -u smokeExpected result: the recall output includes the stored memory, and context is non-empty.
- Use
http://localhost:8000/mcpin yourmcp-remoteargs. - Avoid
host.docker.internalor machine hostnames unless you explicitly configure MCP transport security.
- Symptom: errors fetching anonymous token from
auth.docker.io. - Current workaround in this repo: base image uses
mirror.gcr.io/library/python:3.11-slim. - Retry with a fresh build:
docker compose up -d --build- Install globally:
npm install -g mcp-remote - Or use absolute command path in Claude config:
C:\\Users\\ADMIN\\AppData\\Roaming\\npm\\mcp-remote.cmd
Store a fact or event with remember, then validate retrieval with recall or context.
Use core.brain.Brain directly in Python or wrap it with ai.chat.ChatManager for conversational flows.
Run the MCP server and call the tools from your client using the same user IDs and memory workflow as the CLI.
Main settings are defined in config/settings.py and loaded from .env.
| Setting | Default | Notes |
|---|---|---|
llm_provider |
ollama |
ollama or gemini |
embedding_provider |
ollama |
ollama or gemini |
ollama_model |
qwen2.5:3b-instruct |
Chat model |
ollama_embedding_model |
mxbai-embed-large |
Embedding model |
qdrant_host |
localhost |
Qdrant host |
qdrant_port |
6333 |
Qdrant port |
langsmith_tracing |
false |
Optional tracing |
- Docker route is the easiest:
http://localhost:8080. - In Python environments >= 3.13, the project installs
label-studio-sdkinstead of fulllabel-studiopackage due upstream build issues. - If you need full local CLI on Windows, use Docker or a Python 3.12 virtual environment dedicated to Label Studio.
pytestUseful utility scripts live under utils/ for data checks, embedding checks, and evaluation debugging.
This repository publishes images to Docker Hub as azizmbk/neuromem using GitHub Actions.
Required repository secrets:
DOCKER_HUB_USERNAMEDOCKER_HUB_TOKEN
Publish behavior:
- Push to
mainpublishesazizmbk/neuromem:latestandazizmbk/neuromem:sha-<commit>. - Push a git tag like
v0.1.0publishesazizmbk/neuromem:v0.1.0.
Release flow:
git tag v0.1.0
git push origin v0.1.0MIT