
CPersona
β 2from Cloto-dev
Persistent AI memory server with 3-layer hybrid search, confidence scoring, and 16 tools. Zero LLM dependency.
cpersona
MCP Memory Server
Give Claude persistent memory across sessions. Single SQLite file. 27 tools. Zero LLM dependency.
Quick Start Β· Features Β· Architecture Β· All Tools Β· Zenn Book (JP)
</div>Standalone repository β This is the standalone version for use with Claude Desktop, Claude Code, and any MCP client. If you are a ClotoCore user, install CPersona from the in-app marketplace (ClotoHub) instead β it distributes this same repository.
Project status (July 2026) β Accuracy-improvement work on the 2.4 series is complete (RRF fusion, per-agent threshold calibration, recall-precision control, channel/project isolation). The remaining 2.4.x releases are stabilization only β bug fixes, health-check hardening, and performance repairs β after which 2.4 will be declared stable. New feature development moves to the 2.5 series.
The Problem
Claude forgets everything between sessions. Every conversation starts from zero β no context about your project, your preferences, or what you discussed yesterday.
cpersona fixes this. It's an MCP server that stores memories in a local SQLite file and retrieves them through hybrid search. Claude remembers you.
Features
Hybrid Search β Three independent retrieval strategies run in parallel and merge results via Reciprocal Rank Fusion (RRF):
| Layer | Method | Strength |
|---|---|---|
| Vector | Cosine similarity (jina-v5-nano, 768d) | Semantic meaning |
| FTS5 | SQLite full-text search with trigram tokenizer | Exact terms, names, IDs |
| Keyword | Fallback pattern matching | Edge cases, partial matches |
Memory Types:
- Declarative memory β Individual facts, decisions, instructions stored via
store - Episodic memory β Conversation summaries archived via
archive_episode - Profile memory β Accumulated user/project attributes via
update_profile
Confidence Scoring β Each recalled memory gets a confidence score combining:
- Cosine similarity (semantic relevance)
- Dynamic time decay (adapts to corpus time range β a 1-year-old corpus and a 1-day-old corpus use different decay curves)
- Recall boost (frequently useful memories surface more easily, with natural fade-out)
- Completion factor (resolved topics decay faster)
Zero LLM Dependency β cpersona is a pure data server. It never calls an LLM internally. All summarization and extraction is performed by the calling agent. This means zero API costs from cpersona itself, deterministic behavior, and no hidden latency.
Additional capabilities:
- Agent namespace isolation β multiple agents share one DB without interference
- Background task queue β DB-persisted, crash-recoverable async processing
- JSONL export/import β full memory portability between environments
- Agent-to-agent memory merge β atomic copy/move with deduplication
- Auto-calibration β statistical threshold tuning via null distribution z-score (no labels needed)
- Health check β 16 automated detections with auto-repair (contamination, duplicates, FTS desync, invalid data, stale tasks, empty content, invalid sources)
- Deep check β semantic data quality analysis (anonymous source recovery, short content, stale profiles, orphaned episodes)
- Memory protection β lock/unlock to prevent accidental deletion or editing
- Recent recall penalty β suppresses echo chamber effect for frequently recalled memories
- stdio + Streamable HTTP transport
- Single-file SQLite β no external database required
Architecture
βββββββββββββββββββββββββββββββββββββββ
β MCP Host β
β (Claude Desktop / Claude Code) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β MCP (JSON-RPC)
ββββββββββββββββΌβββββββββββββββββββββββ
β cpersona β
β (server.py) β
β β
β βββββββββββ βββββββββββ β
β β store β β recall β ... β
β ββββββ¬βββββ ββββββ¬βββββ β
β β β β
β ββββββΌββββββββββββββΌβββββββββββββ β
β β SQLite DB β β
β β β β
β β memories (content + embed) β β
β β episodes (summaries) β β
β β profiles (attributes) β β
β β memories_fts (FTS5 index) β β
β β episodes_fts (FTS5 index) β β
β β task_queue (async jobs) β β
β ββββββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββ¬ββββββββββββββββββββββββ
β HTTP
ββββββββββββββββΌβββββββββββββββββββββββ
β Embedding Server β
β (jina-v5-nano ONNX, 768d) β
βββββββββββββββββββββββββββββββββββββββRecall flow (RRF mode):
Query β βββ Vector search (cosine similarity) βββ
βββ FTS5 search (episodes + memories) βββΌββ RRF merge β Confidence scoring β Top-K
βββ Keyword fallback βββBenchmarks
Tested on LMEB (Long-term Memory Evaluation Benchmark) β 22 evaluation tasks measuring memory retrieval quality:
| Embedding Model | Params | Dimensions | Mean NDCG@10 |
|---|---|---|---|
| MiniLM-L6-v2 | 22M | 384 | 36.88 |
| e5-small | 33M | 384 | 46.36 |
| jina-v5-nano | 33M | 768 | 54.14 |
jina-v5-nano achieves +47% improvement over the MiniLM baseline.
All Tools
| Tool | Description |
|---|---|
store | Store a message in agent memory |
recall | Recall relevant memories (vector + FTS5 + keyword, RRF merge) |
recall_with_context | Recall with external conversation context (auto-dedup) |
get_profile | Get current agent profile |
update_profile | Save pre-computed agent profile |
archive_episode | Archive conversation episode with summary and keywords |
list_memories | List recent memories |
list_episodes | List archived episodes |
update_memory | Update memory content (rejects if locked) |
lock_memory | Lock memory to prevent deletion/editing |
unlock_memory | Unlock memory to allow deletion/editing |
delete_memory | Delete a single memory (ownership enforced) |
delete_episode | Delete a single episode (ownership enforced) |
delete_agent_data | Delete all data for an agent |
calibrate_threshold | Auto-calibrate vector search threshold via z-score |
set_recall_precision | Set an agent's recall precision (knob 3) and recalibrate its gate |
get_recall_precision | Read an agent's effective recall precision (knob 3) |
pause_persistence | Turn writes into no-ops for an opt-in TTL window |
resume_persistence | Re-enable persistence immediately |
persistence_status | Report whether persistence is paused and the TTL remaining |
migrate_channel_axis | Re-channel bridge-type memories to their concrete channel |
export_memories | Export to JSONL (memories, episodes, profiles) |
import_memories | Import from JSONL (idempotent via msg_id dedup) |
merge_memories | Merge one agent's data into another (atomic, with dedup) |
get_queue_status | Background task queue status |
check_health | Registry-driven health check (severity-tagged issues) with auto-repair |
deep_check | Deep semantic data quality analysis with auto-repair |
Stats
- ~5,600 LOC Python across focused modules
- 146 tests across 12 test modules
- Schema v10 (auto-migrating)
- MIT License
Works With
cpersona is an MCP server β it works with any MCP-compatible host:
- Claude Desktop
- Claude Code
- ClotoCore (AI agent platform, where cpersona originated)
- Any custom MCP client
Part of ClotoCore
cpersona is the memory layer of ClotoCore, an open-source AI agent platform written in Rust. While cpersona is fully standalone (MIT license), it was designed to give AI agents persistent, searchable memory within the ClotoCore ecosystem.
Learn More
- Zenn Book (Japanese) β Full design walkthrough and setup guide
- Memory System Design β Technical specification
- ClotoCore β The AI agent platform
License
MIT β free to use from any MCP host without restriction.
</div>git clone https://github.com/Cloto-dev/cpersona.git
cd cpersona
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install .Before it works, you'll need: EMBEDDING_PROVIDEREMBEDDING_HTTP_PORT
Quick Start
Prerequisites: Python 3.11+ (and uv for the one-command path).
1. Install cpersona
uvx cpersona # run directly, no install step
# or
pip install cpersona # then the `cpersona` command is on your PATHgit clone https://github.com/Cloto-dev/cpersona.git
cd cpersona
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install .Run it with python -m cpersona (or python server.py).
2. Set up Embedding Server (Recommended)
cpersona's hybrid search works best with an embedding server for vector similarity. cpersona is embedding-server-agnostic: point CPERSONA_EMBEDDING_URL (see step 3) at any HTTP endpoint that implements the following minimal contract.
POST /embed
Request: { "texts": ["string", ...] } # non-empty array, max 100 per batch
Response: { "embeddings": [[float, ...], ...], "dimensions": <int> }The reference server is CEmbedding (MIT) β it runs jina-v5-nano on-device (CPU) and exposes exactly this endpoint:
git clone https://github.com/Cloto-dev/CEmbedding.git && cd CEmbedding
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install ".[onnx]"
python download_model.py --model jina-v5-nano
EMBEDDING_PROVIDER=onnx_jina_v5_nano python server.py # serves http://127.0.0.1:8401/embedcpersona was tuned and benchmarked against jina-v5-nano (33M params, 768d), so CEmbedding reproduces the numbers below. Any other server that satisfies the contract above works too.
Without an embedding server, cpersona falls back to FTS5 + keyword search only. Vector search (the strongest retrieval layer) will be disabled.
3. Configure your MCP client
Claude Desktop β add to claude_desktop_config.json:
{
"mcpServers": {
"embedding": {
"command": "/path/to/.venv/bin/python",
"args": ["/path/to/servers/embedding/server.py"],
"env": {
"EMBEDDING_PROVIDER": "onnx_jina_v5_nano",
"EMBEDDING_HTTP_PORT": "8401"
}
},
"cpersona": {
"command": "uvx",
"args": ["cpersona"],
"env": {
"CPERSONA_DB_PATH": "/home/you/.claude/cpersona.db",
"EMBEDDING_MODE": "http",
"EMBEDDING_HTTP_URL": "http://127.0.0.1:8401/embed"
}
}
}
}Windows: use
C:/Users/you/.claude/cpersona.dbfor the DB path. No embedding server yet? Drop the twoEMBEDDING_*lines (or setEMBEDDING_MODE=none) β cpersona runs on FTS5 + keyword and tells you when it's degraded.
Claude Code:
claude mcp add-json cpersona '{"type":"stdio","command":"uvx","args":["cpersona"],"env":{"CPERSONA_DB_PATH":"/home/you/.claude/cpersona.db","EMBEDDING_MODE":"http","EMBEDDING_HTTP_URL":"http://127.0.0.1:8401/embed"}}' -s user(The embedding server in step 2 is registered separately; it is currently installed from source.)
That's it. Claude now has persistent memory. Ask it to store something and recall it in a later session.
Configuration
All settings via environment variables with sensible defaults:
| Variable | Default | Description |
|---|---|---|
CPERSONA_DB_PATH | ./cpersona.db | SQLite database path |
CPERSONA_EMBEDDING_MODE | http | Embedding mode (http or disabled) |
CPERSONA_EMBEDDING_URL | http://127.0.0.1:8401/embed | Embedding server URL |
CPERSONA_VECTOR_SEARCH_MODE | remote | Vector search mode |
CPERSONA_RECALL_MODE | rrf | Recall fusion strategy (rrf, rsf, or cascade) |
CPERSONA_RRF_K | 60 | RRF smoothing parameter |
CPERSONA_CONFIDENCE_ENABLED | false | Include confidence metadata in results |
CPERSONA_AUTO_CALIBRATE | false | Auto-calibrate on startup |
CPERSONA_TASK_QUEUE_ENABLED | false | Enable background task queue |
CPERSONA_RECENT_RECALL_PENALTY | 0.7 | Penalty for recently recalled memories |
CPERSONA_RECENT_RECALL_WINDOW_MIN | 5 | Window (minutes) for recent recall penalty |
Recall fusion mode (CPERSONA_RECALL_MODE)
rrf(default) β Reciprocal Rank Fusion: merges the vector + FTS channels by rank only. Robust and scale-free, but discards score magnitude.rsfβ Relative Score Fusion: per-query min-max-normalizes each channel's raw score (cosine for vector, bm25 for keyword) and sums them, so the keyword channel's bm25 magnitude survives the merge. Recommended for topic-drift-prone or space-less language (e.g. Japanese) contexts, where that magnitude is the discriminating signalrrfflattens away (β Weaviate'srelativeScoreFusion; see the ClotoCoreRECALL_CONTAMINATION_AB_2026-06-14report Β§10β12). Caveat: min-max normalization can over-cut small, closely-scored result sets whenautocutis enabled βrrfremains the default until that interaction is hardened.cascadeβ Sequential channel fill (legacy).
No common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.