ctrl-memory
Provides automatic prefetch of relevant context before every LLM turn, captures conversation turns as facts, and exposes tools for memory management (add, search, delete, status) for Hermes Agent.
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., "@ctrl-memoryremember that Alice prefers Fastify over Express"
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.
ctrl-memory
Lightweight, local-first MCP memory server for LLM agents.
Store, search, and retrieve agent memories with zero external dependencies. Plug it into Hermes, Claude Code, Cursor, or any MCP-compatible client.
pip install ctrl-memory
ctrl-memory-mcp✨ Features
Zero-dependency core — pure Python, no databases, no external services
Two backends — JSON files (MVP, zero deps) or SQLite (production, WAL mode)
Semantic search — optional
sentence-transformersfor cosine similarity rankingHybrid retrieval — keyword recall + vector re-ranking for best precision/recall
Fuzzy matching — Damerau-Levenshtein typo tolerance built in
Scope filtering — tag-based domain isolation
Supersession awareness — automatically filters outdated/obsolete facts
Hermes plugin — auto-prefetch context, auto-capture conversation turns
MCP stdio server — plug into any MCP-compatible client
User isolation — each user's memory is fully separated
Cross-session persistence — memories survive between conversations
Related MCP server: tartarus-mcp
🚀 Quick start
One-liner install (recommended)
curl -fsSL https://raw.githubusercontent.com/ctrlProgrammer/ctrl-memory-system/main/install.sh | bashThis creates an isolated virtual environment in ~/.local/share/ctrl-memory/, installs ctrl-memory with semantic search, and makes the ctrl-memory-mcp command available globally. No pip install --user or sudo needed.
After install, open a new terminal (or exec $SHELL) and run:
ctrl-memory-mcpManual install with pip
# Core (zero deps)
pip install ctrl-memory
# With semantic search
pip install "ctrl-memory[embeddings]"⚠️ If your system restricts global pip installs (PEP 668), use the one-liner above or install inside a virtual environment:
python3 -m venv .venv source .venv/bin/activate pip install "ctrl-memory[embeddings]"
pipx (alternative)
pipx install "ctrl-memory[embeddings]"Run the MCP server
ctrl-memory-mcpThe server listens on stdin/stdout (MCP stdio transport). It starts when a client connects and exits when the client disconnects — no background daemon.
Check if it's working
In one terminal, start the server:
ctrl-memory-mcpIn another terminal, run:
# 1. Initialize the session
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}' | ctrl-memory-mcp
# 2. Add a fact
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"add_memory","arguments":{"user_id":"alice","content":"Alice prefers Fastify over Express"}}}' | ctrl-memory-mcp
# 3. Search
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_memory","arguments":{"user_id":"alice","query":"web framework"}}}' | ctrl-memory-mcp💡 For Hermes users: the plugin activates automatically when you start a new conversation. No need to run
ctrl-memory-mcpseparately. Memory is stored per-user across sessions.
🔄 Updating
# If you used the one-liner installer — just re-run it (upgrades in-place):
curl -fsSL https://raw.githubusercontent.com/ctrlProgrammer/ctrl-memory-system/main/install.sh | bash
# If you used pip:
pip install --upgrade "ctrl-memory[embeddings]"
# If you used pipx:
pipx upgrade ctrl-memory📦 Backends
JSON backend (default)
Zero dependencies
One file per user:
~/.ctrl-memory/<user_id>.jsonAuto-increment IDs, append-only writes
Best for: MVP, personal use, <1000 facts
SQLite backend
Single
.dbfile with WAL modeIndexed queries, ACID transactions
Embedding storage for semantic search
Best for: production, multi-user, >1000 facts
ctrl-memory-mcp --backend sqlite🧠 Semantic search
When sentence-transformers is installed, ctrl-memory automatically enables:
Auto-embedding — facts are vectorized at write time (384-dim all-MiniLM-L6-v2)
Hybrid search — keyword candidates → cosine similarity re-ranking → sorted by relevance
Score filtering — configurable
min_scorethreshold to filter weak matches
pip install "ctrl-memory[embeddings]"No flags needed — detection is automatic.
🔌 Hermes Agent plugin
ctrl-memory ships with a native Hermes Agent provider.
Install
# Copy the plugin
cp -r hermes_provider ~/.hermes/hermes-agent/plugins/memory/ctrl-memory/Configure
Add to ~/.hermes/config.yaml:
memory:
provider: ctrl-memory
config:
backend: sqlite # or json (default)
db_path: ~/.hermes/memory.dbThe plugin provides:
Automatic prefetch — relevant context injected before every LLM turn
Turn capture — facts extracted from conversations and stored
4 tools —
add_memory,search_memory,delete_memory,memory_status
🔧 MCP tools
Tool | Description |
| Store a new fact with optional metadata tags |
| Hybrid keyword + semantic search |
| Retrieve a specific fact by ID |
| List all facts for a user with pagination |
| Edit an existing fact (re-embeds if semantic enabled) |
| Remove a fact (cleans up embedding) |
| Get total fact count for a user |
| Pure cosine similarity search (uses embeddings) |
🏗️ Architecture
┌─────────────────────────────────────┐
│ MCP Client │
│ (Hermes, Claude Code, Cursor...) │
└──────────────┬──────────────────────┘
│ stdio JSON-RPC
┌──────────────▼──────────────────────┐
│ mcp_server.py │
│ MCP stdio transport layer │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ memory_backend.py │
│ ┌─────────┐ ┌──────────┐ │
│ │ JSON │ │ SQLite │ │
│ │ Store │ │ Store │ │
│ └─────────┘ └────┬─────┘ │
│ │ │
│ ┌─────────────────▼──────────┐ │
│ │ EmbeddingEngine │ │
│ │ (optional, auto-detect) │ │
│ └────────────────────────────┘ │
└─────────────────────────────────────┘Search flow
Query
│
▼
1. Keyword search (token-OR with stop-word filter)
│
├── No results? → Fuzzy fallback (Damerau-Levenshtein)
│
▼
2. Cosine similarity re-ranking (if embeddings available)
│
▼
3. Scope filtering (if tags match)
│
▼
4. Supersession filtering (remove obsolete facts)
│
▼
5. Sort by score, return top N📊 Benchmark results
Tested against PrecisionMemBench — 77 retrieval scenarios across alias resolution, fuzzy matching, scope isolation, noise resistance, supersession chains, and budget constraints.
Score: 54 / 77 ✅ (70% passing)
Phase | Passing | Δ |
Base keyword search | 9 / 77 | — |
Hybrid keyword + cosine | 42 / 77 | +33 |
+ Damerau-Levenshtein fuzzy | 43 / 77 | +1 |
+ Scope filtering | 49 / 77 | +6 |
+ Supersession filtering | 54 / 77 | +5 |
What passes (54 tests)
Category | Tests |
Alias resolution | k8s → Kubernetes, GHA → GitHub Actions, ReactJS → React, POV → point of view, DLQ → dead letter queue, base class → composition-inheritance, exceptions → error handling, 2-word shingles |
Exact match | repository-layer, canonical name, long query (400+ chars) |
Scope filtering | Redis-in-writing returns character not datastore, code-scope doesn't leak writing, cross-scope blocked, user-edited respects scope, scope bleed protection |
Supersession | SQLAlchemy superseded by MongoDB hidden, TSLint→ESLint→Biome chain resolves to terminal, resolved_at beliefs excluded, pinned+resolved excluded from questions |
Fuzzy matching | All-caps case-insensitive (REACTJS), typo prefix guard, scope-aware fuzzy filtering |
Messy queries | Filler-heavy extraction, compound surfaces 2 beliefs, negation still surfaces topic, all-caps case insensitive |
Budget/limits | Ceiling eviction, zero graceful, one pinned wins, recency tiebreak |
Edge cases | Cold start, empty query, whitespace query, short query passthrough, short query score clears, empty alias content path |
User isolation | Other-user beliefs never leak |
Universal scope | Persona prelude, explicit query with no relevant, zero-reinforcement fresh belief surfaces |
What fails (23 tests) — root causes
Cause | Tests | Why |
Token bleeding | 8 | Generic query tokens match too many facts (e.g. "kube" finds multiple) |
Relation expansion | 4 | "auth depends on redis" — not yet implemented |
Cap stress | 3 | 6+ entities in single query needs NLP extraction |
Ranking weights | 2 | canonical_name should outrank content match |
Multi-scope Redis | 2 | Redis in both code+writing scopes needs per-scope dedup |
Fuzzy edge cases | 2 | k9s vs k8s prefix guard, single-edit with token bleed |
Other | 2 | why_it_matters not indexed, type isolation routing |
Comparison with other providers
Provider | Passing | Precision | Dependencies |
tenure (reference) | 77 / 77 | 1.00 | MongoDB Atlas Search (BM25, shingles, fuzzy) |
ctrl-memory | 54 / 77 | ~0.70 | Zero external deps |
okf | ~30 / 77 | ~0.47 | PostgreSQL |
supermemory | ~21 / 77 | ~0.22 | Supabase + API |
yourmemory | ~21 / 77 | ~0.17 | MongoDB |
mem0 | ~9 / 77 | ~0.06 | Qdrant + API |
Second place among all tested providers. ctrl-memory achieves this with zero external dependencies — no databases, no APIs, no cloud services.
🧪 Development
# Clone
git clone https://github.com/ctrl-alt-dev/ctrl-memory
cd ctrl-memory
# Setup
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[embeddings]"
# Test
python3 -m unittest discover tests -v
# Run benchmark
cd /tmp
git clone https://github.com/tenurehq/precisionMemBench
cd precisionMemBench
MEMORY_PROVIDER=ctrl-memory CTRL_MEMORY_URL=http://localhost:8000 \
RESEED=true npx ava src/retrieval.external.eval.test.ts --timeout 10mTest suite
File | Tests | What it covers |
| 23 | JSON store CRUD, search, user isolation |
| 25 | SQLite store CRUD, search, embeddings |
| 24 | MCP protocol, JSON-RPC, tool dispatch |
| 24 | Embedding engine, cosine similarity |
| 24 | Plugin lifecycle, tools, prefetch |
116 tests total (105 run, 11 skip without sentence-transformers).
📄 License
MIT
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
- 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/ctrlProgrammer/ctrl-memory-system'
If you have feedback or need assistance with the MCP directory API, please join our Discord server