Tools¶
Applies to: CPersona 2.5.x. The authoritative description of every argument is the tool's own MCP description: your client reads it, and it ships with the version you are running. This page groups every tool by what you use it for, and links to the contract whenever a tool behaves in a way its name does not suggest.
Everyday memory¶
| Tool | What it does |
|---|---|
store |
Write one message to memory. Branch on result — stored / skipped / rejected — not on ok (dedup contract) |
recall |
Retrieve memories through the three-layer hybrid search. The last element is the best match (ordering contract) |
recall_with_context |
Recall and merge with conversation history you pass in, deduplicated. Returns a chronological merge, not a score ordering |
get_contents |
Expand preview refs (mem:<id> / ep:<id>) returned by recall into full text (preview tier design) |
archive_episode |
Store a session summary. Also moves the episode boundary, which down-weights everything written before it |
update_memory |
Correct the content of an existing memory. Use this, not a re-store with the same msg_id |
Profile and operator context¶
| Tool | What it does |
|---|---|
get_profile |
Read the accumulated user/project profile for an agent |
update_profile |
Replace the profile with a summary you computed. CPersona never writes it for you — see zero LLM dependency |
get_operating_context |
Read the operator-owned instructions served to every connected client. Read-only over MCP; edited on the filesystem (design) |
Profile rows are injected into recall responses but
carry no score. That
matters when you tighten limit.
Browsing¶
| Tool | What it does |
|---|---|
list_memories |
Recent memories, newest first — no search, no scoring |
list_episodes |
Archived episodes, newest first |
get_queue_status |
Depth and retry state of the background task queue |
Protection and deletion¶
| Tool | What it does |
|---|---|
lock_memory |
Refuse edits and deletes on a memory. It is protection, not a ranking boost (contract) |
unlock_memory |
Lift that protection |
delete_memory |
Delete one memory. Ownership is enforced only when agent_id is passed — omit it and the delete is unscoped and can remove another agent's row (rejected while locked either way) |
delete_episode |
Delete one episode. Same conditional ownership as delete_memory above |
delete_agent_data |
Delete everything belonging to one agent. It is exposed over the network like any other tool, which is reason enough to set CPERSONA_AUTH_TOKEN on the HTTP transport |
Retrieval quality¶
| Tool | What it does |
|---|---|
set_recall_precision |
The main gate knob. Sets an agent's precision preference and recalibrates its post-fusion quality gate — reach for this before touching raw thresholds (tuning order) |
get_recall_precision |
Read the effective precision for an agent |
calibrate_threshold |
Re-derive the vector threshold from the corpus itself. The default method (separation) finds where a null distribution of random pairs separates from same-session positives; percentile and zscore are the alternatives. No labels needed. Run it after a re-embed or a large import |
Portability and migration¶
| Tool | What it does |
|---|---|
export_memories |
Write memories, episodes and profiles to JSONL. It is schema-version independent, so it doubles as a logical backup (backup runbook) |
import_memories |
Read that JSONL back. Idempotent, though not by one key: memories dedup on msg_id and on identical content within the project/channel scope, while episodes dedup on an identical summary (they carry no msg_id) |
merge_memories |
Move or copy one agent's data into another, atomically and with deduplication |
migrate_channel_axis |
Re-channel bridge-type memories onto their concrete channel. A one-time repair, not a routine operation |
Health and maintenance¶
| Tool | What it does |
|---|---|
check_health |
Registry-driven check with severity-tagged issues and, with fix=true, auto-repair: contamination, duplicates, FTS integrity, embedding-dimension drift, schema objects, stale tasks, invalid data. Some checks are report-only by design, isolation-axis hygiene among them: which spelling of an axis is canonical is an operator's call, not a repair |
deep_check |
Semantic data-quality pass: anonymous sources, too-short content, stale profiles, orphaned episodes |
get_session_findings |
The same findings, pulled on demand. This is the SuperAuditor pull contract (standard). Whole-database by design (no agent or project filter), read-only, with capped_kinds naming every kind that had more than per_kind_limit rows. A probe that raised shows up as a finding of kind check_crashed rather than failing the call |
check_health and deep_check are also reachable outside MCP, as
python -m cpersona.checkup. That is the form to use in CI. Cadence guidance
is in the operations runbook.
The package installs one other command, which is not a tool at all: cpersona-policy
(equivalently python -m cpersona.policy) prints the always-loaded policy block, and
installs it into the instructions file your client reads every session. It is described
where it is used, in Getting Started §5.
Server version¶
| Tool | What it does |
|---|---|
check_update |
Whether a newer release of the server itself exists, or whether the release you are running has been withdrawn (PyPI yank) — something an installed server can otherwise never learn. The check runs once per process start and is cached for 24h; this tool reads that verdict, refresh=true re-fetches, and apply=true runs the update (pip and source-checkout installs only) |
The same verdict rides on recall as an update key, once per session and
absent when there is nothing to say. It also appears in check_health as an
update_available (info) or version_yanked (warn) issue.
Nothing is ever installed as a side effect. apply=true is the only thing
that installs anything, and a restart is always required afterwards,
because the process that ran the install is still running the old code.
Two setups are declined, each with a reason. Under uvx, the environment is a
cache entry keyed by the launch arguments, so the change belongs in your MCP
client's config (uvx cpersona@latest). A source checkout that is not on a
branch — a clone parked at a release tag, which is a normal way to deploy one
— is declined too: git pull has nothing to fast-forward from a detached
HEAD. The tool refuses before running anything and answers with the
git fetch --tags && git checkout <tag> form to use instead.
CPERSONA_UPDATE_CHECK=false disables the feature entirely, including the one
outbound request (what it sends).
Session controls¶
| Tool | What it does |
|---|---|
pause_persistence |
Turn writes into no-ops for a TTL window. Responses carry persisted: false; branch on that, not on an id |
resume_persistence |
Re-enable writes immediately |
persistence_status |
Whether writes are paused, and how much TTL remains |
Use these for benchmarking, or for throwaway exploration you do not want in the corpus.
The blast radius follows session_key, which each of the three tools
reports back as scope. Declare a key on the pause and on the write calls it
should cover, and the pause covers that key alone (scope: "session"). A
session sending a different key is neither silenced by it nor able to clear it.
The key is compared, never verified, so it partitions keys rather than callers:
anyone sending the same string shares the pause.
Omit the key and you arm the bucket that every keyless caller shares
(scope: "process"). Under stdio, where the client owns its own process, that
bucket is the session. On a streamable-HTTP deployment one process serves every
client, so a keyless pause silences writes for every other keyless session —
and those sessions are not told.
Two paths do not fit the persisted: false shape. check_health and
deep_check are not blocked, but downgrade to fix=false.
migrate_channel_axis is forced into dry-run and reports repairs_skipped,
with no persisted key at all.
Isolation arguments¶
The three isolation axes are not offered uniformly. agent_id is accepted by
most tools (22), project_id by six, and channel by exactly four: store,
recall, recall_with_context and archive_episode.
They are independent axes rather than one nested hierarchy, and reads treat an empty value differently from an omitted one. See isolation axes.