Skip to main content
Glama

herald

Канал наружу. Ассистент отправляет готовый материал — текст, таблицу, файл, скриншот — в твой рабочий мессенджер, откуда ты пересылаешь его дальше.

Статус: рабочая версия: отправка сообщений через MCP и захват рабочих чатов в локальный буфер.


Зачем

Две причины, и вторая важнее.

Очевидная. Таблицы, длинные разборы и скриншоты копируются из терминала криво. Форматирование рассыпается, картинку вообще не скопируешь. Ты говоришь «отправь это в такой-то топик» — и материал приходит целым.

Неочевидная: это чинит авторство.

Сейчас, когда ты вручную пересылаешь текст ассистента в рабочий чат, он уходит под твоим именем. В выгрузке эти сообщения неотличимы от твоих собственных — ни пометки, ни поля. Проверено на живом чате: тринадцать сообщений от одного автора, часть из которых написана машиной, и различить их можно только по стилю. Догадка по стилю — это ровно то, что запрещает mnemo: не угадывать.

Если пишет бот, а ты пересылаешь его сообщение — Telegram сохраняет forwarded_from с именем бота. Машинный текст становится машинно опознаваемым. Автоматически, без меток и дисциплины.

Related MCP server: telegram-commandcode

Устройство

Ядро — MCP-сервер с токеном и транспортом. Небольшой общий скилл поверх него учит Claude/Codex выбирать структурированную команду и соблюдать стиль.

ассистент ──MCP──> herald ──адаптер──> Telegram (топик группы)
                              │
                              └──> другие платформы, когда появятся

Интерфейс узкий: «отправить <это> в <туда>». Внутри — один адаптер под Telegram.

Абстракцию под платформы заранее не строим. Интерфейс появляется, когда платформ становится две, а не в ожидании второй. Так вышло с парсерами в mnemo: реестр завели на втором формате, и он сразу был правильной формы, потому что опирался на два реальных случая, а не на догадку об одном.

Безопасность — свойством, а не процедурой

herald пишет только в твой стейджинг. Начальству пересылаешь ты, руками.

Это сильнее, чем «бот с подтверждением»: он физически не может отправить что-то не то в чат с заказчиком, потому что не знает туда дороги. Гарантия структурная, а не «мы договорились подтверждать».

Правило: список разрешённых адресатов задаётся в конфиге и не расширяется ассистентом.

Что нужно для запуска

  • токен бота (BotFather), хранится вне репозитория;

  • идентификатор группы-стейджинга и карта топиков «имя → id»;

  • бот добавлен в группу с правом писать.

Первая версия

Сейчас herald — локальный Python MCP-сервер со stdio-транспортом. Он предоставляет десять команд:

  • list_destinations — посмотреть разрешённые проекты и их маршруты;

  • send_client_copy — готовый для пересылки клиенту текст с реальными темами вместо служебных разделов;

  • send_update — внутренний управленческий апдейт из отдельных полей;

  • send_file — отправка файла или изображения из разрешённого каталога;

  • send_text — ручная отправка точного или нестандартного текста;

  • notify_completion — уведомление о завершении задачи, когда у задачи явно установлен такой флаг или дана такая инструкция.

  • inbox_status, inbox_fetch, inbox_export, inbox_done — состояние, чтение, выдача и подтверждение локального буфера захваченных сообщений.

Команды проходят один путь: проект → маршрут → адаптер → Telegram. Сам herald не наблюдает за задачами и не решает, когда уведомлять: это делает Codex, Claude или их lifecycle-hook.

Каждое сообщение получает компактную подпись:

— Codex · GPT · herald · MCP

Установка плагином

Нужен установленный uv. Плагин приносит один и тот же MCP-сервер и один и тот же skill в Claude Code и Codex: отдельные mcp add, симлинки и копии навыка не нужны.

Claude Code:

claude plugin marketplace add ZenonEl/herald
claude plugin install herald@herald --scope user

Codex:

codex plugin marketplace add ZenonEl/herald
codex plugin add herald@herald

После установки открой новую сессию. Установленный skill называется herald:herald-send: в Claude Code его можно вызвать как /herald:herald-send, в Codex — как $herald:herald-send. Обычная просьба «отправь через Herald» также должна активировать его по описанию.

Плагин не содержит токен и рабочие адресаты. Создай пользовательский конфиг:

mkdir -p ~/.config/herald
curl -fsSL https://raw.githubusercontent.com/ZenonEl/herald/main/config.example.toml \
  -o ~/.config/herald/config.toml
printf '%s\n' 'TOKEN_FROM_BOTFATHER' > ~/.config/herald/telegram.token
chmod 600 ~/.config/herald/telegram.token

Открой ~/.config/herald/config.toml и замени пример своими разрешёнными группами, топиками и проектами. Проверить подключение можно просьбой «покажи направления Herald» в новой Claude/Codex-сессии.

Обновление плагина

Claude Code:

claude plugin marketplace update herald
claude plugin update herald@herald --scope user

Codex:

codex plugin marketplace upgrade herald
codex plugin add herald@herald

После обновления тоже нужна новая сессия: уже открытая продолжает работать со старым набором skill/MCP-инструментов.

