CPersona
Officialcpersona
MCP 记忆服务器
让 Claude 在不同会话间拥有持久记忆。 单个 SQLite 文件。21 种工具。零 LLM 依赖。
快速入门 · 功能特性 · 架构 · 所有工具 · Zenn 书籍 (日文)
独立仓库 — 这是供 Claude Desktop、Claude Code 及任何 MCP 客户端使用的独立版本。 如果您是 ClotoCore 用户,请改用 cloto-mcp-servers 中的版本。
问题所在
Claude 在会话之间会遗忘一切。每次对话都从零开始——没有关于您的项目、偏好或昨天讨论内容的上下文。
cpersona 解决了这个问题。它是一个 MCP 服务器,将记忆存储在本地 SQLite 文件中,并通过混合搜索进行检索。Claude 将会记住您。
Related MCP server: mcp-memory-graph
快速入门
先决条件: Python 3.10+, Git
1. 安装 cpersona
git clone https://github.com/Cloto-dev/cpersona.git
cd cpersona
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
# source .venv/bin/activate
pip install .2. 设置嵌入服务器(推荐)
cpersona 的混合搜索在配合嵌入服务器进行向量相似度计算时效果最佳。我们建议使用 cloto-mcp-servers/embedding 并搭配 jina-v5-nano 模型(33M 参数,768 维,在 CPU 上本地运行):
git clone https://github.com/Cloto-dev/cloto-mcp-servers.git
cd cloto-mcp-servers/servers
pip install ./embedding如果没有嵌入服务器,cpersona 将仅回退到 FTS5 + 关键词搜索。向量搜索(最强大的检索层)将被禁用。
3. 配置您的 MCP 客户端
Claude Desktop — 添加到 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": "/path/to/.venv/bin/python",
"args": ["/path/to/cpersona/server.py"],
"env": {
"CPERSONA_DB_PATH": "/home/you/.claude/cpersona.db",
"CPERSONA_EMBEDDING_MODE": "http",
"CPERSONA_EMBEDDING_URL": "http://127.0.0.1:8401/embed"
}
}
}
}Windows: 使用
.venv/Scripts/python.exe和C:/Users/you/.claude/cpersona.db
Claude Code:
claude mcp add-json embedding '{"type":"stdio","command":"/path/to/.venv/bin/python","args":["/path/to/servers/embedding/server.py"],"env":{"EMBEDDING_PROVIDER":"onnx_jina_v5_nano","EMBEDDING_HTTP_PORT":"8401"}}' -s user
claude mcp add-json cpersona '{"type":"stdio","command":"/path/to/.venv/bin/python","args":["/path/to/cpersona/server.py"],"env":{"CPERSONA_DB_PATH":"/home/you/.claude/cpersona.db","CPERSONA_EMBEDDING_MODE":"http","CPERSONA_EMBEDDING_URL":"http://127.0.0.1:8401/embed"}}' -s user就是这样。Claude 现在拥有了持久记忆。您可以让它 store(存储)某些内容,并在以后的会话中 recall(召回)它。
功能特性
混合搜索 — 三种独立的检索策略并行运行,并通过倒数排名融合(RRF)合并结果:
层级 | 方法 | 优势 |
向量 | 余弦相似度 (jina-v5-nano, 768d) | 语义含义 |
FTS5 | 带三元分词器的 SQLite 全文搜索 | 精确术语、名称、ID |
关键词 | 回退模式匹配 | 边缘情况、部分匹配 |
记忆类型:
陈述性记忆 — 通过
store存储的个人事实、决策、指令情景记忆 — 通过
archive_episode归档的对话摘要个人资料记忆 — 通过
update_profile积累的用户/项目属性
置信度评分 — 每次召回的记忆都会获得一个置信度分数,结合了:
余弦相似度(语义相关性)
动态时间衰减(适应语料库的时间范围 — 1 年前的语料库和 1 天前的语料库使用不同的衰减曲线)
召回提升(经常有用的记忆更容易浮现,并带有自然淡出)
完成因子(已解决的主题衰减更快)
零 LLM 依赖 — cpersona 是一个纯数据服务器。它从不在内部调用 LLM。所有摘要和提取均由调用代理执行。这意味着 cpersona 本身零 API 成本、行为确定且无隐藏延迟。
附加功能:
代理命名空间隔离 — 多个代理共享一个数据库而不相互干扰
后台任务队列 — 数据库持久化、支持崩溃恢复的异步处理
JSONL 导出/导入 — 环境间完整的记忆可移植性
代理间记忆合并 — 带有去重的原子复制/移动
自动校准 — 通过零分布 z-score 进行统计阈值调整(无需标签)
健康检查 — 16 项自动检测及自动修复(污染、重复、FTS 同步失败、无效数据、陈旧任务、空内容、无效来源)
深度检查 — 语义数据质量分析(匿名来源恢复、短内容、陈旧个人资料、孤立片段)
记忆保护 — 锁定/解锁以防止意外删除或编辑
近期召回惩罚 — 抑制频繁召回记忆的“回声室效应”
stdio + 可流式传输的 HTTP 传输
单文件 SQLite — 无需外部数据库
架构
┌─────────────────────────────────────┐
│ 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) │
└─────────────────────────────────────┘召回流程 (RRF 模式):
Query → ┌── Vector search (cosine similarity) ──┐
├── FTS5 search (episodes + memories) ──┼── RRF merge → Confidence scoring → Top-K
└── Keyword fallback ──┘基准测试
在 LMEB(长期记忆评估基准,结果)上测试 — 22 项衡量记忆检索质量的评估任务:
嵌入模型 | 参数 | 维度 | 平均 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 相比 MiniLM 基准提升了 +47%。
所有工具
工具 | 描述 |
| 在代理记忆中存储消息 |
| 召回相关记忆(向量 + FTS5 + 关键词,RRF 合并) |
| 获取当前代理个人资料 |
| 保存预计算的代理个人资料 |
| 归档带有摘要和关键词的对话片段 |
| 列出近期记忆 |
| 列出已归档片段 |
| 删除单条记忆(强制所有权) |
| 删除单个片段(强制所有权) |
| 删除代理的所有数据 |
| 通过 z-score 自动校准向量搜索阈值 |
| 导出为 JSONL(记忆、片段、个人资料) |
| 从 JSONL 导入(通过 msg_id 去重实现幂等) |
| 将一个代理的数据合并到另一个(原子操作,带去重) |
| 后台任务队列状态 |
| 使用外部对话上下文召回(自动去重) |
| 更新记忆内容(如果已锁定则拒绝) |
| 锁定记忆以防止删除/编辑 |
| 解锁记忆以允许删除/编辑 |
| 16 点数据库健康检查及自动修复 |
| 深度语义数据质量分析及自动修复 |
配置
所有设置均通过环境变量进行,并提供合理的默认值:
变量 | 默认值 | 描述 |
|
| SQLite 数据库路径 |
|
| 嵌入模式 ( |
|
| 嵌入服务器 URL |
|
| 向量搜索模式 |
|
| 搜索策略 ( |
|
| RRF 平滑参数 |
|
| 在结果中包含置信度元数据 |
|
| 启动时自动校准 |
|
| 启用后台任务队列 |
|
| 近期召回记忆的惩罚值 |
|
| 近期召回惩罚的时间窗口(分钟) |
统计
~3,500 行 Python 代码 (单文件,
server.py)117 个测试,涵盖 12 个测试模块
Schema v8 (自动迁移)
MIT 许可
兼容性
cpersona 是一个 MCP 服务器 — 它适用于任何兼容 MCP 的主机:
ClotoCore (AI 代理平台,cpersona 的发源地)
任何自定义 MCP 客户端
ClotoCore 的一部分
cpersona 是 ClotoCore 的记忆层,这是一个用 Rust 编写的开源 AI 代理平台。虽然 cpersona 是完全独立的(MIT 许可),但它的设计初衷是为 ClotoCore 生态系统中的 AI 代理提供持久、可搜索的记忆。
了解更多
Zenn 书籍 (日文) — 完整的设计演练和设置指南
记忆系统设计 — 技术规范
ClotoCore — AI 代理平台
许可
MIT — 可从任何 MCP 主机免费使用,无任何限制。
Available Tools
31 toolsarchive_episodeA
Archive a conversation episode with pre-computed summary, keywords, and resolved status. All LLM processing is performed by the caller.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | v2.4.22 conversation-channel tag (e.g. a Discord channel id). Default '' (= unscoped). Channel-scoped recall returns episodes whose channel matches; this powers the per-channel episodic loop. | |
| history | No | Original conversation messages (used for start/end timestamp extraction; the episode embedding is computed from summary) | |
| summary | Yes | Episode summary (pre-computed by caller) | |
| agent_id | Yes | Agent identifier | |
| keywords | No | Space-separated keywords (pre-computed by caller) | |
| resolved | No | Whether the topic was completed/concluded | |
| project_id | No | v2.4.17 isolation axis. Omit or pass '' for the global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution. | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal that the operation is non-read-only, non-idempotent, and non-destructive. The description adds a useful behavioral fact: the tool performs no LLM processing itself. However, it does not disclose return behavior, overwrite/conflict semantics, or side effects beyond archiving, so the added transparency is modest.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exactly two sentences with no fluff. The primary action is front-loaded, and the second sentence communicates the critical caller-responsibility constraint. It avoids repeating schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description plus the rich input schema adequately cover the 8 parameters, including nuanced ones like project_id and session_key, and state the key prerequisite. It does not explicitly connect archival to recall/list_episodes or describe the return value, but those are not essential for correctly selecting and invoking the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even without parameter details in the tool description. The phrase 'pre-computed summary, keywords, and resolved status' reinforces that these values must be prepared by the caller, but it does not add meaningfully to the already-detailed schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Archive') and resource ('conversation episode') and states the payload: pre-computed summary, keywords, and resolved status. It is clear about what the tool does and that it creates/stores an archived episode, but it does not explicitly contrast it with sibling tools like store, update_memory, or list_episodes, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'All LLM processing is performed by the caller' is an explicit prerequisite: the agent should only call this tool after summarization, keyword extraction, and resolved-status determination have already happened. It does not name alternatives or state when not to use it, so it lacks the explicit exclusion guidance needed for a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| method | No | 'separation' (default; two-population — learns the operating point from null pairs vs temporally-adjacent same-session positives, falling back to nearest-neighbour when too few exist), 'percentile', or 'zscore' | |
| agent_id | Yes | Agent ID whose memories to sample | |
| z_factor | No | Z-score multiplier for method='zscore' (default: 1.0, higher = stricter) | |
| percentile | No | Null-distribution quantile for method='percentile' (default: 0.95, higher = stricter) | |
| sample_size | No | Number of embeddings to sample (default: 200) | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say the operation is not read-only, not idempotent, and not destructive. The description adds meaningful behavioral detail: it samples memory pairs, places the threshold above the null mean, uses no labels, and adapts to model and corpus. It stops short of explicitly stating whether the calibration result is persisted or how it affects future recalls, but the added algorithm-level transparency is strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured: purpose first, then method details. Every sentence adds meaningful information, though the method explanations are slightly verbose and overlap with the schema descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the algorithm and method choices well, but it does not state what the calibration changes in persisted state, whether there are prerequisites (e.g., existing memories), or what the return value is. Given the absence of an output schema and the mutating nature of the tool, these gaps leave the description slightly incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description goes beyond the schema by explaining the statistical rationale for each method, including when percentile is robust (anisotropic models like bge-m3) and how separation falls back to nearest-neighbour. This helps an agent choose sensible parameter values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Auto-calibrate') on a specific resource ('the vector search threshold'), grounded in a concrete statistical basis (the null cosine distribution). It also distinguishes the different calibration methods, making the tool's intent unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how the tool works and the method options, but it does not say when to use this tool versus alternatives like set_recall_precision or get_recall_precision. It gives no explicit usage conditions, prerequisites, or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_healthA
Check memory database health (29-check registry, each issue tagged with severity critical/warn/info). Detects contamination, duplicates, oversized content, embedding issues, FTS integrity (count + content-level), schema version/object drift (missing UNIQUE indexes or FTS triggers), SQLite file integrity, project_id naming drift, invalid JSON/timestamps, timestamp format drift, stale tasks, missing profiles, empty content, invalid/anonymous sources. Returns storage stats incl. project_id/channel distributions. Set fix=true to auto-repair (agent-scoped, locked-safe); critical file-integrity findings are report-only. Two repairs are lossy and irreversible, each against its own cap: oversized memories are cut to CPERSONA_MAX_CONTENT_LENGTH (default 16000 since 2.5.4a2) and the agent's profile row to CPERSONA_MAX_PROFILE_LENGTH (default 2000), keeping the start. Lower either cap and a fix run shortens rows that were within the old one. Some repairs are bounded per run (source canonicalisation classifies at most 1000 rows); a fix response carrying remaining > 0 with a re-run hint has NOT converged — run fix again until remaining stops decreasing. Use checks parameter to run a subset — an unknown name is rejected (ok=false) rather than silently running nothing, and every response echoes checks_run. The verdict is status: healthy / degraded / unhealthy, derived from severity counts (info never degrades). The pre-2.5.2b1 healthy boolean (len(issues) == 0) is gone — it reported False for an info-only database that status called healthy; read issues / severity_summary for the underlying counts.
| Name | Required | Description | Default |
|---|---|---|---|
| fix | No | Auto-fix detected issues | |
| checks | No | Registry check names to run (empty = all). See cpersona.checks.HEALTH_CHECK_NAMES. | |
| agent_id | No | Agent ID to check (empty = all agents) | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint=false annotation, the description discloses many behavioral traits: lossy/irreversible repairs, report-only file-integrity findings, per-run caps, the remaining convergence signal, unknown-check rejection, and the removal of the old healthy boolean. This is exactly the side-effect and edge-case disclosure an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense and front-loaded: the core purpose and check list come first, followed by repair caveats and status semantics. Each sentence carries distinct information; the historical note about the removed healthy boolean is useful but adds length that could be trimmed in a more tightly structured definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and only one annotation, the description covers behavior, return signals (status, issues, severity_summary, checks_run, remaining, storage stats), version nuances, and parameter usage. An agent has enough information to invoke it correctly and interpret results, including convergence behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all parameters described), but the description adds meaning beyond the schema: it explains that fix=true is agent-scoped, lossy/irreversible, and capped, and that checks rejects unknown names rather than silently doing nothing. It does not add details for agent_id or session_key beyond their schema descriptions, so a 4 is earned rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource — 'Check memory database health' — and enumerates 29 named check categories, making the scope unusually concrete. However, it never names or contrasts sibling tools such as deep_check, so it stops short of explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational guidance: use checks to run a subset, set fix=true to auto-repair, and re-run until remaining stops decreasing. It does not explicitly state when to prefer this tool over alternatives like deep_check, but the context strongly implies a health/safety-check role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. state is one of: ok (running the newest release) / newer (a newer final release exists — pre-releases are never proposed) / yanked (every file of the RUNNING version has been withdrawn on PyPI; reason carries the publisher's text) / unlisted (this version is not on the index at all — a development checkout; not a defect) / unknown (no check has completed, e.g. no network) / disabled. install names how this process was installed (uvx / pip / checkout / unknown) and the exact command that would update it. refresh=true performs the fetch now (3s budget) and updates the cache. apply=true runs that command as an argv list (never a shell), returning exit_code and the last 40 lines of output — supported for pip and checkout installs only; under uvx the environment is a cache entry keyed by the launch arguments, so the update belongs in your client's config (uvx cpersona@latest), and an install here would be discarded on the next launch. A checkout parked at a tag (detached HEAD) is likewise refused before anything runs, and answers with the git fetch --tags && git checkout <tag> form to use instead. Updating is NEVER automatic and never a side effect of any other call. A RESTART IS ALWAYS REQUIRED afterwards: this process keeps serving the old code until it is replaced. Unaffected by pause_persistence — an install writes no memory row, so a no-persist session can still repair a withdrawn version. Set CPERSONA_UPDATE_CHECK=false to disable the feature entirely: no fetch, no cache, no notice on recall or check_health, and this tool answers state=disabled.
| Name | Required | Description | Default |
|---|---|---|---|
| apply | No | Run the detected update command (pip / checkout installs only). Off by default; a restart is required afterwards. | |
| refresh | No | Fetch the package index now instead of reading the cached verdict (3s budget; a failure answers state=unknown). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description extensively discloses behavior beyond the minimal readOnlyHint:false annotation: the once-per-process background check, 24h cache, no network/disk on bare calls, exact state meanings, restart requirement, no automatic updates, install-method constraints, and independence from pause_persistence. This is exemplary transparency for a tool with side-effecting capabilities.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is dense and every major point is relevant, but it is delivered as one long monolithic paragraph with no bullets or headings, making it harder to parse. It is somewhat longer than necessary, with minor repetitions around 'never automatic' and 'only if you ask'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully covers the return contract: state values, reason, install command, exit_code, and output truncation. It also addresses edge cases such as detached HEAD, uvx cache behavior, and the CPERSONA_UPDATE_CHECK disable path, so an agent has everything needed to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds substantial meaning: refresh has a 3s budget and failure yields state=unknown; apply returns exit_code and last 40 lines, never uses a shell, and is restricted to pip/checkout installs. The description enriches both boolean parameters well beyond their schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Report whether a newer release of this server exists' and explicitly scopes the install capability as opt-in. It clearly separates check, refresh, and apply behaviors, making the tool's purpose unambiguous even among many siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when a bare call, refresh=true, and apply=true are appropriate, and explicitly states when apply is refused (checkout at tag, uvx). It does not explicitly name alternative sibling tools, but the usage boundaries are otherwise detailed enough for an agent to decide correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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. Report-only (fix is accepted and ignored): stale_profile, orphaned_episodes, calibration_staleness, near_duplicate — apply those decisions via merge_memories / delete_memory / calibrate_threshold / update_profile. Use checks parameter to select specific checks.
| Name | Required | Description | Default |
|---|---|---|---|
| fix | No | Apply repairs (default: dry-run preview only) | |
| checks | No | Checks to run (empty = all). Options: anonymous_source, short_content, stale_profile, orphaned_episodes, calibration_staleness, near_duplicate | |
| agent_id | Yes | Agent ID to check (required) | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint=false annotation by disclosing exactly which checks are repaired by fix=true, which are report-only, and that fix is accepted but ignored for those. It also surfaces the default dry-run preview behavior and the judgment call nature of the analysis.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence carries a distinct responsibility: scope, issue taxonomy, fix behavior, routing, and check selection. The core capability is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool of this complexity, it covers the input contract, per-check fix behavior, and downstream actions, which is strong. It does not describe the shape or content of the report returned (and there is no output schema), so an agent must assume the issue categories are the output vocabulary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds value by grouping checks into fixable vs report-only and by explaining that fix is not a global repair switch. It confirms how checks selects specific checks, though it does not add detail beyond the schema for session_key or agent_id.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Deep heuristic analysis') and a well-scoped resource (memory data quality), then enumerates the six concrete issue categories it detects. This clearly distinguishes it from sibling health/update tools even without reading their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives actionable guidance on how to use the fix flag and which checks to select, and routes report-only outcomes to the correct follow-up tools (merge_memories, delete_memory, calibrate_threshold, update_profile). It does not explicitly contrast deep_check with check_health or other diagnostic siblings, so an explicit when/not-when boundary is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_agent_dataADestructiveIdempotent
Delete ALL data (memories, profiles, episodes) for a specific agent. Used by kernel during agent deletion.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | Yes | Agent ID whose data should be purged | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false. The description adds meaningful context beyond these flags by specifying exactly what data domains get destroyed (memories, profiles, episodes) and that it is scoped to a single agent, clarifying the blast radius.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The core action and scope are front-loaded, and the usage context is given in the second sentence. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple two-parameter schema and annotations that already cover destructive/idempotent behavior, the description sufficiently explains the tool's purpose and scope. Minor omissions like return values or preconditions are not critical for this kind of cleanup operation. The note about being used by the kernel adds adequate context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters (agent_id and session_key) have detailed descriptions in the input schema, including the nuanced behavior of session_key as a partition hint rather than a data filter. The tool description itself adds no param information beyond what the schema provides, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Delete' and names the exact resource: ALL data (memories, profiles, episodes) for a specific agent. It clearly distinguishes this from sibling memory-manipulation tools by emphasizing it purges everything for one agent during deletion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: 'Used by kernel during agent deletion.' It does not provide explicit alternatives or when-not-to-use guidance, but the context of a cleanup/teardown operation is unambiguous enough for an agent to decide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_episodeADestructiveIdempotent
Delete a single episode by ID. Ownership is enforced when agent_id is provided.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | No | Agent ID for ownership verification (injected by kernel) | |
| episode_id | Yes | Episode ID to delete | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive and non-read-only behavior, and idempotentHint=true is present. The description adds value beyond the annotations by revealing that ownership is enforced when agent_id is provided, which is key behavioral context for callers. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no filler, and the core action is front-loaded. Every word earns its place by clarifying scope or the ownership condition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-ID deletion tool, the description covers the core operation and the ownership nuance. The destructive nature is already communicated by annotations, and no output schema exists, so return-value details are not required. It could mention the alternative of archiving, but that is not necessary for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents episode_id, agent_id, and session_key. The description largely restates what the schema says: delete by ID and ownership enforcement for agent_id. It does not add meaningful parameter-level detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Delete a single episode by ID.' It clearly scopes the operation to one episode, distinguishing it from broader deletion tools like delete_agent_data or archiving tools like archive_episode. The ownership enforcement sentence adds further precision about the operation's conditions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a clear usage context: use when you need to delete exactly one episode by its ID. It also notes an important condition around agent_id and ownership verification, but it does not explicitly name alternatives or explain when not to use this tool versus archive_episode or delete_agent_data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_memoryADestructiveIdempotent
Delete a single memory by ID. Ownership is enforced when agent_id is provided.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | No | Agent ID for ownership verification (injected by kernel) | |
| memory_id | Yes | Memory ID to delete | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish destructive and read-only behavior, so the description adds value by explaining ownership enforcement when agent_id is provided. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise, front-loaded sentences with no filler. The core action is stated first and the ownership caveat follows.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-item deletion tool, the description plus annotations and full schema coverage are largely sufficient. It could additionally clarify not_found behavior or relationship to bulk deletion tools, but these are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are already fully documented. The description does not add meaningful parameter details beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Delete), a specific resource (memory), and a precise scope (single memory by ID). This clearly distinguishes it from sibling tools such as delete_episode and delete_agent_data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is implied: use this when deleting one memory by its ID. However, it does not explicitly mention when_not_to use it or name alternatives like delete_agent_data for broader deletion, leaving some routing to the agent's inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_memoriesADestructive
Export memories, episodes, and profiles to a JSONL file for backup or portability.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | Yes | Agent identifier (empty string to export all agents) | |
| output_path | Yes | File path for the JSONL output | |
| include_embeddings | No | Include embedding BLOBs as base64 (default false, usually not needed) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description describes an export operation, which is typically non-destructive. However, annotations set destructiveHint to true, implying the tool may have destructive side effects (e.g., file overwrite). The description does not disclose this, contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, straightforward sentence with no wasted words. It is front-loaded with the action and purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description mentions the data types exported (memories, episodes, profiles) and the format (JSONL), but does not address potential side effects like file overwriting despite the destructiveHint annotation. Given no output schema, more detail on the return value or behavior would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all three parameters (agent_id, output_path, include_embeddings) with descriptions. The tool description does not add additional meaning beyond what the schema provides, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool exports memories, episodes, and profiles to a JSONL file for backup or portability. It uses a specific verb and resource, and distinguishes from siblings like import_memories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context for when to use the tool (backup or portability) but does not explicitly state when not to use it or mention alternatives. Sibling list makes the purpose clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_contentsARead-only
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 deferred (absent otherwise) alongside budget_chars; re-fetch them in a second call. A single row larger than the budget is still returned in full, because this tool is the only path back to a row's complete text.
| Name | Required | Description | Default |
|---|---|---|---|
| refs | Yes | Refs from recall messages, e.g. ['mem:123', 'ep:45'] (max 20 per call) | |
| agent_id | Yes | Agent identifier (ownership check — another agent's refs come back in `missing`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the readOnlyHint annotation by disclosing two independent bounds (20 refs and 40,000 chars), the deferred return field and budget_chars, the never-cut behavior, the special case of a single row exceeding the budget, and the ownership check via agent_id that results in missing. This level of behavioral detail is exceptional.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and every sentence provides meaningful detail about limits, edge cases, and the deferred mechanism. It is longer than average, but the complexity of the tool justifies the length; the version reference '2.5.4a2' adds specificity without being redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the multi-bound behavior, deferred refs, budget semantics, and the absence of an output schema, the description covers all critical runtime behavior, edge cases, and the ownership check result. The agent receives everything needed to invoke the tool correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both refs and agent_id are already well-described in the schema. The description adds contextual behavior (deferred, missing) but does not add new parameter-level semantics, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Fetch full, untrimmed content for recall preview refs', which clearly specifies the action, resource, and scope. It also distinguishes this tool from the preview-tier recall flow by positioning it as the targeted expansion path, differentiating it from sibling tools like recall and recall_with_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool ('Use after a preview-tier recall to expand only the rows that matter') and names the alternative approach ('instead of opting the whole recall out with full_content=true'). Also gives operational guidance about re-fetching deferred refs in a second call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_operating_contextARead-only
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.
| Name | Required | Description | Default |
|---|---|---|---|
| section | No | Doctrine section name to fetch in full (from doctrine_sections). Empty = preview tier. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description not only aligns with the readOnlyHint annotation but adds significant context: the context is edited on the filesystem (~/.cpersona/operating-context.toml), never via MCP. This discloses the source of truth and mutation path, which annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, front-loaded with the core purpose, followed by mode details and behavioral note. No wasted words. Structure is logical: what, how, important note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one optional parameter, no output schema, and full annotations, the description covers all necessary aspects: return types (preview tier components, full section body), usage modes, and behavioral constraints (read-only, filesystem editing). It is sufficient for an AI agent to correctly invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a description for the 'section' parameter. The description adds value by explaining the default behavior (preview tier) and that the section is from 'doctrine_sections'. It clarifies the parameter's effect beyond the schema's own description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads the 'server-served operating context' with a specific version (v2.5.1). It identifies the resource and its nature as 'operator-owned doctrine'. This is specific and distinct from sibling tools like 'get_profile' or 'get_contents'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the two modes: without arguments returns the preview tier, and with a 'section' argument returns the full body. It mentions read-only and that editing is done via filesystem, not MCP. While it doesn't contrast with siblings, it provides clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_profileCRead-only
Get the current profile for an agent.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | Yes | Agent identifier |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description aligns with readOnlyHint by stating 'Get', but adds no further behavioral details such as error handling for missing agents, return format, or scope of the profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, concise and front-loaded. Could include more detail without being overly long, but the brevity aids readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple 1-parameter tool with no output schema. However, lack of return value description may leave the agent uncertain about the output format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a clear description for 'agent_id'. The tool description does not add any additional meaning beyond the schema, so baseline score applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get the current profile for an agent' clearly states the action (get) and resource (profile) with specifier 'for an agent'. It distinguishes from sibling 'update_profile' but is slightly redundant with the tool name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives, no prerequisites or limitations mentioned. The only implicit guidance is from the readOnlyHint annotation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_queue_statusARead-only
Get the status of the background task queue (pending tasks, retry config).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description's addition of 'pending tasks, retry config' provides some context. However, it could be more transparent about the return format or any other behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence of 13 words. Every word is purposeful and concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, parameterless tool with readOnlyHint annotation, the description is fairly complete. It could benefit from specifying the output structure, but given no output schema, it's adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so baseline is 4. The description does not add parameter details, which is acceptable since there are none.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb 'Get' and resource 'background task queue status', and mentions what is included (pending tasks, retry config). This distinguishes it from sibling tools like check_health or list_episodes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for checking queue status but provides no explicit guidance on when to use it versus alternatives, nor when not to use it. No sibling comparisons mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recall_precisionARead-only
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.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | Yes | Agent whose precision to read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description goes further by stating it never recalibrates or persists, and details the returned fields (beta, precision level, override flags). This adds behavioral context beyond the annotation, though it doesn't cover all edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph that front-loads the main purpose and then provides additional details. It is reasonably concise, though some sentences could be tightened. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple input (1 param, no output schema), the description thoroughly explains the return value and its relationship to the global default and override behavior. It is complete for a read-only tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers the single required parameter (agent_id) with a description. The tool description does not add meaning beyond that, but since schema coverage is 100%, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads an agent's effective recall precision, identifies it as the read-back companion to set_recall_precision, and specifies it is read-only. This distinguishes it from its sibling and provides a specific verb-resource combination.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool (as a read-back companion to set_recall_precision, for UI loading before editing) and implies it should be used before writing. However, it does not explicitly mention alternatives or when not to use it, though the sibling set tool is clearly the counterpart.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_session_findingsARead-only
Pull the storage-integrity findings on demand (SuperAuditor v1 pull contract, docs/SUPERAUDITOR_STANDARD.md) instead of reading them off check_health. Same detector as check_health(fix=false) over the WHOLE database, delivered as findings: each carries kind (the check registry name, so check_health(checks=[kind]) re-runs exactly that probe; escalation tiers are their own kinds, e.g. null_embedding_pipeline_down) and a static per-kind severity (critical = the read contract is broken now / warn = two stored facts contradict / info = an observation). check_health's own instance verdict rides along as health_severity; a probe that raised is reported as kind check_crashed instead of failing the pull, so a partial result says which probe is missing. Read-only, never repairs. NOT free, though: the registry runs unfiltered, which includes two whole-database reads (the FTS5 integrity-check over both indexes, and PRAGMA quick_check over the file), so every pull is O(database) on a channel meant to be pulled once a session — budget it by call frequency. There is deliberately no cheap subset: choosing which probes run would be choosing which forgotten state stays forgotten. Findings are NOT filtered by agent_id or project_id — the channel surfaces forgotten state, and slicing it by the caller's bucket would hide exactly the rows that were forgotten (scope a repair with check_health(agent_id=...)). Honest caps: findings holds at most per_kind_limit rows per kind, capped_kinds names every kind that had more (observed, not inferred from count == limit), total and the counts describe the RETURNED set only, and per_kind_limit echoes the limit applied. summary restates the same trimmed set in prose (pass include_summary=false to skip paying for it). On a shared remote transport with no session_key declared the response carries identity_shared: true — this server has no session-scoped probes, so the key is a partition hint, not a filter. _meta.server_version identifies the running instance.
| Name | Required | Description | Default |
|---|---|---|---|
| session_key | No | Opaque client-declared session identity (partition hint, not authentication). Empty on a non-stdio transport marks the response identity_shared. | |
| per_kind_limit | No | Maximum findings returned per kind (default 5, minimum 1). Kinds that hit it are listed in capped_kinds. | |
| include_summary | No | Include the human-readable `summary` rendering (default true). It restates `findings` in prose — set false when machine-reading. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry readOnlyHint=true, so the description bears the full burden — and it delivers massively: cost profile (O(database), two whole-database reads), the guarantee that findings are NOT filtered by agent_id/project_id, the cap semantics ('capped_kinds names every kind that had more (observed, not inferred from count == limit)'), the check_crashed fallback instead of failing the pull, and identity_shared behavior. The 'Read-only, never repairs' statement is consistent with readOnlyHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is unusually long, but every sentence carries distinct operational information — cost, filtering, caps, crash handling, transport identity — and the core purpose is front-loaded in the first sentence. It is information-dense rather than padded; a slight trim would be possible, but nothing is wasted given the tool's genuinely complex behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description must document return semantics itself — and it names the essential fields (kind, severity with its value meanings, health_severity, check_crashed, findings, capped_kinds, total, per_kind_limit, summary, identity_shared, _meta.server_version). Combined with parameter semantics, cost, and filtering behavior, an agent has everything it needs to call this correctly on a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, but the description adds substantial meaning beyond the schema: per_kind_limit's interaction with capped_kinds and the honesty caveat that total/counts describe only the returned set, session_key being 'a partition hint, not a filter' with identity_shared implications, and include_summary being described as a prose restatement you can skip to avoid paying for it. This goes well beyond the baseline 3 for fully-covered schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Pull the storage-integrity findings on demand') and immediately distinguishes itself from the sibling check_health ('instead of reading them off check_health'). The 'Same detector as check_health(fix=false) over the WHOLE database' line precisely situates it among siblings, so an agent cannot confuse it with check_health, deep_check, or the other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it vs the alternative: it is a pull contract meant to be invoked 'once a session', budgeted by call frequency, versus check_health for scoped repair ('scope a repair with check_health(agent_id=...)'). It also gives concrete invocation guidance like 'pass include_summary=false to skip paying for it' and explains why no cheap subset exists — leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_memoriesADestructiveIdempotent
Import memories, episodes, and profiles from a JSONL file. Idempotent: memories deduplicate on msg_id (and on content within a project/channel), episodes on their summary within a project/channel.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Count records without writing to DB (preview mode) | |
| input_path | Yes | Path to the JSONL file to import | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. | |
| target_agent_id | No | Remap all records to this agent ID (empty to use original agent_id from file) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful behavioral detail beyond annotations by specifying deduplication keys (msg_id/content for memories, summary for episodes). However, destructiveHint is true and the description does not disclose what destructive effect may occur, such as overwriting existing records, which leaves an important behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler: the first states the operation and scope, and the second adds essential idempotency and deduplication semantics. Information is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating tool with destructiveHint, the description is reasonably complete but missing return-value behavior and clarification of the destructive/overwrite effect. The schema and annotations cover parameters and high-level safety, but the description does not fully bridge those gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds no parameter-specific meaning beyond saying the source is a JSONL file; it does not elaborate on dry_run, session_key, or target_agent_id, though the schema already captures those.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Import), the resource (a JSONL file), and the data kinds (memories, episodes, and profiles). This clearly differentiates it from siblings like export_memories, store, or merge_memories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tool's intended use as a bulk importer from a JSONL file is implied, and the idempotency note suggests it is safe for repeated imports. However, it does not explicitly say when to use this instead of alternatives such as store or merge_memories, nor does it state exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_episodesARead-only
List archived episodes for an agent (for dashboard display). bug-255: the response holds an 800,000-character budget across summary and keywords together, with the same degradation and ceiling semantics as list_memories — rows past the budget that exceed the preview cap carry pure prefixes plus summary_truncated/summary_len and keywords_truncated/keywords_len; budget_chars appears iff at least one row was degraded. Their ref expands the summary via get_contents (under the row's own agent_id); a full keywords string is only available through export_data.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max episodes to return | |
| agent_id | No | Agent identifier (empty for all agents) | |
| project_id | No | v2.4.17 γ filter. Same semantics as list_memories. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true is complemented by a detailed exposition of response-size budget, degradation semantics, truncation markers, and conditional budget_chars. The description also discloses special-case behavior (literal '@auto' resolution, no warning). This is transparent about the tool's behavior beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is technically dense but effective numerically; the leading sentence furnishes the purpose ('dashboard display') and the exotic details (budget, ref) are packed after. A slight con: it jumps into bug/history references (bug-255, v2.4.7) that might confuse a simple agent, but the structure is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description compensates by explaining the response layout (summary/keywords truncation, budget_chars presence, ref expansion). It also cross-references get_contents and export_data for full data, so the agent knows how to recover details. The complexity of the tool is well covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters have schema descriptions, but the tool description adds significant semantic depth, particularly for project_id: explaining the '@auto' sentinel, resolution edge cases, and referring to list_memories for same semantics. This goes well beyond the generic schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the verb 'list' with a specific resource ('archived episodes for an agent') and qualifies the scope ('for dashboard display'). It distinguishes itself from list_memories and mentions export_data for full keyword data. However, it doesn't explicitly name sibling alternatives for the list function; it clarifies what it is not for related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear when-to-use context (dashboard display) and directs the agent to alternative tools for expansion (get_contents) and full data (export_data). Yet it still lacks a formal exclusion framework (e.g., 'use export_data when full keywords are needed') in the imperative; but the info about ref and keywords hint is present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_memoriesARead-only
List recent memories for an agent (for dashboard display). bug-255: the response holds a 1,000,000-character content budget. Rows are returned newest-first and none is dropped; once the budget is spent, later rows LONGER than the preview cap (CPERSONA_RECALL_PREVIEW_CHARS, default 500) degrade to a pure prefix with content_truncated/content_len and a ref that get_contents expands under the row's own agent_id (in an all-agents listing, pair the ref with the row's agent_id field). budget_chars appears iff at least one row was degraded. The effective ceiling is the budget plus one whole row plus the degraded rows' prefixes, so it scales with the preview cap; preview cap 0 disables trimming and the budget with it.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max memories to return | |
| agent_id | No | Agent identifier (empty for all agents) | |
| project_id | No | v2.4.17 γ filter. Omit → no filter; '' → global pool only; 'X' → 'X' ∪ global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with readOnlyHint=true, the description goes far beyond that annotation to explain the honored content budget, newest-first ordering, row-degradation mechanics, preview cap, suffix fields, ref expansion behavior, and budget_chars presence. It also covers edge cases like all-agent listings and preview-cap-0 disabling trimming. This is exemplary behavioral disclosure — the agent is fully informed about response size limits, truncation, and associated fields without having to guess.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long and dense, but it front-loads the core purpose in the first sentence, then structures the rest around the bug-255 behavior and its consequences. The detail is necessary for a tool with no output schema, and the organization (budget → degradation → edge cases) makes it navigable. It could arguably be trimmed, but the density is justified by the complexity of the response contract.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, this description carries the full burden of explaining the response shape — and it does so thoroughly: rows, degradation conditions, truncation fields, ref expansion, budget_chars, and the scaling ceiling. It also covers the all-agents pairing nuance and the preview-cap edge case. The description is complete enough for an agent to correctly interpret and invoke the tool, including handling the 'ref' expansion via get_contents.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage for all three parameters (limit, agent_id, project_id), each with descriptive text — project_id's is especially detailed. The tool description adds zero parameter-level information; it focuses entirely on response behavior. Per the rubric, with schema coverage >80%, a baseline of 3 is appropriate, and no extra value is added here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb-object pair — 'List recent memories for an agent' — and adds the dashboard-display context, making the tool's primary function unmistakable. While it doesn't name sibling tools, the distinction from recall/store/get_contents is evident from 'list recent' versus retrieval/storage actions. The purpose is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states a clear use case: 'for dashboard display,' which implicitly signals this is for lightweight listing rather than full recall. It does not explicitly name alternatives or exclusionary conditions (e.g., 'use recall for full content'), but the dashboard-display context implies a preference for this tool over more memory-heavy operations. The guidance is adequate but could be stronger with an explicit 'use this when…' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lock_memoryAIdempotent
Lock a memory to prevent deletion and editing. Ownership enforced when agent_id provided.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | No | Agent ID for ownership verification | |
| memory_id | Yes | Memory ID to lock | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the annotations by explaining that locking prevents deletion and editing. It also clarifies the conditional ownership enforcement tied to agent_id, which is not captured in the readOnlyHint, idempotentHint, or destructiveHint flags. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler. It front-loads the primary purpose and immediately follows with the key ownership condition, making it efficient and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple locking tool with a single required parameter, the description covers the core behavior and the important ownership nuance. No output schema exists, but little is needed because the tool's effect is straightforwardly described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds value by clarifying that ownership is only enforced when agent_id is provided. This is a meaningful semantic qualifier beyond the schema's generic 'Agent ID for ownership verification' phrasing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Lock') and resource ('a memory') and clearly states the intended effect: preventing deletion and editing. It is distinguishable from sibling tools like unlock_memory and delete_memory, so there is no ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when a memory must be protected from deletion or editing, but it does not explicitly state when to choose this over alternatives or when not to use it. The ownership note ('Ownership enforced when agent_id provided') gives conditional usage context, but no direct comparison to siblings is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_memoriesADestructiveIdempotent
Merge memories, episodes, and profiles 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).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Merge mode: 'copy' (preserve source) or 'move' (delete source after merge) | copy |
| dry_run | No | Preview merge without writing to DB | |
| strategy | No | Merge strategy: 'skip' (default) — skip duplicates, keep target's version | skip |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. | |
| source_agent_id | Yes | Agent ID to merge FROM | |
| target_agent_id | Yes | Agent ID to merge INTO |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as non-read-only, idempotent, and destructive. The description adds useful behavioral context beyond those flags: atomicity, lack of intermediate files, and the deduplication behavior for strategy 'skip' by msg_id and summary. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three focused sentences, each adding distinct value: the operation and scope, the atomic/one-shot nature, and the deduplication rule. No fluff or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 6-parameter schema and destructive annotations, the description plus schema provide enough for an agent to select and invoke the tool correctly. It could go slightly further by describing what the call returns, especially since there is no output schema, but that is a minor gap for a mutating merge operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all six parameters. The description adds minor value by detailing how the 'skip' strategy deduplicates, but it does not need to compensate for missing parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific operation ('Merge memories, episodes, and profiles from one agent into another') and the exact resource scope. The phrase 'Atomic one-shot equivalent of export→import without intermediate files' strongly distinguishes it from sibling tools like export_memories and import_memories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use this tool: when a single atomic merge between agents is desired, avoiding the multi-step export→import flow. It does not explicitly give exclusion criteria or name alternatives, but the contrast with export/import is enough to guide selection among related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview counts only, no mutation (default: true) | |
| agent_id | No | Agent ID to migrate (empty = all agents) | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. | |
| globalize_unrecoverable | No | Also move channel='discord' rows with no snowflake session_id to channel='' (global). Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnlyHint=false, which is minimal. The description compensates fully by disclosing that the operation is non-destructive (only the channel column changes), idempotent (re-running is a no-op), that dry_run avoids mutation, and that globalize_unrecoverable moves unmatched rows to the global channel. It also explains the unrecoverable bucket behavior. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and long, but every clause contributes necessary operational detail: the transformation rule, the session_id format, non-destructiveness, idempotency, dry_run behavior, and the globalize option. It is front-loaded with the core purpose. A more structured list might improve readability, but the content is warranted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a migration tool with no output schema, the description covers all essential context: what gets rewritten, the exact session_id format, default behavior, the unrecoverable case, and the optional globalize behavior. An agent can correctly decide whether to call this tool and how to set the parameters without additional information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by explaining what dry_run=true reports (recoverable count, channels, unrecoverable bucket) and what globalize_unrecoverable does to the unrecoverable bucket. This goes beyond the simple boolean descriptions in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action: 'Re-channel bridge-type memories to their concrete channel', naming the resource (bridge-type memories) and the transformation (rewriting channel from session_id). It clearly distinguishes this migration utility from the sibling memory tools, which operate on individual memories or recall rather than performing a schema migration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational guidance: dry_run=true is the default and reports without mutating, while globalize_unrecoverable=true is an opt-in escalation. It also clarifies idempotency and non-destructive behavior. It does not explicitly name alternative tools or exclusion conditions, but there is no obvious sibling alternative for this migration, and the flag semantics effectively tell the agent when to use which mode.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pause_persistenceAIdempotent
Pause write operations on this MCP server for an opt-in TTL window. While paused, every write tool — store, 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 persisted: false, dry_run: true and a reason (with the TTL remaining) instead of writing to the database. persisted: false is the authoritative signal: branch on it, not on an id. Where the success shape has an id, it reads "no-persist" (store, archive_episode); action-specific id keys (deleted_id / updated_id / locked_id / unlocked_id / episode_id) are blanked to null so a truthy echo cannot read as success. migrate_channel_axis is gated differently — it is forced to dry_run and reports repairs_skipped rather than returning a skipped-response, so it carries no persisted key. check_health and deep_check are not blocked but downgrade to fix=false (they answer with repairs_skipped: true). Read tools (recall, list_*, get_profile, etc.) still answer normally, except that recall suppresses its recall_count / last_recalled_at bump — a write that would otherwise move ranking state during a paused session. Blast radius follows session_key (response scope). Pass the same session_key here and on your write calls and the pause covers that key alone (scope: "session"): a session that sends a different key is neither silenced by it nor able to clear it. The key is a partition hint, not a credential — it is compared, never verified — so anyone who sends the same string shares the pause. Omit it and you arm the bucket every keyless caller shares (scope: "process") — on a streamable-HTTP deployment a single process serves every connected client, so a keyless pause silences writes for every other keyless session until resume or TTL elapse, and those sessions get no signal. Under stdio (one process per client) that bucket is the session. This affects only this MCP server (cpersona); call cscheduler's pause_persistence too if you want both paused. Use for benchmarking, AB testing, or ephemeral exploration where memory contamination must be avoided. Default TTL: 1800 seconds (30 minutes); upper bound: 86400 seconds (1 day).
| Name | Required | Description | Default |
|---|---|---|---|
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. | |
| ttl_seconds | No | TTL until automatic resume. Min 1, max 86400 (clamped). Default 1800. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only idempotentHint=true and readOnlyHint=false as annotations, the description carries the full burden of behavioral disclosure and exceeds it: it explains the no-op response shape, the authoritative `persisted: false` signal, blanked id keys, wildcard versus key-scoped pause semantics, the keyless shared bucket fallback, and the migrate_channel_axis exception. No contradiction with the annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every sentence earns its place given the nontrivial semantics of scoped pausing. The critical behavior is front-loaded, with response signatures, scope rules, and edge cases presented in logical order. No filler or repeated schema content is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain the response shape—and it does, including `persisted: false`, `dry_run: true`, the reason field, the 'no-persist' id, and nulled id keys. It also covers TTL defaults, scoped/global behavior, resume requirements, and server boundaries, making it complete for an agent to correctly invoke and interpret the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already documents both parameters, the description adds meaning beyond the structured fields. For session_key, it clarifies that '*' is global, non-wildcard keys are partition hints rather than credentials, pauses do not stack or clear each other, and omitting the key shares a process-level bucket. For ttl_seconds, it reinforces the default and upper bound while explaining the automatic resume behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Pause write operations on this MCP server for an opt-in TTL window.' It clearly names the affected write tools and distinguishes the behavior from resume_persistence and persistence_status by explicitly stating that only resume_persistence can end the pause early.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases: 'Use for benchmarking, AB testing, or ephemeral exploration where memory contamination must be avoided.' It also gives cross-tool guidance by telling the agent to call cscheduler's pause_persistence if both servers should be paused, and clarifies which operations are not affected.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
persistence_statusARead-only
Report whether persistence is currently paused and the TTL remaining (in seconds). It reports the bucket session_key selects (response scope), not the server as a whole: with a session_key it answers for your session only, so paused: false here does not mean no other session is paused. Without one it reflects the bucket every keyless caller shares, which on a streamable-HTTP deployment means paused: true may have been armed by a different keyless session.
| Name | Required | Description | Default |
|---|---|---|---|
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare `readOnlyHint: true`, lowering the burden. The description still adds valuable behavioral nuance: the status is scoped to a bucket selected by `session_key`, not the whole server, and in streamable-HTTP deployments a keyless caller may see `paused: true` caused by another session. This meaningfully goes beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is longer than typical, every sentence earns its place: the main question is front-loaded, and the subsequent sentences clarify non-obvious scope semantics. No filler or redundant restatement of the tool name or schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description supplies the needed outcome expectations: paused state, TTL remaining in seconds, and scope. It also covers the one optional parameter and the tricky multi-session semantics. Nothing needed to call and interpret this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents `session_key` as an opaque partition hint with 100% coverage, so baseline is 3. The description adds extra meaning by connecting the parameter to response scope, explaining that omitting it shares a bucket with other keyless callers, and clarifying that it is not authentication or a data filter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Report whether persistence is currently paused and the TTL remaining (in seconds).' It clearly distinguishes itself from broader server-wide status by emphasizing the returned `scope` is tied to a session key, so it is not ambiguous against sibling status or mutating tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: it explains what happens when `session_key` is provided vs omitted, and warns that `paused: false` does not mean no other session is paused. It stops short of explicitly naming alternative tools or saying 'use this when X, not when Y,' but the inclusion criteria are strongly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallARead-only
Recall relevant memories using multi-strategy search (vector + FTS5 + keyword). Message content is returned as a preview tier by default — expand selected rows with get_contents(refs), or opt out wholesale with full_content=true. full_content is itself budgeted (200k chars per response, bug-211): rows past the budget degrade to the preview tier and the response carries full_content_budget_chars (absent when the budget never bites). v2.5.2 additive: each scored message carries match_reason={signal, score, ...} where signal is the branch the ranking / quality gate keyed on (confidence > rsf > cosine > rrf) and the remaining keys (cosine / rrf / rsf) surface the internal per-retriever contributions present on that row. Unscored rows (cascade FTS/keyword) omit match_reason. A response carrying gate_fallback=true (absent otherwise) means every candidate fell below the quality gate and the below-gate lexical matches were returned instead of an empty result — treat them as low-confidence.
| Name | Required | Description | Default |
|---|---|---|---|
| deep | No | Deep recall — halves the quality gate (and the calibrated fused gate), so weaker matches are admitted. It also disables time and completion decay, which are inert unless CPERSONA_CONFIDENCE_ENABLED=true, and it does NOT widen the scan window (CPERSONA_MAX_MEMORIES) — deep is about how weak a match may be, not how far back the search reaches. | |
| limit | No | Per-retriever search depth, not a pure response cap: the value is handed to each retrieval channel (vector / episode FTS / keyword) as its top-K, so lowering it shrinks the candidate pool itself — rows beyond the depth are unreachable at any gate value, and score normalization / autocut operate on the smaller pool, which can also reorder what remains. Fewer rows than this may be returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.) | |
| query | Yes | Search query (empty returns recent memories) | |
| channel | No | Filter memories by channel (e.g. 'chat', 'discord'). Default: '' (all channels). | |
| agent_id | Yes | Agent identifier | |
| source_id | No | v2.4.20 per-user source filter. Empty (default) = no filter. Non-empty = prefix match against json_extract(source, '$.id'), e.g. 'discord:12345' to restrict to one Discord user, or 'discord:' to scope to all Discord-sourced memories. Episodes carry no per-user source tagging, so they are skipped when this is set — UNLESS channel is also set, which scopes episodes to one conversation and re-admits them. | |
| project_id | No | v2.4.17 γ filter. Omit → no filter (all projects). '' → global pool only. 'X' → 'X' bucket ∪ global pool. Threaded through cascade / RRF / vector / FTS / keyword paths. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution. | |
| session_key | No | Opaque session identity you declare — a partition hint, NOT authentication. It scopes this process's per-session state: the degraded-recall advisory's "already told you" memory, and which no-persist pause applies to this call. It does NOT filter stored data (use agent_id / project_id / channel for that), and it never reaches the database. Omit it to share one bucket with every other caller that omits it, which is the behaviour that predates this parameter. | |
| full_content | No | v2.5.0 preview tier opt-out. By default message content longer than the preview cap (CPERSONA_RECALL_PREVIEW_CHARS, default 500) is returned as a pure prefix with content_truncated/content_len markers; each message's `ref` expands via get_contents. true returns full text. | |
| exclude_contents | No | Normalized content strings to exclude from results (starts-with match). Used to prevent duplication with conversation context already known to the caller. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses substantial behavioral details: content is returned as a preview tier by default, full_content is budgeted at 200k chars, rows past the budget degrade, match_reason and gate_fallback appear conditionally, and unscored rows omit match_reason. It also exposes edge cases with bug IDs and version markers, giving an agent a genuinely accurate model of the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long and dense, but every sentence carries operational weight: purpose, preview behavior, budget semantics, match_reason encoding, and gate_fallback handling. It is front-loaded with the core purpose and then structured into logical behavioral blocks, though some version-specific details add reading load.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and minimal annotations, the description carries the full burden of explaining return behavior. It covers result tiers, budget degradation, per-row match_reason structure, and the gate_fallback failure mode. For a tool this complex, the description is unusually complete for invocation and interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful extra context for full_content, including the 200k-char budget and the full_content_budget_chars response field, which is not present in the schema description. This additional semantic detail justifies a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Recall relevant memories using multi-strategy search (vector + FTS5 + keyword)', giving a clear verb, resource, and method. It does not explicitly distinguish itself from the sibling tool recall_with_context, but its scope and mechanism are clearly stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful guidance on when to use get_contents vs full_content for expanding message content, and explains the default preview-tier behavior. However, it never explicitly addresses when to choose this tool over recall_with_context or other sibling recall-related tools, leaving that comparison to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recall_with_contextARead-only
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). 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. 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 instead of an empty result — treat them as low-confidence.
| Name | Required | Description | Default |
|---|---|---|---|
| deep | No | Deep recall — same semantics as in `recall`: halves the quality gate so weaker matches are admitted. | |
| limit | No | Per-retriever search depth for the underlying recall, not a pure response cap — same semantics as recall's limit: lowering it shrinks the candidate pool itself, not just the rows returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.) | |
| query | Yes | Search query | |
| channel | No | Memory channel filter | |
| agent_id | Yes | Agent ID | |
| source_id | No | v2.4.20 per-user source filter — passed through to recall. Same semantics as in `recall`. | |
| project_id | No | v2.4.17 γ filter — passed through to recall. Same semantics as in `recall`. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution. | |
| session_key | No | Opaque session identity you declare — a partition hint, NOT authentication. It scopes this process's per-session state: the degraded-recall advisory's "already told you" memory, and which no-persist pause applies to this call. It does NOT filter stored data (use agent_id / project_id / channel for that), and it never reaches the database. Omit it to share one bucket with every other caller that omits it, which is the behaviour that predates this parameter. | |
| full_content | No | v2.5.0 preview tier opt-out — same semantics as in `recall`. | |
| external_context | No | Conversation history entries [{role, name?, user_id?, content, timestamp?}, ...] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering the safety profile, the description adds substantial behavioral detail beyond annotations: deduplication, chronological ordering, preview-tiering, external_context filtering semantics, role-based merging, context_filter_only behavior, and gate_fallback low-confidence signaling. This is rich context that an agent needs to interpret the response correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and long but almost every sentence earns its place given the absence of an output schema and the tool's intricate return semantics. It front-loads the core purpose before diving into caveats. It could be tightened with bullet points, but the structure is effective for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 10 parameters, no output schema, and several non-obvious response behaviors, the description covers dedup, ordering, preview tiers, filtering semantics, context_filter_only, and gate_fallback. It also cross-references sibling tools and known caveats like bug-211, making it about as complete as an agent needs for correct invocation and interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema: it explains how external_context entries filter the recall and which roles are merged into messages, and it clarifies the full_content response-budget implication. This goes beyond simply restating parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Recall memories and merge with external conversation context.' It further clarifies the value-add—deduplication, chronological sorting, and a unified list—and explicitly distinguishes itself from 'separate recall + manual merge,' making its purpose unambiguous relative to siblings like recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states it replaces the separate recall-plus-merge workflow and references recall, full_content, and get_contents for alternative behavior. It does not provide an explicit 'use this when external_context is present, use recall otherwise' rule, but the merge focus and references make the intended usage context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_persistenceAIdempotent
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 scope): with a session_key, your own pause and no other session's; without one, the shared keyless bucket, which on a streamable-HTTP deployment re-enables writes for every other keyless session too.
| Name | Required | Description | Default |
|---|---|---|---|
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing the non-obvious shared-bucket side effect: without a session_key, resuming can 're-enable writes for every other keyless session too.' It also explains what `was_active` means and that only the selected bucket is cleared. This is exactly the kind of behavioral nuance annotations do not capture, and there is no contradiction with the readOnlyHint/idempotentHint/destructiveHint flags.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the action and return value, and the second sentence details the critical scope side effect. No sentence is wasted, and the bolded scope warning earns its place because incorrect usage could affect other sessions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the description covers the essential agent decision points: what operation occurs, which bucket is affected, what happens when session_key is omitted, and what return value to expect. The behavior is fully specified enough for correct invocation, especially with the schema's additional session_key clarification.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents session_key well, including that it is a partition hint rather than authentication. The description adds value by explaining the real-world consequence of each choice: with a session_key, only your own pause is cleared; without one, the shared keyless bucket is affected. This goes beyond the schema's neutral wording and helps the agent choose correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action: 'Re-enable persistence immediately, clearing this caller's active no-persist TTL.' It clearly identifies the resource (the caller's no-persist pause bucket) and distinguishes this tool from siblings like pause_persistence and persistence_status by its reversal semantics. It also names the return value, giving the agent a concrete outcome.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the usage context clear: this tool undoes a pause and works on either the session-specific bucket or the shared keyless bucket depending on session_key. It explains the behavioral difference between providing and omitting session_key, but it does not explicitly state 'use this instead of X' or list conditions when not to use it. This is clear context without formal exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_recall_precisionAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| beta | No | Raw specificity weight; overrides the named precision when > 0. | |
| agent_id | Yes | Agent whose precision to set | |
| precision | No | strict / balanced / lenient. Empty (with beta <= 0) clears the override. | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly=false, idempotent=true, destructive=false), it explains that the gate is recalibrated immediately, the change is persisted, it is live without restart, and how named levels, raw beta, and empty values resolve. No contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but organized: purpose first, then parameter semantics, then scope. It is longer than average, but every sentence carries behavioral information; minor jargon like 'knob 3' and 'separation curve' keeps it from being perfectly crisp.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a mutation tool of this complexity: it covers when to use it, all parameter interactions, reset behavior, persistence, and live effect. No output schema exists, but a setter's return value is not needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all four parameters (100% coverage), so the baseline is 3. The description adds real value by defining the precision-to-beta mapping (strict/balanced/lenient -> 2.0/1.0/0.5), beta override precedence, and clearing behavior, which go beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Set an agent's recall precision ... and recalibrate its quality gate') and later adds the distinguishing scope ('per-agent setting, not a per-recall argument'). This separates it clearly from recall-scoped siblings and from get_recall_precision.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear exclusion — this is for per-agent settings, not per-recall arguments — and explains when the empty+beta<=0 form clears the override and returns to default. It doesn't explicitly name sibling tools like calibrate_threshold or get_recall_precision, but the context is enough for typical routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
storeAIdempotent
Store a message in agent memory for future recall. Every response carries result — the one field to branch on: 'stored' (a new row was written; {ok:true, result:'stored', id:, embedded:}, embedded true iff a local blob was persisted or the remote index push succeeded — false under EMBEDDING_MODE=none; the response also carries truncated:true when content exceeded the length cap and was shortened), 'skipped' (nothing written and nothing wrong: {ok:true, result:'skipped', reason:...}; the msg_id / content dedup branches echo the pre-existing row's id, the OR IGNORE fallback reason='duplicate (unique index)' omits id by design — TOCTOU seam), or 'rejected' (nothing written because the request was refused: {ok:false, result:'rejected', reason:...} — empty content, content that sanitizes to empty, or an operating-context project_id refusal, which also carries error). Note for pre-2.5.2b1 callers: ok is no longer unconditionally true, and skipped:true is gone — a rejection used to look like a success. reason is human-readable, not a stable machine token. Under pause_persistence the write is skipped (result:'skipped') and the response carries persisted:false (id:'no-persist', embedded:false) — branch on persisted to tell a paused write apart from a dedup hit.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | Memory channel for context separation (e.g. 'chat', 'discord'). Default: '' (shared). | |
| message | Yes | ClotoMessage to store. Legacy source shapes are normalized server-side where unambiguous (e.g. lowercase type words, Rust serde externally-tagged dicts, bare 'user'/'assistant' strings); unknown shapes are stored verbatim and surfaced by check_health(invalid_source_type). | |
| agent_id | Yes | Agent identifier | |
| project_id | No | v2.4.17 isolation axis. Optional — omit or pass '' to store in the global pool. Reads via γ semantics: a recall with project_id='X' returns 'X' rows + global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution. | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide idempotentHint and safety flags; the description adds a wealth of behavioral detail: the three result branches with exact shapes, skipped/rejected semantics, the TOCTOU dedup seam, version-migration note about ok/skipped, pause_persistence behavior with persisted:false and id:'no-persist', sanitization and size-cap rejection. This far exceeds what annotations convey and does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence front-loads purpose, and nearly every clause is information-dense. However, the description is one long run-on paragraph with dense parentheticals and version notes, making it harder to parse than an equivalent bulleted structure would. Length is justified by complexity, but structure is not concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully specifies return shapes and branch conditions, including embedded, truncated, persisted, id, resolved_project_id, and operating_context_warning. It also covers parameter edge cases, pause-persistence interactions, dedup behavior, and a backward-compatibility note. An agent has nearly everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Though schema coverage is 100% (baseline 3), the description considerably enriches each parameter: msg_id/content dedup branches, '@auto' project_id resolution with bug-186 caveats, source-type normalization and legacy shapes, metadata 8000-char cap policy, timestamp drift detection, and session_key pause partitioning. This is substantial meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: 'Store a message in agent memory for future recall.' This distinguishes the tool from read/query siblings like recall and list_memories. The generic name 'store' is fully disambiguated by the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied from the stated purpose — use this to persist a message for future recall — but there is no explicit when-to-use vs alternatives, no prerequisites, and no mention of sibling tools such as recall or update_memory for competing scenarios. It is implied guidance, not explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unlock_memoryBIdempotent
Unlock a memory to allow deletion and editing. Ownership enforced when agent_id provided.
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | No | Agent ID for ownership verification | |
| memory_id | Yes | Memory ID to unlock | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description adds one behavioral trait beyond them: ownership enforcement when agent_id is provided. It does not disclose failure behavior when ownership check fails, the locked→unlocked state transition semantics, or reversibility, which a mutation tool should surface.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences totaling 13 words with the primary action and effect front-loaded. Both sentences earn their place: the first states the operation and outcome, the second adds the ownership condition. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating tool with no output schema, the description is thin: it omits the state transition semantics (what exactly 'unlocked' means), failure behavior when ownership fails, reversibility, and how session_key interacts with unlock. The schema's odd session_key note ('Full text on recall') is not reconciled in the description, leaving an agent with open questions for a state-changing call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is effectively 100%, so all three parameters are already documented and the baseline is 3. The description's agent_id note is consistent with the schema's 'Agent ID for ownership verification' but adds no new meaning; memory_id and session_key are not elaborated in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (unlock) and resource (memory) and explains the effect ('to allow deletion and editing'), which clearly differentiates it from the sibling lock_memory and from delete/update operations. It stops short of explicitly naming sibling contrast, so it misses the top score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose clause 'to allow deletion and editing' implies when the tool should be called (before editing or deleting a locked memory), and the ownership condition qualifies agent_id usage. However, no alternatives are named and there is no explicit when-not-to-use guidance or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_memoryAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | New content for the memory | |
| agent_id | No | Agent ID for ownership verification | |
| memory_id | Yes | Memory ID to update | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description discloses meaningful behaviors: rejection when locked, ownership enforcement when agent_id is provided, sanitizer max-length truncation with a truncated:true response flag, strip of [Memory from ...] annotations, and refusal of content consisting only of those annotations. This goes well beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: the primary action is front-loaded, followed by key edge cases (lock, ownership) and the sanitizer behavior. There is no filler or redundant repetition of schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with four parameters, no output schema, and rich annotations, the description covers the critical operational details: what happens on locked memories, ownership semantics, sanitizer behavior, truncation signaling, and refusal of annotation-only content. Nothing essential for correctly calling the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds extra meaning beyond the schema by explaining that the sanitizer caps content length, sets truncated:true, and strips annotation prefixes, and that ownership is enforced only when agent_id is provided. These details enrich the parameter semantics beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Update memory content by ID', a specific verb and resource that clearly states the tool's function. It further distinguishes itself by noting lock rejection and ownership enforcement, which separates it from store, delete_memory, and lock_memory siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool through context like 'same sanitizer as store', but it never explicitly states when to use this tool versus alternatives such as store or lock_memory. The usage context is clear but no exclusions or alternative routing are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| profile | Yes | Profile text to save (pre-computed by caller). Capped at 2000 characters (CPERSONA_MAX_PROFILE_LENGTH); the response says truncated:true when the cap cut it. | |
| agent_id | Yes | Agent identifier | |
| session_key | No | Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by disclosing the 2000-character cap, the truncated:true response flag, the sanitizer behavior shared with store, and that discarded content is not stored elsewhere. This gives the agent actionable information about side effects and output, though it does not describe auth needs or full response behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise and front-loaded with the core purpose, then adds the critical truncation behavior. The phrasing 'when the cap bit — branch on it' is slightly awkward, but every sentence contributes meaningful information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple save operation with no output schema, the description covers the main behavioral caveat the agent must handle: truncation and the truncated:true flag. It does not specify the success response shape or whether an existing profile is overwritten, which are minor gaps but not blocking for invoking the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by naming the constant CPERSONA_MAX_PROFILE_LENGTH, mentioning the shared sanitizer, and warning that the discarded remainder is not persisted. It does not add detail on session_key, but the schema already explains it adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly says the tool saves a pre-computed agent profile to the database, with a specific verb, resource, and scope. It does not explicitly differentiate update_profile from its sibling store, though the 'pre-computed' qualifier and the reference to store's sanitizer imply a distinct role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied: call this when you already have a pre-computed agent profile to save. However, it does not explicitly state when to prefer this over store or any other sibling, nor does it give exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
23 tool updates
v2.5.10- Changed
archive_episode1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
calibrate_threshold1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
check_health1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Added
check_update - Changed
deep_check1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
delete_agent_data1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
delete_episode1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
delete_memory1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Added
get_session_findings - Changed
import_memories1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
lock_memory1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
merge_memories1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
migrate_channel_axis1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
pause_persistence1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
persistence_status1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
recall2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Per-retriever search depth, not a pure response cap (CSC #716): the value is handed to each retrieval channel (vector / episode FTS / keyword) as its top-K, so lowering it shrinks the candidate pool itself — rows beyond the depth are unreachable at any gate value, and score normalization / autocut operate on the smaller pool, which can also reorder what remains. Fewer rows than this may be returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.)"New value: +"Per-retriever search depth, not a pure response cap: the value is handed to each retrieval channel (vector / episode FTS / keyword) as its top-K, so lowering it shrinks the candidate pool itself — rows beyond the depth are unreachable at any gate value, and score normalization / autocut operate on the smaller pool, which can also reorder what remains. Fewer rows than this may be returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.)" - added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare — a partition hint, NOT authentication. It scopes this process's per-session state: the degraded-recall advisory's \"already told you\" memory, and which no-persist pause applies to this call. It does NOT filter stored data (use agent_id / project_id / channel for that), and it never reaches the database. Omit it to share one bucket with every other caller that omits it, which is the behaviour that predates this parameter.", + "type": "string" +}
- Changed
recall_with_context2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Per-retriever search depth for the underlying recall, not a pure response cap — same semantics as recall's limit (CSC #716): lowering it shrinks the candidate pool itself, not just the rows returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.)"New value: +"Per-retriever search depth for the underlying recall, not a pure response cap — same semantics as recall's limit: lowering it shrinks the candidate pool itself, not just the rows returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.)" - added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare — a partition hint, NOT authentication. It scopes this process's per-session state: the degraded-recall advisory's \"already told you\" memory, and which no-persist pause applies to this call. It does NOT filter stored data (use agent_id / project_id / channel for that), and it never reaches the database. Omit it to share one bucket with every other caller that omits it, which is the behaviour that predates this parameter.", + "type": "string" +}
- Changed
resume_persistence1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
set_recall_precision1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
store1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
unlock_memory1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
update_memory1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
- Changed
update_profile1 field changed- added
Input schema / properties / session_keyAdded value: +{ + "default": "", + "description": "Opaque session identity you declare: a partition hint, not authentication and not a data filter. Selects which no-persist pause applies to this call. Omit to share one bucket with every caller that omits it. Full text on recall.", + "type": "string" +}
2 tool updates
v2.5.6- Changed
recall1 field changed- changed
Input schema / properties / deep / descriptionPrevious value: -"Deep recall — disable time and completion decay for exhaustive search"New value: +"Deep recall — halves the quality gate (and the calibrated fused gate), so weaker matches are admitted. It also disables time and completion decay, which are inert unless CPERSONA_CONFIDENCE_ENABLED=true, and it does NOT widen the scan window (CPERSONA_MAX_MEMORIES) — deep is about how weak a match may be, not how far back the search reaches."
- Changed
recall_with_context1 field changed- changed
Input schema / properties / deep / descriptionPrevious value: -"Disable time decay"New value: +"Deep recall — same semantics as in `recall`: halves the quality gate so weaker matches are admitted."
5 tool updates
v2.5.4- Changed
calibrate_threshold1 field changed- added
Input schema / properties / method / enumAdded value: +[ + "separation", + "percentile", + "zscore" +]
- Changed
recall1 field changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max memories to return (agent-facing cap; the library layer accepts up to the scan window for direct callers)"New value: +"Per-retriever search depth, not a pure response cap (CSC #716): the value is handed to each retrieval channel (vector / episode FTS / keyword) as its top-K, so lowering it shrinks the candidate pool itself — rows beyond the depth are unreachable at any gate value, and score normalization / autocut operate on the smaller pool, which can also reorder what remains. Fewer rows than this may be returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.)"
- Changed
recall_with_context1 field changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max recalled memories (agent-facing cap; the library layer accepts up to the scan window for direct callers)"New value: +"Per-retriever search depth for the underlying recall, not a pure response cap — same semantics as recall's limit (CSC #716): lowering it shrinks the candidate pool itself, not just the rows returned. (Agent-facing cap; the library layer accepts up to the scan window for direct callers.)"
- Changed
store2 fields changed- changed
Input schema / properties / message / properties / source / properties / type / descriptionPrevious value: -"Producer role — this enum IS the contract; send one of these. Legacy producers that cannot are folded server-side at the write seam ('ai' / 'assistant' are normalized to 'Agent'; 'session' is normalized to 'System' (type words are matched case-insensitively)), and shapes outside that table are stored verbatim for check_health(invalid_source_type) to surface."New value: +"Producer role — send one of 'User', 'Agent', 'System'. Legacy producers that cannot are folded server-side at the write seam ('ai' / 'assistant' are normalized to 'Agent'; 'session' is normalized to 'System' (type words are matched case-insensitively)), and shapes outside that table are stored verbatim for check_health(invalid_source_type) to surface." - removed
Input schema / properties / message / properties / source / properties / type / enumRemoved value: -[ - "User", - "Agent", - "System" -]
- Changed
update_profile1 field changed- changed
Input schema / properties / profile / descriptionPrevious value: -"Profile text to save (pre-computed by caller)"New value: +"Profile text to save (pre-computed by caller). Capped at 2000 characters (CPERSONA_MAX_PROFILE_LENGTH); the response says truncated:true when the cap cut it."
17 tool updates
v2.5.2- Changed
archive_episode1 field changed- changed
Input schema / properties / project_id / descriptionPrevious value: -"v2.4.17 isolation axis. Omit or pass '' for the global pool."New value: +"v2.4.17 isolation axis. Omit or pass '' for the global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution."
- Added
calibrate_threshold - Added
check_health - Added
delete_episode - Added
delete_memory - Added
export_memories - Added
get_operating_context - Added
get_recall_precision - Changed
list_episodes1 field changed- changed
Input schema / properties / project_id / descriptionPrevious value: -"v2.4.17 γ filter. Same semantics as list_memories."New value: +"v2.4.17 γ filter. Same semantics as list_memories. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution."
- Changed
list_memories1 field changed- changed
Input schema / properties / project_id / descriptionPrevious value: -"v2.4.17 γ filter. Omit → no filter; '' → global pool only; 'X' → 'X' ∪ global pool."New value: +"v2.4.17 γ filter. Omit → no filter; '' → global pool only; 'X' → 'X' ∪ global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution."
- Added
pause_persistence - Added
recall - Added
recall_with_context - Added
resume_persistence - Changed
store4 fields changed- changed
Input schema / properties / message / properties / content / descriptionPrevious value: -"The text to store. Empty content is skipped."New value: +"The text to store. Content that is empty — or that sanitizes to empty — is refused with ok:false, result:'rejected'." - changed
Input schema / properties / message / properties / metadata / descriptionPrevious value: -"Free-form JSON object for producer-specific context. Empty when unused."New value: +"Free-form JSON object for producer-specific context. Empty when unused. Serialised size is capped at 8000 characters (same cap for source); an oversized field is refused with result='rejected' rather than truncated, because a truncated JSON document is not a JSON document." - changed
Input schema / properties / message / properties / source / properties / type / descriptionPrevious value: -"Producer role. 'Assistant' / 'ai' are normalized to 'Agent'; 'session' is normalized to 'System'."New value: +"Producer role — this enum IS the contract; send one of these. Legacy producers that cannot are folded server-side at the write seam ('ai' / 'assistant' are normalized to 'Agent'; 'session' is normalized to 'System' (type words are matched case-insensitively)), and shapes outside that table are stored verbatim for check_health(invalid_source_type) to surface." - changed
Input schema / properties / project_id / descriptionPrevious value: -"v2.4.17 isolation axis. Optional — omit or pass '' to store in the global pool. Reads via γ semantics: a recall with project_id='X' returns 'X' rows + global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (echoed as resolved_project_id)."New value: +"v2.4.17 isolation axis. Optional — omit or pass '' to store in the global pool. Reads via γ semantics: a recall with project_id='X' returns 'X' rows + global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (the resolution is echoed as resolved_project_id; an unmapped agent yields operating_context_warning). bug-186: resolution requires a configured operating context. With none — the default, and equally the outcome of a sidecar that fails to parse — the sentinel is NOT resolved: it is stored and filtered as the literal project_id '@auto', resolved_project_id echoes '@auto', and no warning is raised. Read resolved_project_id before relying on the resolution."
- Added
unlock_memory - Added
update_profile
15 tool updates
v2.5.1- Changed
archive_episode1 field changed- changed
Input schema / properties / history / descriptionPrevious value: -"Original conversation messages (used for timestamp extraction and embedding)"New value: +"Original conversation messages (used for start/end timestamp extraction; the episode embedding is computed from summary)"
- Removed
calibrate_threshold - Removed
check_health - Removed
delete_episode - Removed
delete_memory - Removed
export_memories - Added
get_contents - Removed
get_recall_precision - Removed
pause_persistence - Removed
recall - Removed
recall_with_context - Removed
resume_persistence - Changed
store3 fields changed- changed
Input schema / properties / message / descriptionPrevious value: -"ClotoMessage to store (id, content, source, timestamp, metadata)"New value: +"ClotoMessage to store. Legacy source shapes are normalized server-side where unambiguous (e.g. lowercase type words, Rust serde externally-tagged dicts, bare 'user'/'assistant' strings); unknown shapes are stored verbatim and surfaced by check_health(invalid_source_type)." - added
Input schema / properties / message / propertiesAdded value: +{ + "content": { + "description": "The text to store. Empty content is skipped.", + "type": "string" + }, + "id": { + "description": "Caller-supplied message id used for msg_id-based dedup (γ-project-scoped). Optional.", + "type": "string" + }, + "metadata": { + "description": "Free-form JSON object for producer-specific context. Empty when unused.", + "type": "object" + }, + "source": { + "description": "Attribution of who produced the content. Canonical shape is {type, id, name}. Type is the discriminator; id / name identify the concrete producer. Store null / empty {} only when the producer is genuinely unknown. A null source is normalized to {} at the write seam, so both persist (and recall) as the anonymous {}.", + "properties": { + "id": { + "description": "Stable producer id (e.g. discord user id, agent id). Empty when anonymous.", + "type": "string" + }, + "name": { + "description": "Human-readable label for display. Empty when unknown.", + "type": "string" + }, + "type": { + "description": "Producer role. 'Assistant' / 'ai' are normalized to 'Agent'; 'session' is normalized to 'System'.", + "enum": [ + "User", + "Agent", + "System" + ], + "type": "string" + } + }, + "type": "object" + }, + "timestamp": { + "description": "UTC ISO-8601 timestamp with offset (e.g. '2026-07-22T12:00:00+00:00'). Defaults to server-time UTC when omitted. Aware non-UTC offsets are accepted; naive strings are surfaced by check_health(timestamp_format_drift).", + "type": "string" + } +} - changed
Input schema / properties / project_id / descriptionPrevious value: -"v2.4.17 isolation axis. Optional — omit or pass '' to store in the global pool. Reads via γ semantics: a recall with project_id='X' returns 'X' rows + global pool."New value: +"v2.4.17 isolation axis. Optional — omit or pass '' to store in the global pool. Reads via γ semantics: a recall with project_id='X' returns 'X' rows + global pool. v2.5.1: pass '@auto' to resolve this agent's default from the server's operating context (echoed as resolved_project_id)."
- Removed
unlock_memory - Removed
update_profile
2 tool updates
v2.4.37- Changed
check_health1 field changed- added
Input schema / properties / checksAdded value: +{ + "description": "Registry check names to run (empty = all). See cpersona.checks.HEALTH_CHECK_NAMES.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
deep_check1 field changed- changed
Input schema / properties / checks / descriptionPrevious value: -"Checks to run (empty = all). Options: anonymous_source, short_content, stale_profile, orphaned_episodes"New value: +"Checks to run (empty = all). Options: anonymous_source, short_content, stale_profile, orphaned_episodes, calibration_staleness, near_duplicate"
13 tool updates
v2.4.34- Changed
archive_episode2 fields changed- added
Input schema / properties / channelAdded value: +{ + "description": "v2.4.22 conversation-channel tag (e.g. a Discord channel id). Default '' (= unscoped). Channel-scoped recall returns episodes whose channel matches; this powers the per-channel episodic loop.", + "type": "string" +} - added
Input schema / properties / project_idAdded value: +{ + "description": "v2.4.17 isolation axis. Omit or pass '' for the global pool.", + "type": "string" +}
- Changed
calibrate_threshold3 fields changed- added
Input schema / properties / methodAdded value: +{ + "description": "'percentile' (default), 'zscore', or 'separation' (two-population, learns the operating point from null vs nearest-neighbour positives)", + "type": "string" +} - added
Input schema / properties / percentileAdded value: +{ + "description": "Null-distribution quantile for method='percentile' (default: 0.95, higher = stricter)", + "type": "number" +} - changed
Input schema / properties / z_factor / descriptionPrevious value: -"Z-score multiplier (default: 1.0, higher = stricter)"New value: +"Z-score multiplier for method='zscore' (default: 1.0, higher = stricter)"
- Added
get_recall_precision - Changed
list_episodes1 field changed- added
Input schema / properties / project_idAdded value: +{ + "description": "v2.4.17 γ filter. Same semantics as list_memories.", + "type": "string" +}
- Changed
list_memories1 field changed- added
Input schema / properties / project_idAdded value: +{ + "description": "v2.4.17 γ filter. Omit → no filter; '' → global pool only; 'X' → 'X' ∪ global pool.", + "type": "string" +}
- Added
migrate_channel_axis - Added
pause_persistence - Added
persistence_status - Changed
recall2 fields changed- added
Input schema / properties / project_idAdded value: +{ + "description": "v2.4.17 γ filter. Omit → no filter (all projects). '' → global pool only. 'X' → 'X' bucket ∪ global pool. Threaded through cascade / RRF / vector / FTS / keyword paths.", + "type": "string" +} - added
Input schema / properties / source_idAdded value: +{ + "default": "", + "description": "v2.4.20 per-user source filter. Empty (default) = no filter. Non-empty = prefix match against json_extract(source, '$.id'), e.g. 'discord:12345' to restrict to one Discord user, or 'discord:' to scope to all Discord-sourced memories. Episodes are skipped when set (no per-user source tagging).", + "type": "string" +}
- Changed
recall_with_context2 fields changed- added
Input schema / properties / project_idAdded value: +{ + "description": "v2.4.17 γ filter — passed through to recall. Same semantics as in `recall`.", + "type": "string" +} - added
Input schema / properties / source_idAdded value: +{ + "default": "", + "description": "v2.4.20 per-user source filter — passed through to recall. Same semantics as in `recall`.", + "type": "string" +}
- Added
resume_persistence - Added
set_recall_precision - Changed
store1 field changed- added
Input schema / properties / project_idAdded value: +{ + "description": "v2.4.17 isolation axis. Optional — omit or pass '' to store in the global pool. Reads via γ semantics: a recall with project_id='X' returns 'X' rows + global pool.", + "type": "string" +}
6 tool updates
v2.4.10- Added
deep_check - Added
lock_memory - Changed
recall1 field changed- added
Input schema / properties / exclude_contentsAdded value: +{ + "description": "Normalized content strings to exclude from results (starts-with match). Used to prevent duplication with conversation context already known to the caller.", + "items": { + "type": "string" + }, + "type": "array" +}
- Added
recall_with_context - Added
unlock_memory - Added
update_memory
16 tool updates
v0.1.0- First observed
archive_episode - First observed
calibrate_threshold - First observed
check_health - First observed
delete_agent_data - First observed
delete_episode - First observed
delete_memory - First observed
export_memories - First observed
get_profile - First observed
get_queue_status - First observed
import_memories - First observed
list_episodes - First observed
list_memories - First observed
merge_memories - First observed
recall - First observed
store - First observed
update_profile
TDQS
Most tools have distinct purposes (store, recall, delete, lock, archive), but several memory-management and health-check tools overlap significantly (check_health/get_session_findings/deep_check, list_memories/recall, import_memories/merge_memories). The detailed descriptions help distinguish them, but an agent could still confuse check_health with deep_check or get_session_findings.
The majority of tools follow a clear verb_noun pattern (store, recall, list_memories, delete_memory, lock_memory, update_profile, pause_persistence). However, there are inconsistencies: some use adjective prefixes (deep_check, check_health, check_update, get_session_findings), some use with_/get_ prefixes irregularly, and tool names like recall vs recall_with_context vs get_contents are not perfectly parallel.
31 tools is heavy for a memory server. While the domain (memory storage, recall, episodes, profiles, health, persistence, channels, updates) is broad, several tools are niche or administrative (check_update, migrate_channel_axis, persistence_status) and could be consolidated; a 31-tool surface risks overwhelming agents and increases selection error. Still, each tool seems internally justified.
The memory lifecycle is well covered: create (store, archive_episode, import_memories), read (recall, get_contents, list_memories, get_profile), update (update_memory, update_profile), delete (delete_memory, delete_episode, delete_agent_data), plus lock/unlock, bulk operations, health checks, and persistence control. Minor gaps include no direct search by metadata or explicit forgetting-by-agent UI, and some health-repair actions must be done via other tools, but the core surface is comprehensive.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Persistent, outcome-grounded episodic memory for Claude. 14ms CPU retrieval, no GPU, no vector DB.
Persistent memory for AI agents. Semantic search, memory graph, W3C DID identity.
Persistent memory for AI agents across Claude, ChatGPT and any MCP client.
- AmberOAuthcom.ambermem
Long-term memory for AI assistants. Hybrid retrieval, query expansion, auto-topics.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenancePersistent AI memory server with 3-layer hybrid search (vector + FTS5 + keyword), confidence scoring via Reciprocal Rank Fusion, episodic/profile memory, and 16 tools. Zero LLM dependency. Works standalone with Claude Desktop and Claude Code. MIT licensed.3Business Source 1.1
- AlicenseAqualityAmaintenanceLocal-first memory for Claude Code and any MCP client: hybrid vector + keyword search and a bi-temporal knowledge graph in one SQLite file. Local embeddings, no API key, $0/token.512061PolyForm Noncommercial 1.0.0
- FlicenseNot gradedqualityDmaintenanceA lightweight MCP memory server built on SQLite + FTS5, providing cross-session long-term memory for Claude Code.-
- FlicenseNot gradedqualityDmaintenancePersistent memory server for AI assistants with semantic search and three-layer context (global, project, personality). Works with MCP-compatible AI tools like Claude Code, Cursor, Continue, Cline, and more.1-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Cloto-dev/CPersona'
If you have feedback or need assistance with the MCP directory API, please join our Discord server