CPersona
Officialcpersona
MCP-сервер памяти
Обеспечьте Claude постоянной памятью между сессиями. Один файл SQLite. 21 инструмент. Нулевая зависимость от LLM.
Быстрый старт · Возможности · Архитектура · Все инструменты · Книга Zenn (JP)
Автономный репозиторий — это автономная версия для использования с 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 (33 млн параметров, 768d, работает локально на 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 (вспомнить) это в более поздней сессии.
Возможности
Гибридный поиск — три независимые стратегии извлечения работают параллельно и объединяют результаты через Reciprocal Rank Fusion (RRF):
Уровень | Метод | Сила |
Векторный | Косинусное сходство (jina-v5-nano, 768d) | Семантический смысл |
FTS5 | Полнотекстовый поиск SQLite с триграммным токенизатором | Точные термины, имена, ID |
Ключевые слова | Резервное сопоставление с шаблоном | Краевые случаи, частичные совпадения |
Типы памяти:
Декларативная память — отдельные факты, решения, инструкции, сохраненные через
storeЭпизодическая память — архивированные сводки разговоров через
archive_episodeПрофильная память — накопленные атрибуты пользователя/проекта через
update_profile
Оценка достоверности — каждое извлеченное воспоминание получает оценку достоверности, объединяющую:
Косинусное сходство (семантическая релевантность)
Динамическое затухание во времени (адаптируется к временному диапазону корпуса — корпус годовой давности и корпус однодневной давности используют разные кривые затухания)
Ускорение извлечения (часто полезные воспоминания всплывают легче, с естественным затуханием)
Фактор завершенности (решенные темы затухают быстрее)
Нулевая зависимость от LLM — cpersona — это чистый сервер данных. Он никогда не вызывает LLM внутри себя. Вся суммаризация и извлечение выполняются вызывающим агентом. Это означает отсутствие затрат на API со стороны самой cpersona, детерминированное поведение и отсутствие скрытых задержек.
Дополнительные возможности:
Изоляция пространства имен агентов — несколько агентов используют одну БД без помех
Очередь фоновых задач — асинхронная обработка с сохранением в БД и возможностью восстановления после сбоев
Экспорт/импорт JSONL — полная переносимость памяти между средами
Объединение памяти между агентами — атомарное копирование/перемещение с дедупликацией
Автокалибровка — статистическая настройка порогов через z-оценку нулевого распределения (метки не нужны)
Проверка работоспособности — 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 (Long-term Memory Evaluation Benchmark, результаты) — 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 достигает улучшения на +47% по сравнению с базовым уровнем MiniLM.
Все инструменты
Инструмент | Описание |
| Сохранить сообщение в памяти агента |
| Извлечь релевантные воспоминания (вектор + FTS5 + ключевые слова, объединение RRF) |
| Получить текущий профиль агента |
| Сохранить предварительно вычисленный профиль агента |
| Архивировать эпизод разговора со сводкой и ключевыми словами |
| Список недавних воспоминаний |
| Список архивированных эпизодов |
| Удалить одно воспоминание (применяется владение) |
| Удалить один эпизод (применяется владение) |
| Удалить все данные для агента |
| Автокалибровка порога векторного поиска через z-оценку |
| Экспорт в JSONL (воспоминания, эпизоды, профили) |
| Импорт из JSONL (идемпотентно через дедупликацию msg_id) |
| Объединить данные одного агента с другим (атомарно, с дедупликацией) |
| Статус очереди фоновых задач |
| Извлечение с внешним контекстом разговора (автодедупликация) |
| Обновить содержимое памяти (отклоняется, если заблокировано) |
| Заблокировать память для предотвращения удаления/редактирования |
| Разблокировать память для разрешения удаления/редактирования |
| 16-точечная проверка работоспособности базы данных с автовосстановлением |
| Глубокий семантический анализ качества данных с автовосстановлением |
Конфигурация
Все настройки через переменные окружения с разумными значениями по умолчанию:
Переменная | По умолчанию | Описание |
|
| Путь к базе данных SQLite |
|
| Режим эмбеддингов ( |
|
| URL сервера эмбеддингов |
|
| Режим векторного поиска |
|
| Стратегия поиска ( |
|
| Параметр сглаживания RRF |
|
| Включить метаданные достоверности в результаты |
|
| Автокалибровка при запуске |
|
| Включить очередь фоновых задач |
|
| Штраф для недавно извлеченных воспоминаний |
|
| Окно (минуты) для штрафа за недавнее извлечение |
Статистика
~3,500 строк кода Python (один файл,
server.py)117 тестов в 12 тестовых модулях
Схема v8 (автоматическая миграция)
Лицензия MIT
Работает с
cpersona — это MCP-сервер, он работает с любым MCP-совместимым хостом:
ClotoCore (платформа ИИ-агентов, где зародилась cpersona)
Любой пользовательский MCP-клиент
Часть ClotoCore
cpersona — это уровень памяти ClotoCore, платформы ИИ-агентов с открытым исходным кодом, написанной на Rust. Хотя cpersona полностью автономна (лицензия MIT), она была разработана для предоставления ИИ-агентам постоянной памяти с возможностью поиска в экосистеме ClotoCore.
Узнать больше
Книга Zenn (на японском) — Полное руководство по проектированию и настройке
Дизайн системы памяти — Техническая спецификация
ClotoCore — Платформа ИИ-агентов
Лицензия
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