Если Herald раньше подключался вручную, перед установкой плагина убери старую MCP-запись командами codex mcp remove herald и claude mcp remove herald. Проверь старые пути ~/.agents/skills/herald-send и ~/.claude/skills/herald-send: если это именно символические ссылки на checkout, удали ссылки через unlink, не затрагивая сам репозиторий. Пользовательский ~/.config/herald/ при миграции сохраняется.

Конфиг и версии

Проект использует uv. Версия Python зафиксирована в .python-version, версия пакета и зависимости — в pyproject.toml, точные версии — в uv.lock.

Версии следуют Semantic Versioning: pyproject.toml — SSOT версии пакета, менять её нужно через uv version --bump patch|minor|major. Каждый публичный выпуск получает подписанный тег vX.Y.Z, GitHub Release и запись в CHANGELOG.md; версия тега обязана совпадать с project.version. Тесты дополнительно сверяют версию пакета с обоими плагин-манифестами и marketplace Claude Code.

В ~/.config/herald/config.toml задаются платформы, разрешённые маршруты, проекты и каталоги файлов. Это SSOT: MCP-команда может выбрать только существующий маршрут, а файл — только путь внутри allowed_roots. Конфиг перечитывается перед каждым вызовом, поэтому после добавления проекта или топика сервер перезапускать не нужно. Telegram-токен по умолчанию читается из отдельного файла:

printf '%s\n' 'TOKEN_FROM_BOTFATHER' > ~/.config/herald/telegram.token
chmod 600 ~/.config/herald/telegram.token

Сам токен и рабочий конфиг не хранятся в репозитории. Вместо файла можно задать token_env = "HERALD_TELEGRAM_BOT_TOKEN" в секции платформы.

Чтобы узнать chat_id и topic_id, добавь бота в staging-группу, отправь сообщение в нужный топик и посмотри ответ getUpdates: message.chat.id — это chat_id, а message.message_thread_idtopic_id.

Проект задаёт маршрут по умолчанию:

[routes.demo-shop]
platform = "telegram"
chat_id = "-1001234567890"
topic_id = 2

[projects.demo-shop]
label = "Demo Shop"
description = "Демонстрационный интернет-магазин и относящиеся к нему материалы."
route = "demo-shop"

[files]
allowed_roots = ["~/Herald/outbox"]
max_bytes = 50000000

Создай каталог ~/Herald/outbox и клади туда только то, что разрешено отправлять ассистенту. Не открывай ему целиком домашний каталог или все рабочие репозитории: среди них часто лежат .env, ключи и клиентские данные.

Обычно ассистент передаёт только project = "demo-shop"; поле route нужно лишь для явного переопределения. subject — краткая тема для подписи сообщения, а не Telegram topic_id.

Форматирование

Формат нужно выбрать явно: plain либо html. Для обычного сообщения человеку предпочтителен format = "html"; herald добавит parse_mode = "HTML". Поддерживаются теги Telegram вроде <b>, <i>, <u>, <s>, <tg-spoiler>, <a href="…">, <code>, <pre> и <blockquote>. Служебная подпись и ссылка экранируются самим herald, HTML основного текста передаётся как есть.

Если при format = "html" передать экранированные теги вроде &lt;b&gt;, herald отклонит вызов и подскажет передать сырой <b>. Это не даёт ассистенту молча прислать видимые HTML-теги вместо форматирования.

Пресеты сообщения

Для send_update сервер сам собирает HTML из полей summary, completed, blockers, decisions_needed, client_questions и next_steps, экранирует значения и проверяет длину каждого пункта. Это основной путь для статусов и отчётов: модель не присылает готовую портянку.

Поле preset задаёт плотность материала:

  • brief — режим по умолчанию: самодостаточный текст для клиента простым языком, один результат и только необходимые вопросы или действия, без внутренней кухни и жаргона;

  • standard — компактное структурированное сообщение;

  • detailed — полный отчёт с разделами и деталями.

Для send_update, send_text и notify_completion по умолчанию используется brief. В нём итог ограничен 180 символами, каждый пункт — 140 символами, а всё сообщение — пятью пунктами. send_text остаётся свободной формой. Перед отправкой проверяется лимит Telegram: не более 4096 отображаемых символов с учётом HTML-разметки. Автоматического разбиения длинного HTML в этой версии ещё нет.

Если нужно раскрыть вариант, процесс или функцию, skill использует send_text: название объекта, затем полный перечень необходимых шагов, свойств, результата и ограничений. Краткость в этом режиме убирает рассуждения и обобщения, но не факты.

Тема запроса служит жёсткой границей сообщения. Вопрос клиенту добавляется, только если ответ ещё неизвестен, находится у клиента и без него нельзя выполнить ближайшее действие по этой теме. Побочные проблемы проекта и вопросы о более поздних шагах не добавляются.

Перед формулировкой вопроса skill строит цепочку зависимостей и выбирает первое неизвестное решение, которым управляет клиент. Готовый текст обращается напрямую к клиенту; внутренние формулировки вроде «заводить ли заказчице доступ» запрещены. Пары примеров находятся в skills/herald-send/references/decision-examples.md.

