CPersona
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CPERSONA_RRF_K | No | RRF smoothing parameter | 60 |
| CPERSONA_DB_PATH | No | SQLite database path | ./cpersona.db |
| CPERSONA_SEARCH_MODE | No | Search strategy (`rrf` or `cascade`) | rrf |
| CPERSONA_EMBEDDING_URL | No | Embedding server URL | http://127.0.0.1:8401/embed |
| CPERSONA_AUTO_CALIBRATE | No | Auto-calibrate on startup | false |
| CPERSONA_EMBEDDING_MODE | No | Embedding mode (`http` or `disabled`) | http |
| CPERSONA_CONFIDENCE_ENABLED | No | Include confidence metadata in results | false |
| CPERSONA_TASK_QUEUE_ENABLED | No | Enable background task queue | false |
| CPERSONA_VECTOR_SEARCH_MODE | No | Vector search mode | remote |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| pause_persistenceA | Pause write operations on this MCP server for an opt-in TTL window (default 1800 seconds, at most 86400). While paused, every write tool — store, declare_associations, archive_episode, update_memory, delete_memory, delete_episode, delete_agent_data, lock_memory, unlock_memory, update_profile, import_memories, merge_memories, calibrate_threshold, set_recall_precision — returns a no-op response carrying |
| resume_persistenceA | Re-enable persistence immediately, clearing this caller's active no-persist TTL. Returns was_active=true if THIS bucket was paused before the call. It clears only the bucket session_key selects (response |
| persistence_statusA | Report whether persistence is currently paused and the TTL remaining (in seconds). It reports the bucket session_key selects (response |
| get_operating_contextA | Read the server-served operating context (v2.5.1): the operator-owned doctrine distributed to every connected client. Without arguments returns the preview tier — context_revision, instructions_summary, project_id registry (+ enforce mode), @auto defaults, and doctrine section names. Pass section to fetch one section's full body. Read-only: the context is edited by the operator on the filesystem (~/.cpersona/operating-context.toml), never via MCP. |
| storeA | Store a memory for future recall: put the text in content. agent_id may be omitted on a connection that can write to exactly one agent (the agent used is echoed as resolved_agent_id), and source defaults to that agent. lock:true also locks the memory, as lock_memory does, and the response says locked:true|false. Every response carries result, the one field to branch on: 'stored' (a new row: id, and embedded, whether a vector was kept; truncated:true when content was shortened to the length cap; nodes:{status:'queued'} when the text runs past the embedding window and its overflow-tree nodes were queued), 'skipped' (nothing written and nothing wrong: a duplicate id, or content already stored under the same source id, echoes the existing row's id, except reason='duplicate (unique index)', a concurrent-write race, which has none), or 'rejected' (ok:false, nothing written; reason is human-readable, not a stable token). Under pause_persistence the write is skipped and the response carries persisted:false (id:'no-persist'), which tells a paused write from a duplicate. The older message={content, id, source, timestamp, metadata} form still works; use it or the top level, not both. |
| declare_associationsA | Declare associative memory after the fact: entities with aliases, and subject–predicate–object relations, recorded verbatim and walked by reconstruct. The server extracts nothing and infers nothing — coverage is exactly what was declared. |
| traverseA | The neighbourhood of a declared entity, as a graph: the entity named, its aliases, the entity -> entity relations declared on it and on what they reach, up to |
| recallA | Recall memories by multi-strategy search (vector + FTS5 + keyword). To answer a question from memory, prefer |
| recall_with_contextA | Recall memories and merge with external conversation context. Automatically deduplicates, sorts chronologically, and returns a unified list. Replaces separate recall + manual merge in the caller. Content is preview-tiered by default — see recall's full_content / get_contents (full_content shares recall's 200k-char response budget, bug-211); a recalled row the preview cut carries excerpt / excerpt_basis as recall's do. Every external_context entry's content filters the recall (the caller already holds that text), but only role=user / role=assistant entries are merged into messages. When entries of other roles are present the response carries context_filter_only={roles:[...]} — those entries filtered the recall without appearing in the output, whether or not they dropped a memory this time. context_field_issues={entries:[{index, fields}]} (absent otherwise) names entries whose declared field was not a string: it was read as absent and the entry merged without it. CPERSONA_EXTERNAL_CONTEXT_MODE=reject refuses such a call instead. gate_fallback=true (absent otherwise) is forwarded from the underlying recall: every candidate fell below the quality gate and the below-gate lexical matches were returned — treat them as low-confidence. Only CPERSONA_CONFIDENCE_ORDERING=legacy with confidence on does that; otherwise such a recall contributes no rows. |
| get_contentsA | Fetch full, untrimmed content for recall preview refs. Use after a preview-tier recall to expand only the rows that matter instead of opting the whole recall out with full_content=true. Bounded twice: at most 20 refs per call, and a 40,000-character budget across the batch (2.5.4a2) that does not move when CPERSONA_MAX_CONTENT_LENGTH does. Rows are never cut to fit — when the budget is spent the remaining refs come back in |
| reconstructA | The recommended way to answer a question from memory. Returns up to |
| get_profileC | Get the current profile for an agent. |
| update_profileA | Save a pre-computed agent profile to the database. The text passes through the same sanitizer as store, against the profile's own ceiling: it is capped at 2000 characters (CPERSONA_MAX_PROFILE_LENGTH) and the response carries truncated:true when the cap bit — branch on it, the discarded remainder is not stored anywhere else. |
| archive_episodeA | Archive a conversation episode with pre-computed summary, keywords, and resolved status. All LLM processing is performed by the caller. A summary that runs past the embedding window adds nodes:{status:'queued'} to the response, as on store. |
| list_memoriesA | List recent memories for an agent (for dashboard display). bug-385: |
| list_episodesA | List archived episodes for an agent (for dashboard display). bug-385: |
| delete_agent_dataA | Delete ALL data (memories, profiles, episodes) for a specific agent. Used by kernel during agent deletion. |
| calibrate_thresholdA | Auto-calibrate the vector search threshold from the null (random-pair) cosine distribution. Samples random memory pairs and places the threshold ABOVE the null mean so unrelated pairs are rejected. method='separation' (default) learns the operating point from two populations — null pairs vs temporally-adjacent same-session positives (nearest-neighbour fallback when too few exist); method='percentile' uses a quantile of the null distribution (robust to anisotropic models such as bge-m3); method='zscore' uses mean + z*std. No labels used, purely statistical. Adapts to both embedding model and corpus characteristics. |
| set_recall_precisionA | Set an agent's recall precision (knob 3) and recalibrate its quality gate. precision = strict | balanced | lenient maps to a specificity weight beta of 2.0 / 1.0 / 0.5 in the gate separation objective (sensitivity + beta*specificity): strict sits the gate higher (fewer contaminants, more misses), lenient lower (fewer misses, more contaminants). A raw beta > 0 overrides the named level; an empty precision with beta <= 0 clears the per-agent override and returns the agent to the global CPERSONA_RECALL_PRECISION default. The gate is recalibrated at the new beta immediately and persisted, so the change is live without a restart. Precision is a per-agent setting, not a per-recall argument: the gate threshold is precomputed on the separation curve at a fixed beta, so this tool recalibrates once instead. |
| get_recall_precisionA | Read an agent's effective recall precision (knob 3) — the read-back companion to set_recall_precision. Returns the resolved specificity weight (beta) and its named precision level (strict / balanced / lenient, or 'custom' for a raw beta), and flags whether the value is a per-agent override or the global CPERSONA_RECALL_PRECISION default (overridden + global_precision / global_beta). Read-only: it never recalibrates and never persists, so a UI can load the current setting, let the user edit it, and write it back instead of the control being write-only. |
| delete_memoryB | Delete a single memory by ID. Ownership is enforced when agent_id is provided. |
| delete_episodeA | Delete a single episode by ID. Ownership is enforced when agent_id is provided. |
| update_memoryA | Update memory content by ID. Rejects if memory is locked. Ownership enforced when agent_id provided. The new content passes through the same sanitizer as store: it is capped at the content length limit (the response carries truncated:true when the cap bit) and [Memory from ...] annotations are stripped, so content consisting only of those is refused rather than written as an empty row. A new text that another memory in the same agent, project and channel already holds is refused with ok:false naming that memory, since one copy is kept per bucket. A new text that runs past the embedding window gets nodes:{status:'queued'}, as on store. |
| lock_memoryA | Lock a memory to prevent deletion and editing (delete_memory, update_memory). Operator re-scoping (migrate_channel_axis, merge_memories move) still relocates it, lock kept; delete_agent_data removes it. Ownership enforced when agent_id provided. |
| unlock_memoryA | Unlock a memory to allow deletion and editing. Ownership enforced when agent_id provided. |
| get_queue_statusA | Get the status of the background task queue (pending tasks, retry config). |
| export_memoriesA | Export memories, episodes, profiles and declared associations (entities, aliases, mentions, relations) to a JSONL file for backup or portability. |
| import_memoriesA | Import memories, episodes, profiles and declared associations from a JSONL file; the associations are pointed at the records they name as restored. Idempotent: memories deduplicate on msg_id (and on content within a project/channel), episodes on their summary within a project/channel. |
| merge_memoriesA | Merge memories, episodes, profiles and declared associations from one agent into another. Atomic one-shot equivalent of export→import without intermediate files. Strategy 'skip' deduplicates by msg_id (memories) and summary (episodes). |
| check_healthA | Check memory database health (38-check registry, each issue tagged critical/warn/info): contamination, duplicates, oversized content, embeddings, FTS and schema integrity, SQLite file integrity, naming, JSON and timestamp drift, stale tasks, profiles and sources. Returns storage stats with project_id/channel distributions. The verdict is |
| get_session_findingsA | Pull the storage-integrity findings on demand (the SuperAuditor pull contract, docs/SUPERAUDITOR_STANDARD.md) instead of reading them off check_health: the same detector as check_health(fix=false) over the WHOLE database. Read-only, never repairs. Each finding carries |
| deep_checkA | Deep heuristic analysis of memory data quality. Detects issues requiring recovery or judgment (anonymous sources, short/trivial content, stale profiles, orphaned episodes, stale threshold calibration, embedding-space near-duplicate pairs as merge candidates). fix=true applies repairs for: anonymous_source, short_content. The short_content repair deletes every unlocked row it reports; run without fix first and read its samples. Report-only (fix is accepted and ignored): stale_profile, orphaned_episodes, calibration_staleness, near_duplicate, unnormalized_content, embedding_norm — apply those decisions via merge_memories / delete_memory / calibrate_threshold / update_profile. Use checks parameter to select specific checks. |
| migrate_channel_axisA | Re-channel bridge-type memories to their concrete channel (knob2 v2 default flip prep). Memories the kernel filed under the bridge type ('discord') are rewritten to the concrete channel recovered from the stored session_id ('{channel_id}:{user_id}:{chunk}' | '{channel_id}:shared' → channel_id), so per-channel recall can match them. Non-destructive (only the channel column changes) and idempotent (re-running is a no-op once moved). dry_run=true (default) reports the recoverable count, the channels that would be recovered, and an unrecoverable bucket (channel='discord' rows with no snowflake session_id) without mutating. globalize_unrecoverable=true moves the unrecoverable bucket to channel='' (global, matched by every channel-scoped recall) so the flip orphans nothing; default false (report only). |
| check_updateA | Report whether a newer release of this server exists, and — only if you ask — install it. The check itself runs ONCE per process start, in a background task that nothing waits on, and its verdict is cached for 24h (CPERSONA_UPDATE_CHECK_INTERVAL_SECONDS) in a file beside the database; a bare call here reads that verdict and reaches neither the network nor the disk. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 34 tools
Most tools target distinct resources or actions, but several families have subtle boundaries: recall, recall_with_context, and reconstruct all retrieve memories, while check_health, deep_check, and get_session_findings all report diagnostics. The detailed descriptions explicitly steer between them, but an agent must read carefully to choose correctly.
All tool names use snake_case and most follow a verb_noun pattern such as get_profile, update_memory, delete_episode, and check_health. A few are bare verbs (store, recall, reconstruct, traverse) or noun-like (persistence_status), so the convention is readable but not perfectly uniform.
At 34 tools, the surface is well above the typical well-scoped range, mixing core memory operations with many niche admin, diagnostic, and maintenance tools such as check_update, get_queue_status, migrate_channel_axis, and pause/resume persistence. The breadth may reflect a mature backend, but it is heavy for an MCP server and increases selection cost.
The core memory lifecycle is well covered: store, update, delete, lock/unlock, list, recall/reconstruct, profiles, episodes, declared associations, import/export/merge, and health diagnostics. Minor gaps remain, such as no dedicated get/update for a single episode and no queue-management operations, but agents can work around them.