ctrl-memory

ctrl-memory

A lightweight, local-first MCP memory server for LLM agents that enables storing, searching, and retrieving agent memories with zero external dependencies.

Category
访问服务器

README

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-transformers for cosine similarity ranking
  • Hybrid 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

🚀 Quick start

One-liner install (recommended)

curl -fsSL https://raw.githubusercontent.com/ctrlProgrammer/ctrl-memory-system/main/install.sh | bash

This 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-mcp

Manual 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-mcp

The 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-mcp

In 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-mcp separately. 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>.json
  • Auto-increment IDs, append-only writes
  • Best for: MVP, personal use, <1000 facts

SQLite backend

  • Single .db file with WAL mode
  • Indexed 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_score threshold 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.db

The plugin provides:

  • Automatic prefetch — relevant context injected before every LLM turn
  • Turn capture — facts extracted from conversations and stored
  • 4 toolsadd_memory, search_memory, delete_memory, memory_status

🔧 MCP tools

Tool Description
add_memory Store a new fact with optional metadata tags
search_memory Hybrid keyword + semantic search
get_fact Retrieve a specific fact by ID
list_facts List all facts for a user with pagination
update_fact Edit an existing fact (re-embeds if semantic enabled)
delete_fact Remove a fact (cleans up embedding)
count_facts Get total fact count for a user
search_memory_semantic 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 10m

Test suite

File Tests What it covers
test_memory_backend.py 23 JSON store CRUD, search, user isolation
test_sqlite_store.py 25 SQLite store CRUD, search, embeddings
test_mcp_server.py 24 MCP protocol, JSON-RPC, tool dispatch
test_embeddings.py 24 Embedding engine, cosine similarity
test_hermes_provider.py 24 Plugin lifecycle, tools, prefetch

116 tests total (105 run, 11 skip without sentence-transformers).


📄 License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选