send_client_copy является основным путём для сообщений, которые начальство пересылает клиенту. Заголовки задаются содержанием обращения или проекта, например Пункт СДЭК, Фотографии или Оплата. Сервер отклоняет фиксированные заголовки внутреннего отчёта вроде Проблемы, Нужно решить и Вопросы. Жёсткого лимита слов, тем или фактов нет: сохраняются все нужные клиенту сведения, пока сообщение помещается в лимит Telegram на 4096 видимых символов.

send_file в режиме auto отправляет небольшие JPEG/PNG/WebP как фотографию, остальное — как документ. Подпись ограничена 1024 отображаемыми символами; документ — настроенным лимитом до 50 МБ.

Ручное подключение из checkout

Этот способ нужен для разработки или установки без marketplace. Не смешивай его с установкой плагина: иначе клиент увидит две копии skill или два MCP-сервера.

git clone https://github.com/ZenonEl/herald.git
cd herald
uv sync --locked
mkdir -p ~/.config/herald
cp config.example.toml ~/.config/herald/config.toml

Используй абсолютный путь к checkout, чтобы сервер был доступен из любого проекта и нового чата.

Codex (пользовательский ~/.codex/config.toml):

codex mcp add herald -- uv run --directory /absolute/path/to/herald herald

Claude Code (важен scope user, а не default local):

claude mcp add --scope user herald -- \
  uv run --directory /absolute/path/to/herald herald

После добавления открой новые сессии. Проверка:

codex mcp get herald
claude mcp get herald

Общий skill лежит в skills/herald-send. При ручной установке обе системы могут использовать один источник через символические ссылки:

mkdir -p ~/.claude/skills ~/.agents/skills
ln -s /absolute/path/to/herald/skills/herald-send ~/.claude/skills/herald-send
ln -s /absolute/path/to/herald/skills/herald-send ~/.agents/skills/herald-send

В таком режиме без plugin namespace он вызывается как /herald-send в Claude Code и $herald-send в Codex. Инструкция предлагает применить доступный humanizer, но не требует и не копирует его: если такого скилла нет, отправка продолжается по встроенному чек-листу.

Разработка

uv run pytest

Тесты не обращаются к Telegram: HTTP-ответы подменяются локально, а MCP-контракт проверяется in-memory клиентом официального SDK.

Место в связке

Проект

Роль

mnemo

архив материала с провенансом + факты, решения, вопросы

ephemeris

дейлики: состояние и синк в issues

herald

канал наружу к людям

herald ничего не хранит. Он отправляет то, что ему дали, и не знает, откуда это взялось. Связь с остальными — только через ссылку на запись в тексте сообщения (см. ниже): отправил разбор — вставил ссылку, по которой видно, на каком материале он стоит.

Захват рабочих чатов

Вторая половина того же канала: herald не только отправляет наружу, но и вычитывает рабочие группы в локальный буфер, откуда ассистент забирает их сам — вместо ручного копирования сообщений, файлов и скриншотов.

Смысл не в удобстве. Копипаста из Telegram подписывает пересланное сообщение тем, кто его переслал; Bot API отдаёт настоящего автора, если тот не скрыл себя. На живом рабочем чате это разница в 16 сообщениях из 21.

Захват сейчас рассчитан на Unix (flock); готовый сервис — на Linux с systemd. Обычная отправка через MCP от systemd не зависит.

Что нужно от Telegram

  • бот добавлен в рабочую группу;

  • privacy-режим выключен у BotFather — иначе бот видит только команды и ответы себе. Настройка применяется лишь после переприглашения бота в группу;

  • право «отправлять сообщения» можно снять: читать это не мешает, а случайно написать в рабочий чат станет нечем.

Пределы, которые не обходятся

  • истории нет. Бот не прочитает ни одного сообщения, отправленного до того, как его добавили. Всё, что было раньше, вносится выгрузкой чата;

  • очередь живёт около суток. Простой меньше суток демон догоняет сам, дольше — сообщения потеряны. Отсюда Restart=always и heartbeat в inbox_status;

  • скачивание до 20 МБ. Больший файл записью не теряется: остаётся строка с пометкой, что скачать не удалось, и оригинал в Telegram.

Настройка захвата

Marketplace-плагин автоматически подключает MCP и skill, но не запускает фоновый процесс. Для постоянного capture нужен стабильный checkout репозитория: путь внутри plugin-cache меняется при обновлении. Клонируй Herald вручную, настрой тот же пользовательский конфиг и запускай демон из checkout.

В ~/.config/herald/config.toml (или в файле, на который указывает HERALD_CONFIG — им же удобно пробовать, не трогая боевой):

[capture]
enabled = true            # в поставляемом примере false, иначе демон откажется стартовать
ttl_days = 7
capture_self = true       # твои собственные сообщения тоже нужны: половина
                          # договорённостей звучит в твоих же ответах
# self_id = 123456789     # обязателен, только если capture_self = false

[[capture.chats]]
id = -1001234567890       # ЧИСЛО, без кавычек — в отличие от chat_id в [routes]
topic_id = 42             # необязательно: захватывать только этот топик форума
slug = "demo-shop"        # войдёт в ссылки ctx: и в имя каталога буфера

Можно перечислить несколько топиков одной группы отдельными блоками с разными topic_id и slug. Если задан topic_id, сообщения из общего чата и других топиков не сохраняются. Запись без topic_id захватывает весь чат; смешивать её с отдельными топиками того же чата конфиг не разрешит.

