The FTS5 and keyword layers catch what embeddings miss — identifiers, error strings, exact names — and the trigram index means it works on Japanese and other scripts without spaces. Isolation is built in: agent_id, project_id and channel let several agents share one file without reading each other's memories.
An MCP memory server. It stores facts, session summaries and an accumulated profile in one local SQLite file and retrieves them with a fused vector, FTS5 and keyword search. It never calls a generative model itself — your agent writes the summary and hands over the result.
- store, recall and recall_with_context — write a message to memory, search it with the fused strategies, or merge the results with the current conversation in one deduplicated, chronological list
- get_contents — expand only the rows worth reading after a preview-tier recall, instead of pulling every full body
- get_profile and update_profile — read and save the accumulated profile for an agent
- archive_episode, list_episodes and list_memories — file a conversation episode with its summary and keywords, and list what is stored
- update_memory, delete_memory, delete_episode, lock_memory and unlock_memory — edit and remove rows, or lock one against both
- calibrate_threshold, set_recall_precision and get_recall_precision — calibrate the vector threshold from the random-pair distribution, and set recall to strict, balanced or lenient
- check_health and deep_check — a 25-check registry flagging contamination, duplicates, oversized content and FTS problems, plus a heuristic pass for stale profiles and orphaned episodes
- export_memories, import_memories and merge_memories — JSONL backup and restore, deduplicated by message id, and a one-shot merge from one agent into another
- pause_persistence, resume_persistence and persistence_status — suspend every write for a TTL window and check whether it is active
- delete_agent_data, get_queue_status and migrate_channel_axis — remove one agent's data, inspect the background task queue, and re-file bridge-type memories onto their concrete channel
Python 3.11 or newer; clients run it with uvx cpersona over stdio. Point CPERSONA_DB_PATH at an absolute path so the database does not follow the client's working directory. Vector search needs an embedding server: set CPERSONA_EMBEDDING_MODE to http and CPERSONA_EMBEDDING_URL to its endpoint — without one it falls back to the lexical layers and says so. CPERSONA_RECALL_MODE picks the fusion strategy, rrf by default.
One command — uvx cpersona