Секции [routes] и [projects] для захвата не нужны — конфиг может быть только читающим. А вот [platforms.telegram] с токеном нужен всегда: читать без токена нельзя, даже если отправлять нечего.

chat_id берётся из getUpdates, но демон опрашивает тот же токен, а двух опросов Telegram не допускает. Поэтому узнавай id до запуска демона или остановив его.

Запуск

uv run herald-capture --once   # один опрос и выход: проверить настройку
uv run herald-capture          # рабочий режим

Демон один: два опроса на один токен Telegram отвергает, поэтому второй экземпляр честно откажется стартовать. Лок берётся по токену, а не по базе, и лежит в ~/.local/share/herald/locks: это общий путь для systemd с PrivateTmp и ручного --once. Отправка при этом не мешает — конфликтует только опрос с опросом.

Готовый юнит — herald-capture.service в корне репозитория:

cp herald-capture.service ~/.config/systemd/user/
$EDITOR ~/.config/systemd/user/herald-capture.service
systemctl --user daemon-reload
systemctl --user enable --now herald-capture

В юните поправь под себя:

  • ExecStart — путь к клону (в файле стоит %h/GitHub/herald);

  • ReadWritePaths — если менял database или files_dir, иначе ProtectSystem=strict не даст туда писать;

  • Environment=HERALD_CONFIG=… — если конфиг лежит не по умолчанию.

Пути в конфиге меняются только с рестартом. Демон открывает базу и каталог файлов один раз; подхватывать их на лету значило бы, что он пишет в старую базу, пока ассистент читает новую и видит пустой буфер. Про смену пути в логе будет предупреждение. Всё остальное — список чатов, enabled, TTL — действует сразу.

Что видит ассистент

Команда

Что делает

inbox_status

объём буфера по чатам и heartbeat демона, без содержимого

inbox_export

основной путь: самодостаточный каталог для импорта в архив

target — обязательно новый каталог; повтор в тот же отвергается

include_taken — пересобрать пачку, отданную раньше и не дошедшую до архива

inbox_fetch

только строки, без копирования файлов — почитать текст

inbox_done

зафиксировано в архиве → удаляет скачанные копии, строка живёт TTL

Инструменты видны всегда, но при capture.enabled = false отвечают отказом.

Ответы сохраняются вместе с reply_to и структурированным reply_context: автором, датой, полным текстом/caption родителя, метаданными вложения и точной выделенной цитатой (quote). Если родитель находится в разрешённом топике, Herald добавляет его в буфер отдельной записью и скачивает доступное вложение. Так ответ на старое сообщение может донести его в архив даже если бот вступил в чат позже. Произвольно читать историю бот не может: Telegram передаёт только одного непосредственного родителя нового ответа.

Контекст из топика, которого нет в [[capture.chats]], целиком не сохраняется: остаётся только явно показанная в разрешённом сообщении цитата. Для внешнего ответа Telegram не отдаёт полный текст; Herald фиксирует доступные origin, id, метаданные вложения и цитату, но не пытается выдать их за исходное сообщение.

Как захваченное попадает в архив

inbox_export пишет каталог такого вида:

bundle/
├── inbox.json          строки сообщений; local_path — ОТНОСИТЕЛЬНЫЙ путь
└── files/<slug>/…      сами вложения

Относительность здесь не деталь: архив обязан отвергать источник, который адресует что-либо вне своего каталога, — правило существует потому, что выгрузки приходят от третьих лиц. Отдавать сырые строки с абсолютными путями значит получить все вложения в статусе «пропало» при живых файлах на диске.

Дальше — обычный импорт в mnemo:

python3 …/mnemo/scripts/mnemo_import.py --export _chat-export --source bundle
python3 …/mnemo/scripts/mnemo_import.py --export _chat-export --source bundle --apply

Строка сообщения. Обязательные поля — без любого из них архив откажется принять каталог, и это намеренно: без author_name импорт прошёл бы, подписав все сообщения как «неизвестно», а тихая порча хуже честного отказа.

Поле

Обяз.

Значение

chat_id

да

числовой id чата

message_id

да

номер сообщения; уникален внутри чата

chat_slug

да

тема; из него берётся slug экспорта

date

да

ISO-8601 с зоной

author_name

да

кто отправил (не обязательно автор — см. origin_type)

origin_type

нет → написал отправитель; user → переслано, автор известен; hidden_user / chat / channel → автор не установлен

origin_name

показанное имя; автором не считается, когда origin_type не user

origin_id, origin_date

нет

id и время оригинала пересылки

media_kind

нет

voice · photo · document · video … — задаёт зону RAW

file_id

нет

есть вложение; вместе с пустым local_path даёт запись «не добыт»

file_name, mime, size

нет

как прислал Telegram

local_path

нет

путь внутри каталога выгрузки либо null

media_note

нет

почему файла нет — попадает в архив, а не теряется

author_username, reply_to, topic_id

нет

как есть

reply_context

нет

снимок родителя/внешнего ответа и точная цитата

Один каталог — один чат: номера сообщений в разных чатах повторяются, и смешение молча теряло бы часть. inbox_export отказывается собирать пачку из нескольких чатов.

Буфер — не архив. Он неполон (нет истории, нет удалений) и живёт неделю; разбираться, что из этого нужно, — работа архива, а не буфера.

Ссылки на записи

Единый формат цитирования для всей связки:

ctx:<slug>#<id>          ctx:demo-shop#i004   ctx:meetings#q012

ctx — от «context», а не от имени инструмента. Программа, которая ведёт архив, может смениться; ссылка не должна от этого умирать. slug — тема (экспорт), id — запись внутри неё: i материал, q вопрос, t требование, r изъятие.

Нормативное описание — mnemo/SPEC/CITATION.md.

Общего у трёх проектов — три опубликованных версионированных формата: ссылка, манифест и контракт чтения. Ничего исполняемого: ни библиотеки, ни базы, ни общего процесса. Тот, кому нужны данные архива, вызывает команду mnemo и получает JSON — так же, как herald вызывает Telegram.

Лицензии

Репозиторий лицензирован по частям:

Путь

Лицензия

README.md и skills/herald-send/references/ — документация и текстовые материалы

CC BY-SA 4.0

всё остальное — сервер, capture, MCP, навык, конфиг и тесты

AGPL-3.0-or-later

Для производных редакций документации нужны указание авторства, отметка об изменениях и та же лицензия. Для изменённой сетевой версии Herald пользователям должен быть доступен соответствующий исходный код. Сообщения, файлы и другие пользовательские материалы, проходящие через Herald, этими лицензиями не перелицензируются.

Available Tools

10 tools
inbox_doneA

Mark messages as archived, which deletes their downloaded copies.

Call this only after the messages are in the archive with their hashes: the buffer copy of a file is redundant from that moment and is what actually grows on disk. Each key is {"chat_id": int, "message_id": int}. Rows survive for the configured TTL so a mistake stays recoverable.

ParametersJSON Schema
NameRequiredDescriptionDefault
keysYes

TDQS

A4.2/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description states 'deletes their downloaded copies,' which is a destructive action, but the annotations declare destructiveHint: false. This is a direct contradiction. The additional note about TTL recovery does not reconcile the mismatch, so the behavioral information is misleading.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place. The main action is front-loaded, followed by a usage condition and a recovery note. There is no fluff or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, precondition, parameter shape, and persistence behavior (TTL). It provides enough detail for an agent to invoke the tool correctly, even without an output schema, and the only significant gap is the annotation contradiction which is already flagged.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema only defines 'keys' as an array of objects with additionalProperties: true. The description adds essential semantics: 'Each key is {"chat_id": int, "message_id": int}. This precisely specifies the required structure, compensating fully for the 0% schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Mark messages as archived, which deletes their downloaded copies.' It uses a specific verb and resource, and the context about buffer copy redundancy distinguishes it from sibling tools like inbox_fetch or inbox_export.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Call this only after the messages are in the archive with their hashes' and explains why (the buffer copy is redundant and grows on disk). This provides a clear precondition and rationale, effectively telling the agent when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inbox_exportA

Write a self-contained folder for a range, ready to import into an archive.

Prefer this over inbox_fetch whenever the messages are going into the archive: it copies the attachments next to inbox.json and rewrites their paths to be relative, which is the only form an archive will accept. Passing raw rows instead files every attachment as missing while the bytes are still on disk. Messages are marked taken; call inbox_done once they are recorded.

target must be a fresh directory. Set include_taken to rebuild a bundle for messages handed out earlier but never archived - that is the only route by which their attachments can still reach the archive.

ParametersJSON Schema
NameRequiredDescriptionDefault
chatNo
limitNo
sinceNo
untilNo
targetYes
include_takenNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses key behavioral traits beyond the annotations: it copies attachments next to inbox.json and rewrites paths to relative, marks messages as taken, requires target to be a fresh directory, and warns about the consequence of passing raw rows (attachments marked missing). These are side effects and preconditions not captured in the schema or annotations, providing rich transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured. It opens with a one-sentence summary, then elaborates with focused paragraphs on usage, workflow, and key parameter requirements. Every sentence adds value, with no fluff or redundancy. The inclusion of a warning (raw rows) and edge-case handling (include_taken) is packed efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 params, no output schema) and the rich annotations, the description covers the essential aspects: what the tool produces (a self-contained folder), when to use it (archiving), how it integrates with other tools (inbox_done), critical parameter constraints, and a failure mode. This is complete for the intended use case and leaves minimal gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has no parameter descriptions (0% coverage), so the description must compensate. It adds crucial semantics for target ('must be a fresh directory') and include_taken ('rebuild a bundle... only route by which attachments can still reach the archive'). However, it does not explain chat, limit, since, or until beyond their names, leaving their meaning and usage partially implicit (e.g., 'range' hints at since/until). While some parameters are covered, the incomplete compensation for the schema gap warrants a mid-range score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear, specific action: 'Write a self-contained folder for a range, ready to import into an archive.' It explicitly contrasts with inbox_fetch, stating 'Prefer this over inbox_fetch whenever the messages are going into the archive,' which distinguishes its purpose from the sibling tool. The verb 'write' and resource 'folder' make the operation unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: 'Prefer this over inbox_fetch whenever the messages are going into the archive.' It also instructs on the required workflow ('call inbox_done once they are recorded') and when to set include_taken ('rebuild a bundle for messages handed out earlier but never archived'). This is comprehensive and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inbox_fetchA

Fetch buffered messages for a time range and mark them as taken.

since and until are ISO-8601 timestamps compared against the message date in UTC. Rows carry the forwarded-message origin, so a forwarded quote keeps its real author instead of the person who forwarded it. Fetching does not remove anything: call inbox_done once the messages are recorded in the archive.

Set include_taken to see messages handed out earlier but never archived - that is how a batch interrupted halfway is recovered.

ParametersJSON Schema
NameRequiredDescriptionDefault
chatNo
limitNo
sinceNo
untilNo
include_takenNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses the side effect of marking messages as taken, consistent with readOnlyHint=false and idempotentHint=false. Clarifies non-destructive behavior ('Fetching does not remove anything') and adds forwarded-message origin context. Slight gap: no mention of error conditions, but the key behavioral traits are covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with purpose, then critical details. No filler; each sentence earns its place. The structure logically progresses from core action to workflow to recovery use case.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the main workflow, time-range semantics, and recovery scenario. Has an output schema, so return values need no explanation. Missing explicit guidance on chat and limit parameters, but these are relatively self-explanatory from the schema names.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema coverage, the description must compensate. It explains since/until as ISO-8601 UTC timestamps and include_taken's purpose. However, chat and limit are left undescribed; limit may be inferred as a count, but chat's role is only implicit from the message context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Fetch buffered messages for a time range and mark them as taken.' This clearly states the tool's function and distinguishes it from siblings like inbox_done (archive/completion) and inbox_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs the workflow: 'call inbox_done once the messages are recorded in the archive.' Also explains the include_taken flag as a recovery mechanism for interrupted batches. This provides clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inbox_statusA
Read-onlyIdempotent

Summarise what the capture daemon has buffered, without fetching content.

Check this before inbox_fetch: it reports volume per chat and the age of the oldest unprocessed message, so a range can be chosen deliberately. last_poll is the daemon's heartbeat - if it is hours old the daemon is down and Telegram will start dropping undelivered updates after about a day.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive, and the description reinforces and expands on this by noting it works 'without fetching content' and explaining output semantics (volume, age, heartbeat). The last_poll explanation adds significant operational context beyond the annotations, clarifying what the tool reveals about daemon status and potential message loss.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well-structured: the first sentence succinctly states the core purpose, the second provides targeted usage guidance, and the third gives critical daemon-health context. Every sentence adds value, and the information is front-loaded with the most essential detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema and no parameters, the description is fully self-contained. It tells the agent what the tool does, when to use it, what to look for, and how to interpret a potential failure state. This is complete for the tool's simple read-only nature and integrates well with the sibling tool list.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, so there is no parameter complexity to explain. Per the rubric, 0 parameters earns a baseline of 4. The description does not mention parameters, which is appropriate since none exist, and it adds no unnecessary parameter-related text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool summarizes the capture daemon's buffered content without fetching it, using a specific verb and resource. It differentiates from siblings by explicitly saying 'Check this before inbox_fetch', establishing its role as a status/inspection tool distinct from fetching or sending.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides excellent usage guidance: when to use ('before inbox_fetch'), what information it provides (volume per chat, age of oldest message), and how to interpret the daemon's health (last_poll heartbeat with a concrete failure condition). This is exactly the contextual information an agent needs to decide when to call this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_destinationsA
Read-onlyIdempotent

List allowed projects and their default Telegram destinations.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, covering the safety profile. The description adds contextual detail ('allowed projects', 'default destinations') but does not disclose behavioral traits beyond that, such as ordering or filtering behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the action and subject. Every word adds value, with no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, zero-parameter list tool with annotations covering safety and an output schema available, the description fully communicates the tool's purpose. The mention of 'allowed projects' and 'default Telegram destinations' gives sufficient context for invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so schema coverage is trivially 100%. No parameter descriptions are needed, and the description does not attempt to over-explain. The baseline for zero-parameter tools is 4, and nothing lowers it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('allowed projects and their default Telegram destinations'), clearly distinguishing this tool from sibling send/inbox operations. It unambiguously states what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: call this to discover permitted destinations. However, it does not explicitly state when to use it over alternatives or provide exclusions, so guidance remains implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

notify_completionA

Send a concise formatted completion notice when explicitly requested.

Prefer format='html' and raw Telegram HTML tags, never escaped tag text. Use brief by default and state the concrete completed result without an emoji, greeting, or generic "done" preface. Select standard or detailed only when the user explicitly requests more context.

ParametersJSON Schema
NameRequiredDescriptionDefault
agentYes
modelYes
routeNo
formatYes
presetNobrief
projectYes
subjectYes
summaryYes
referenceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations indicating a non-read-only, non-destructive action, the description adds valuable behavioral details: never send escaped HTML, avoid emoji/greetings/'done' prefaces, and state concrete results. These formatting rules go beyond what annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences long, front-loaded with the primary action, and each sentence provides actionable guidance without wordiness. It is an excellent model of conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity and existence of an output schema, the description covers core usage and formatting behavior well. It does not explain all parameter purposes or contrast with siblings, but it provides enough practical context for a notification tool. A slightly lower score would be warranted if the parameter set were more complex.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 0% description coverage for parameters. The description compensates for the 'format' and 'preset' parameters by explaining when to use each, and 'summary' is implicitly linked to 'state the concrete completed result.' However, the other six parameters (agent, model, project, subject, route, reference) remain unexplained, leaving significant gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states it sends a 'concise formatted completion notice' when explicitly requested. This distinguishes it from sibling messaging tools by specifying the completion-notice purpose and the conditional trigger.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: use 'brief' preset by default, choose 'standard' or 'detailed' only when user requests more context, and prefer HTML format. Although it does not name alternative sibling tools, it clearly defines when to use this tool versus over-use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_client_copyA

Send copy-ready text addressed directly to the client.

This is the default tool when a manager should be able to copy the body without understanding the project or rewriting it. Each topic title must be a concrete subject taken from the client message or current project, such as "Оплата" or "Фотографии". Never use fixed report headings such as "Проблемы", "Нужно решить", or "Вопросы". Preserve all subjects raised by the client that are inside the requested scope; brevity removes internal reasoning, not necessary facts.

Put concrete facts, proposals, and next actions in details. Address the client directly. Add question only when its answer blocks the next action now, and ask only the earliest unresolved dependency. Omit question when no answer is needed. Do not shorten by a fixed word or item count. Keep all facts the client needs; the only hard content limit is Telegram's 4096 visible characters.

ParametersJSON Schema
NameRequiredDescriptionDefault
agentYes
modelYes
routeNo
topicsYes
projectYes
subjectYes
referenceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses important behavioral traits beyond annotations: it preserves all client subjects, removes only internal reasoning, requires questions only when they block the next action, and enforces a 4096-character limit. It also clarifies that brevity is not achieved by fixed counts, which is non-obvious behavior. This complements the annotations (readOnlyHint=false, etc.) without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence serves a purpose: purpose, usage context, and specific formatting rules. It is front-loaded with the core purpose, followed by actionable guidelines. No word is wasted given the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, usage, content constraints, question policy, and the hard length limit. It references context ('client message or current project') and specifies Telegram. With an output schema available, return values need not be described. The tool is complex, but the description is thorough enough for an agent to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description provides rich semantics for the nested ClientTopic fields, explaining that titles must be concrete subjects, details should contain facts/proposals/actions, and questions have conditional rules. However, it does not address top-level parameters like project, subject, agent, model, route, or reference, leaving those to schema names. Given 0% schema description coverage, the partial compensation is strong but incomplete, warranting a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Send copy-ready text addressed directly to the client,' a specific verb+resource that clearly states the tool's function. It further distinguishes itself as 'the default tool when a manager should be able to copy the body without understanding the project or rewriting it,' separating it from siblings like send_update or send_text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: 'when a manager should be able to copy the body without understanding the project or rewriting it.' This implies when not to use (when understanding/rewriting is needed). It also provides detailed content rules, such as requiring concrete topic titles and avoiding fixed report headings, guiding the agent on what to include and exclude.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_fileA

Send an explicitly requested local file or image with a concise caption.

The path must resolve under files.allowed_roots. kind=auto sends supported, small images as Telegram photos and everything else as documents. Use raw Telegram HTML in an HTML caption and keep it within the 1024-character limit.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoauto
pathYes
agentYes
modelYes
routeNo
formatNohtml
captionYes
projectYes
subjectYes
referenceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal non-read-only, external side effects (openWorldHint), and non-idempotent behavior. The description adds valuable context: allowed_roots path restriction, the auto/non-auto mode selection, and the 1024-character caption limit. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise sentences, front-loads the primary purpose, and packs essential constraints (allowed roots, kind behavior, caption limits) without fluff. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the high complexity (10 parameters, 6 required) and rich output schema, the description covers key behavioral rules but misses important required parameter semantics and does not fully explain conditions or edge cases. It is more complete than average but still has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains 'path', 'kind', 'caption', and 'format', but leaves required parameters 'project', 'subject', 'agent', 'model', and optional 'route'/'reference' completely undocumented. This is inadequate for a 10-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool sends an explicitly requested local file or image with a caption, which is a specific verb+resource+scope. It distinguishes itself from sibling tools like send_text and send_update by focusing on files/images rather than text messages or status updates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context: files must resolve under files.allowed_roots, kind=auto behavior is explained, and caption format/length limits are given. It does not explicitly name alternatives or when not to use, but the 'explicitly requested' phrasing implies appropriate conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_textB

Send a formatted message with provenance metadata.

Prefer format='html' for human-facing text. Use raw Telegram HTML tags: , , , , , , , , and . Never encode tags as &lt;b&gt;. brief is the default: concise, self-contained, client-ready copy without process or internal technical details. For an explanation, structure the text by named objects and list their concrete steps, properties, result, and limits. Do not replace details with a general conclusion or a prose comparison. standard adds necessary context; detailed is used only when explicitly requested and must still fit Telegram's 4096-character limit.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
agentYes
modelYes
routeNo
formatYes
presetNobrief
projectYes
subjectYes
referenceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds valuable context beyond annotations: raw Telegram HTML tags, the prohibition on encoding tags, the 4096-character limit, and preset semantics. Annotations already indicate a non-read-only, open-world operation, so no contradiction; the description enriches understanding of the operation's constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose and moves to actionable formatting rules. Each sentence provides needed guidance (tag list, encoding warning, preset definitions, character limit) without excessive verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter tool, the description is incomplete: it explains formatting and preset choices but not the meaning or constraints of provenance fields (project, subject, agent, model, route, reference) or how they relate to the message. It also omits side-effect details beyond the Telegram limit. The presence of an output schema mitigates return-value gaps but does not cover parameter semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description only elaborates on format and preset (e.g., 'brief is the default,' 'standard adds necessary context'). It leaves project, subject, agent, model, route, and reference undefined, relying on names alone. This fails to compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

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: 'Send a formatted message with provenance metadata,' which clearly states the tool's function. The detailed formatting and preset guidance further clarifies scope, though it doesn't explicitly differentiate from sibling tools like send_update or send_client_copy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides concrete usage guidance for format and presets: 'Prefer format="html" for human-facing text,' defines brief/standard/detailed, and warns against encoded tags. However, it does not explain when to choose this tool over alternatives like send_update or send_file, leaving tool selection implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_updateC

Send a concise, client-ready structured update.

brief is the default. Write for a recipient who has not followed the project: put the concrete subject and current result in one self-contained summary using plain everyday language. Replace jargon and internal names with their practical meaning. Add only blockers, decisions, questions, or the next action needed now; completed is omitted when the summary already says what was done. Keep every field inside the exact subject requested by the user; never append unrelated project health. Include a client question only if the answer is not already available, the recipient controls it, and progress on the subject stops without it now. Build the dependency chain internally and ask only the first unresolved dependency, not questions about later steps. Omit the question section when nothing passes this test. Address the recipient directly. For client copy, put a required choice in client_questions, not the internal decisions_needed section. Do not include chronology, review or test logs, implementation details, tool names, or internal reasoning unless they change a client decision, risk, cost, or deadline. The server enforces preset-specific length and item limits and renders safe Telegram HTML.

ParametersJSON Schema
NameRequiredDescriptionDefault
agentYes
modelYes
routeNo
presetNobrief
projectYes
subjectYes
summaryYes
blockersNo
completedNo
referenceNo
next_stepsNo
client_questionsNo
decisions_neededNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description mentions server enforcement of length and item limits and safe Telegram HTML rendering, adding some behavioral context. However, it does not disclose side effects like message delivery guarantees, authentication requirements, or error handling. Annotations already set readOnly=false, so the description adds moderate value but is not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is excessively long and repetitive, with many redundant instructions (e.g., multiple statements about omitting completed items, including only relevant questions). It reads more like a style guide than a tool description, lacking brevity and clear structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 13 parameters and no schema description coverage, yet the description does not adequately explain the tool's overall purpose, parameter roles, return value, or selection criteria. It gives partial guidance on content style but misses essential context for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, and the description only indirectly references a few parameters like client_questions and decisions_needed to distinguish their use. It does not systematically explain the meaning or purpose of most parameters (e.g., agent, model, project, summary). The guidance is fragmented and not parameter-focused.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Send a concise, client-ready structured update.' which clearly indicates the action (send) and resource (update). It differentiates from siblings like send_text or notify_completion by emphasizing 'structured' and 'client-ready', making the purpose reasonably clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool versus alternatives. It implies client-facing updates but lacks direct guidance on selection relative to send_text or send_client_copy. No 'when to use' or 'when not to use' is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A3.6/5.0
Disambiguation4/5

Most tools have clearly distinct purposes, with send_update, send_text, and send_client_copy all serving different messaging contexts. However, send_update and send_client_copy could be confused as both produce client-ready copy, though their descriptions clarify the structured update vs topic-based copy distinction.

Naming Consistency3/5

The send_*, list_*, and notify_* tools follow a consistent verb_noun pattern, but the inbox_* family breaks this with noun-first names like inbox_status, inbox_fetch, inbox_done, and inbox_export, mixing nouns, verbs, and an adjective. This creates noticeable inconsistency.

Tool Count5/5

With 10 tools, the set is well-scoped for the server's purpose of Telegram messaging and inbox management. Each tool serves a distinct function and none feel redundant or unnecessary.

Completeness4/5

The inbox lifecycle is well covered with status, fetch, export, and done, and the sending tools handle various message types. A minor gap exists in managing destinations or allowed projects, but those are likely configured externally, so core workflows are complete.

Maintenance

ActivityMaintained
ResponsivenessSyncing

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

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that enables interaction with Telegram to send, read, and search messages across chats and dialogs. It supports waiting for incoming messages and retrieving conversation history through natural language commands.
    14
    4
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for Telegram integration with Command Code, enabling AI agents to send messages, photos, files, and read updates via Telegram.
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server enabling AI agents to interact with users via Telegram, supporting message and image sending, inline quick replies, and waiting for user responses.
    13
    MIT

Latest Blog Posts

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/ZenonEl/herald'

If you have feedback or need assistance with the MCP directory API, please join our Discord server