@retensy/mcp 0.37.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/package.json +2 -2
- package/skills/build-bot-funnel/SKILL.md +1 -1
- package/src/index.mjs +25 -0
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ MCP-сервер (+ скилл для Claude Code) для **сборки и пу
|
|
|
57
57
|
- 📰 **Публикации и VK**: `publications_usage` — месячная квота (общая для Telegram/MAX/Instagram/VK), `vk_status`/`vk_connect`/`vk_disconnect`/`vk_post` — подключение VK-сообщества токеном и публикация на стену.
|
|
58
58
|
- 🔗 **Ссылка вместо отказа**: что нельзя сделать через API (вход через Google/Instagram, оплата тарифа, вход в аккаунт) — инструмент возвращает прямую ссылку и одну строку, что сделать.
|
|
59
59
|
- 📝 **Статьи блога** (тот же токен `zmcp_…`): `article_publish`, `article_update`, `article_list`, `article_get` — публикация статей в Markdown (как README на GitHub) в раздел **/articles**.
|
|
60
|
-
- 🧠 **ИИ-агенты и база знаний**: `agent_list`/`agent_get`/`agent_create`/`agent_update`/`agent_publish`/`agent_health`/`agent_test_chat`/`agent_unanswered`, `agent_tool_calls`, `kb_docs`/`kb_add_qa`/`kb_add_text`/`kb_add_site`/`kb_reindex` — настройка ИИ-агента и его базы знаний (раздел «ИИ-агенты»).
|
|
60
|
+
- 🧠 **ИИ-агенты и база знаний**: `agent_list`/`agent_get`/`agent_create`/`agent_update`/`agent_publish`/`agent_health`/`agent_test_chat`/`agent_unanswered`/`agent_tests_run`/`agent_tests_list`, `agent_tool_calls`, `kb_docs`/`kb_add_qa`/`kb_add_text`/`kb_add_site`/`kb_reindex` — настройка ИИ-агента и его базы знаний (раздел «ИИ-агенты»).
|
|
61
61
|
- 📎 **Медиа**: `upload_file` грузит фото/видео/документы в библиотеку **/bots/files** (до 50 МБ) и возвращает публичный URL — его вставляешь в медиа-карточку сценария.
|
|
62
62
|
- 🌐 **Сайты из блоков** (раздел «Страницы»): создание, правка операциями (блоки, Zero-блок со свободной вёрсткой, код блока, папки страниц, дизайны, шаблоны из библиотеки), публикация и откат, свои домены, заявки из форм и куда их доставлять — инструменты `site_*` + скилл `build-site`.
|
|
63
63
|
- 🧠 **Скилл `build-bot-funnel`**: учит агента собирать корректный граф (типы узлов, ветки, кнопки, задержки) и проверять его перед публикацией. Поддерживает Telegram, MAX и Instagram.
|
|
@@ -135,7 +135,7 @@ MCP-сервер (+ скилл для Claude Code) для **сборки и пу
|
|
|
135
135
|
| Право | Что разрешает | Примеры инструментов |
|
|
136
136
|
|---|---|---|
|
|
137
137
|
| `read` | любое чтение: списки, карточки, аналитика, превью, поиск, `dry_run`. **Включает персональные данные**: подписчики, переписка в диалогах, заявки с сайтов и их файлы | `list_bots`, `get_graph`, `site_leads`, `dialog_messages`, `broadcast_preview` |
|
|
138
|
-
| `write:bots` | создание и изменение ботов, сценариев, цепочек, интеграций, ИИ-агентов, базы знаний, черновиков рассылок. Правка опубликованного сценария сразу меняет ответы бота подписчикам; можно сменить ключи и вебхуки интеграций; `agent_test_chat`
|
|
138
|
+
| `write:bots` | создание и изменение ботов, сценариев, цепочек, интеграций, ИИ-агентов, базы знаний, черновиков рассылок. Правка опубликованного сценария сразу меняет ответы бота подписчикам; можно сменить ключи и вебхуки интеграций; `agent_test_chat` и `agent_tests_run` тратят ИИ-бюджет, `integration_test` ходит во внешний сервис | `create_graph`, `publish_graph`, `chain_update`, `connect_integration`, `agent_test_chat` |
|
|
139
139
|
| `write:sites` | сайты, лиды, VK-лендинги, статьи | `site_create`, `site_edit`, `site_publish`, `vk_landing_update`, `article_publish` |
|
|
140
140
|
| `crm` | теги/переменные подписчиков, импорт, передача диалога оператору, записи. `booking_confirm`/`booking_reject` отправляют клиенту сообщение | `audience_tag_edit`, `bot_users_import`, `dialog_handoff`, `booking_create` |
|
|
141
141
|
| `broadcast` | всё, что доходит до живых людей без участия человека: рассылки, ответы, посты, а также **включённая цепочка без согласования постов** (approvalMode `NONE`/`AI_ONLY`) и **публикация/правка/активация сценария с `TRIGGER_SCHEDULE`** | `broadcast_send`, `dialog_reply`, `channel_post`, `vk_post`, `chain_approve`, `chain_enable` (без согласования) |
|
|
@@ -257,6 +257,8 @@ MCP-сервер (+ скилл для Claude Code) для **сборки и пу
|
|
|
257
257
|
| `agent_health(agentId)` | счётчики документов/фрагментов базы знаний |
|
|
258
258
|
| `agent_test_chat(agentId, question, history?)` | проверить ответ в песочнице (**тратит бюджет ИИ** — не вызывай массово) |
|
|
259
259
|
| `agent_unanswered(agentId, days?)` | вопросы без ответа за период (7\|30\|90, по умолчанию 30) |
|
|
260
|
+
| `agent_tests_run(agentId, confirm, caseIds?, generate?, wait?, timeoutSec?)` | проверка агента ИИ-клиентами по тест-кейсам: диалог в песочнице, ИИ-судья (PASS/FAIL, причина, цитата), сравнение с прошлым прогоном. **Тратит бюджет ИИ** — нужен `confirm:true` |
|
|
261
|
+
| `agent_tests_list(agentId, runId?)` | тест-кейсы, история прогонов и полный прогон (последний или по `runId`) с регрессиями; ничего не тратит |
|
|
260
262
|
| `kb_docs(kbId)` | документы базы знаний агента (источник, статус, фрагменты) |
|
|
261
263
|
| `kb_add_qa(kbId, pairs)` | добавить пары вопрос-ответ (`pairs: [{question, answer}]`, до 200 за раз) |
|
|
262
264
|
| `kb_add_text(kbId, title, text)` | добавить источник «Текст/инструкция» |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retensy/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"description": "MCP server to build and publish Telegram and MAX bot funnels/automations, broadcasts, service integrations, block-based websites (incl. free-layout Zero blocks, designs, templates, custom domains, form leads) and Markdown blog articles in the Retensy Bots service. Zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"start": "node src/index.mjs",
|
|
23
23
|
"check": "node --check src/index.mjs",
|
|
24
|
-
"test": "node scripts/smoke.mjs && node scripts/telemetry.test.mjs && node scripts/live-edit-422.test.mjs && node scripts/broadcast-connect.test.mjs && node scripts/integration-core.test.mjs && node scripts/site-init.test.mjs && node scripts/ai-agents.test.mjs && node scripts/agent-write-tools.test.mjs && node scripts/battery-tools.test.mjs && node scripts/parity-tools.test.mjs && node scripts/parity-2.test.mjs && node scripts/validate-graph.test.mjs && node scripts/call-scenario.test.mjs && node scripts/audience-publications.test.mjs && node scripts/chains-analytics.test.mjs && node scripts/platform-decisions.test.mjs && node scripts/token-scopes.test.mjs && node scripts/secondary-graphs.test.mjs && node scripts/graph-versions.test.mjs && node scripts/templates-filter.test.mjs",
|
|
24
|
+
"test": "node scripts/smoke.mjs && node scripts/telemetry.test.mjs && node scripts/live-edit-422.test.mjs && node scripts/broadcast-connect.test.mjs && node scripts/integration-core.test.mjs && node scripts/site-init.test.mjs && node scripts/ai-agents.test.mjs && node scripts/agent-write-tools.test.mjs && node scripts/battery-tools.test.mjs && node scripts/parity-tools.test.mjs && node scripts/parity-2.test.mjs && node scripts/validate-graph.test.mjs && node scripts/call-scenario.test.mjs && node scripts/audience-publications.test.mjs && node scripts/chains-analytics.test.mjs && node scripts/platform-decisions.test.mjs && node scripts/token-scopes.test.mjs && node scripts/secondary-graphs.test.mjs && node scripts/graph-versions.test.mjs && node scripts/templates-filter.test.mjs && node scripts/agent-tests.test.mjs",
|
|
25
25
|
"validate": "node skills/build-bot-funnel/validate.mjs"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
@@ -35,7 +35,7 @@ description: Собрать воронку (сценарий) бота для с
|
|
|
35
35
|
- Пакет `ACTIONS` — до 30 действий (метки, профиль, HTTP, уведомления, интеграции GetCourse/amoCRM/Битрикс24/Google Sheets/Я.Метрика, приём оплат, модерация группы). Список — в schema.md. **Интеграции РАБОТАЮТ** (это не заглушки), но каждой нужен `connectionId` — возьми его через **`list_integrations`**; без него действие упадёт «не выбрано подключение». Для Google Таблиц вместо `connectionId` нужен `googleEmail` (аккаунт подключается в вебе).
|
|
36
36
|
- `AI_REPLY` («AI-агент») — два режима, поле `mode` (`"simple"`/не задан, либо `"agent"`). Платный узел в обоих режимах (`PREMIUM_NODE_FORBIDDEN` на бесплатном тарифе) и недоступен в Instagram-графах (нет в IG-allowlist). Тратит месячный AI-бюджет тарифа — он в токенах, не в рублях.
|
|
37
37
|
- **`mode` не задан или `"simple"`** — ответ модели по `systemPrompt`/`userPromptTemplate` (обязателен, иначе выход `error`). Исчерпание бюджета — не ошибка: узел шлёт `quotaFallbackText` (если задан) и идёт дальше по `next`, как обычно.
|
|
38
|
-
- **`mode: "agent"`** — поиск по подключённой базе знаний (`knowledgeBaseId`), ветки-действия (`actions[]`, каждому — своё ребро `action_<id>`), извлечение переменных из разговора (`extract[]`, значения — слова клиента, не проверенный факт) и готовая сводка на действии в `{{var.ai_summary}}` без отдельной настройки. Без найденных в базе фрагментов (нет базы, либо релевантность ниже порога) агент в ЛЮБОМ режиме (строгом и нет) уходит в `unknown` — модель даже не вызывается; исключение — узел с непустым `actions[]`: он и без фрагментов зовёт модель, чтобы та могла выбрать действие («запишите меня на завтра» слов из базы не содержит), а её ответ без фрагментов в любом режиме (и в нестрогом тоже) уходит в `unknown`; нестрогий режим лишь разрешает модели дополнять УЖЕ найденные фрагменты общими знаниями (кроме цен/сроков/обещаний), а не отвечать вовсе без базы. **У узла нет выхода `next`** — только `answered`/`action_<id>`/`unknown`/`budget_exhausted`/`error` (`error` — сбой модели/поиска, ИИ не настроен, headless-вебхук или исчерпанный бюджет без ветки `budget_exhausted`). Исчерпание бюджета — своя ветка `budget_exhausted` (если подключена) либо `error`, `quotaFallbackText` отправляется в обоих случаях. Если собираешь агента этим скиллом — обязательно веди себя по этому списку выходов, старый одиночный `AI_REPLY` без `mode` для агента не годится. `systemPrompt`: мягкая норма 10 000 символов (у бэкенда для неё нет отдельного предупреждения, только `validate.mjs` этого скилла warn'ит явно), жёсткий потолок 30 000 (`AGENT_PROMPT_TOO_LONG`, блокирует публикацию) — платформа сама добавляет защиту от инъекций/вытягивания инструкции, запрет обещать несделанное и формат под мессенджер, дублировать это в `systemPrompt` не нужно. Подробности всех полей и кодов ошибок (`AGENT_*`) — в schema.md/validation.md.
|
|
38
|
+
- **`mode: "agent"`** — поиск по подключённой базе знаний (`knowledgeBaseId`), ветки-действия (`actions[]`, каждому — своё ребро `action_<id>`), извлечение переменных из разговора (`extract[]`, значения — слова клиента, не проверенный факт) и готовая сводка на действии в `{{var.ai_summary}}` без отдельной настройки. Без найденных в базе фрагментов (нет базы, либо релевантность ниже порога) агент в ЛЮБОМ режиме (строгом и нет) уходит в `unknown` — модель даже не вызывается; исключение — узел с непустым `actions[]`: он и без фрагментов зовёт модель, чтобы та могла выбрать действие («запишите меня на завтра» слов из базы не содержит), а её ответ без фрагментов в любом режиме (и в нестрогом тоже) уходит в `unknown`; нестрогий режим лишь разрешает модели дополнять УЖЕ найденные фрагменты общими знаниями (кроме цен/сроков/обещаний), а не отвечать вовсе без базы. **У узла нет выхода `next`** — только `answered`/`action_<id>`/`unknown`/`budget_exhausted`/`error` (`error` — сбой модели/поиска, ИИ не настроен, headless-вебхук или исчерпанный бюджет без ветки `budget_exhausted`). Исчерпание бюджета — своя ветка `budget_exhausted` (если подключена) либо `error`, `quotaFallbackText` отправляется в обоих случаях. Перед публикацией агента можно прогнать проверку ИИ-клиентами: `agent_tests_list` (кейсы и история) → `agent_tests_run` с `confirm:true` (тратит бюджет ИИ; PASS/FAIL с причиной и цитатой, регрессии к прошлому прогону). Если собираешь агента этим скиллом — обязательно веди себя по этому списку выходов, старый одиночный `AI_REPLY` без `mode` для агента не годится. `systemPrompt`: мягкая норма 10 000 символов (у бэкенда для неё нет отдельного предупреждения, только `validate.mjs` этого скилла warn'ит явно), жёсткий потолок 30 000 (`AGENT_PROMPT_TOO_LONG`, блокирует публикацию) — платформа сама добавляет защиту от инъекций/вытягивания инструкции, запрет обещать несделанное и формат под мессенджер, дублировать это в `systemPrompt` не нужно. Подробности всех полей и кодов ошибок (`AGENT_*`) — в schema.md/validation.md.
|
|
39
39
|
- **Приём оплат** — действие `issue_invoice` внутри `ACTIONS` (НЕ отдельный узел: `YOOKASSA_PAYMENT` устарел). Деньги идут на кассу владельца бота; `connectionId` — подключение `provider=YOOKASSA` из `list_integrations`. Два режима, выбирай по задаче:
|
|
40
40
|
- **дождаться оплаты прямо в диалоге** — протяни от блока ветку `paid` (появятся выходы `paid`/`timeout`); сценарий встанет на паузу до подтверждения кассой;
|
|
41
41
|
- **не ждать** — ветку `paid` не рисуй, блок просто пришлёт счёт и пойдёт по `next`; выдать доступ потом сможет отдельный сценарий с триггером `TRIGGER_PAYMENT`.
|
package/src/index.mjs
CHANGED
|
@@ -1109,6 +1109,8 @@ const TOOLS = [
|
|
|
1109
1109
|
{ name: "kb_add_site", description: "Добавить сайт в базу знаний обходом страниц (POST /api/bots/kb/{kbId}/docs/site): url (http/https, не внутренняя сеть), schedule — расписание повторного обхода: NEVER|DAILY|WEEKLY|MONTHLY (по умолчанию NEVER). Обход уходит в фон; документ появится в kb_docs со статусом PENDING.", inputSchema: { type: "object", properties: { kbId: { type: "string" }, url: { type: "string" }, schedule: { type: "string", enum: ["NEVER", "DAILY", "WEEKLY", "MONTHLY"] } }, required: ["kbId", "url"] } },
|
|
1110
1110
|
{ name: "kb_reindex", description: "Переиндексировать документ-файл базы знаний из сохранённого оригинала (POST /api/bots/kb/{kbId}/docs/{docId}/reindex) — «Повторить» после ошибки. headerRow — необязательно, для табличных файлов: номер строки с шапкой (1..50), если автоопределение ошиблось. Только для источника FILE.", inputSchema: { type: "object", properties: { kbId: { type: "string" }, docId: { type: "string" }, headerRow: { type: "number" } }, required: ["kbId", "docId"] } },
|
|
1111
1111
|
{ name: "agent_unanswered", description: "Вопросы без ответа агента за период (GET /api/bots/agents/{agentId}/unanswered): days — 7|30|90 (по умолчанию 30). Группы вопросов, на которые агент не нашёл ответ в базе знаний — подсказка, что туда добавить. Read-only.", inputSchema: { type: "object", properties: { agentId: { type: "string" }, days: { type: "number", enum: [7, 30, 90] } }, required: ["agentId"] } },
|
|
1112
|
+
{ name: "agent_tests_run", description: "Проверка агента ИИ-клиентами (POST /api/bots/agents/{agentId}/ai-tests/runs): ИИ играет клиентов по сохранённым тест-кейсам (персона + цель + критерии), ведёт диалог с агентом в песочнице, ИИ-судья ставит PASS/FAIL с причиной и цитатой; результат сравнивается с прошлым прогоном (регрессии). ТРАТИТ бюджет ИИ (до 120 вызовов на прогон, до 10 кейсов, до 30 прогонов в сутки; пробные ответы не используются) — поэтому нужен confirm:true. caseIds — какие кейсы гнать (по умолчанию все, максимум 10). wait (по умолчанию true) — дождаться конца прогона (до timeoutSec, по умолчанию 240) и вернуть итог; wait:false вернёт id прогона сразу — дальше agent_tests_list с runId. Кейсы создаёт владелец во вкладке «Проверка» или generate:N (1–10): сначала создаст N кейсов с ИИ (ещё один вызов ИИ), потом прогонит.", inputSchema: { type: "object", properties: { agentId: { type: "string" }, confirm: { type: "boolean", description: "true — подтверждение расхода бюджета ИИ" }, caseIds: { type: "array", items: { type: "string" } }, generate: { type: "number", description: "Создать столько кейсов с ИИ перед прогоном (1–10)" }, wait: { type: "boolean" }, timeoutSec: { type: "number" } }, required: ["agentId", "confirm"] } },
|
|
1113
|
+
{ name: "agent_tests_list", description: "Кейсы проверки ИИ-клиентами и история прогонов агента (GET /api/bots/agents/{agentId}/ai-tests/cases, /runs, /runs/{runId}): cases — кейсы, history — последние 20 прогонов (итоги без диалогов), run — полный прогон (runId или последний): по каждому кейсу verdict PASS/FAIL/ERROR, reason, quote, диалог, previousVerdict и regression (раньше проходил, теперь нет). Ничего не тратит. Read-only.", inputSchema: { type: "object", properties: { agentId: { type: "string" }, runId: { type: "string" } }, required: ["agentId"] } },
|
|
1112
1114
|
// ---- Боты ----
|
|
1113
1115
|
{ name: "create_bot", description: "Подключить бота по токену (POST /api/bots): platform TELEGRAM (токен от @BotFather) или MAX (токен от MasterBot в MAX). Вебхук настраивается сам; name — отображаемое имя (иначе @username). Возвращает бота с id. Число ботов ограничено тарифом — HTTP 402 со ссылкой на смену тарифа. platform WEB — чат-виджет для сайта без токена (POST /api/bots/web): вернёт botId, key и snippet — код вставки на сайт (у существующего виджета — web_widget_snippet). platform INSTAGRAM по токену не подключается — только входом через Instagram (OAuth) в кабинете (/bots/instagram), нужен Instagram-аккаунт Business или Creator — инструмент вернёт ссылку на кабинет вместо ошибки. platform VK — сообщество как полноценный канал (Callback API, НЕ путать с vk_connect — тот для публикаций на стену): token — токен СООБЩЕСТВА (Управление сообществом → Работа с API → Создать ключ, доступ «Сообщения сообщества»), groupId — числовой id сообщества (обязателен). После подключения нужно вручную включить Callback API в настройках сообщества — см. webhookSecret в ответе и URL /vk/hooks/{botId} (подробный чек-лист у разработчика). inactive (только TELEGRAM/MAX) — создать бота остановленным: токен проверяется безопасным getMe, вебхук/поллинг НЕ трогаются — живой вебхук бота в другом конструкторе (BotHelp и т.п.) не снимается. Нужно при переносе бота из другого сервиса: создай inactive:true, перенеси сценарии/подписчиков (migration_preview/migration_commit), потом bot_resume — это и есть переключение (cutover).", inputSchema: { type: "object", properties: { platform: { type: "string", enum: ["TELEGRAM", "MAX", "WEB", "INSTAGRAM", "VK"] }, token: { type: "string", description: "Токен бота/сообщества: 123456789:AA… (Telegram), токен MAX, или community token VK" }, groupId: { type: "string", description: "Только platform=VK: числовой id сообщества" }, name: { type: "string" }, inactive: { type: "boolean", description: "Только TELEGRAM/MAX: создать остановленным (перенос из другого конструктора) — включить потом через bot_resume" } }, required: ["platform"] } },
|
|
1114
1116
|
// ---- VK-лендинги (growth tools, Mini App) ----
|
|
@@ -1599,6 +1601,29 @@ async function handleCall(params) {
|
|
|
1599
1601
|
const qs = a.days != null ? `?days=${encodeURIComponent(a.days)}` : "";
|
|
1600
1602
|
return okResult(await api(`/api/bots/agents/${a.agentId}/unanswered${qs}`));
|
|
1601
1603
|
}
|
|
1604
|
+
case "agent_tests_list": {
|
|
1605
|
+
const base = `/api/bots/agents/${a.agentId}/ai-tests`;
|
|
1606
|
+
const [cases, history] = await Promise.all([api(`${base}/cases`), api(`${base}/runs`)]);
|
|
1607
|
+
const run = a.runId ? await api(`${base}/runs/${a.runId}`) : (await api(`${base}/runs/latest`)) || null;
|
|
1608
|
+
return okResult({ cases, history, run });
|
|
1609
|
+
}
|
|
1610
|
+
case "agent_tests_run": {
|
|
1611
|
+
if (a.confirm !== true) throw new Error("Проверка тратит бюджет ИИ (до 120 вызовов на прогон). Передай confirm:true, когда владелец согласен на расход.");
|
|
1612
|
+
const base = `/api/bots/agents/${a.agentId}/ai-tests`;
|
|
1613
|
+
if (a.generate != null) {
|
|
1614
|
+
const n = Number(a.generate);
|
|
1615
|
+
if (!Number.isInteger(n) || n < 1 || n > 10) throw new Error("generate — целое от 1 до 10.");
|
|
1616
|
+
await api(`${base}/generate`, { method: "POST", body: { count: n, confirmed: true } });
|
|
1617
|
+
}
|
|
1618
|
+
let run = await api(`${base}/runs`, { method: "POST", body: { caseIds: a.caseIds, confirmed: true, trigger: "MCP" } });
|
|
1619
|
+
if (a.wait === false) return okResult(run);
|
|
1620
|
+
const deadline = Date.now() + Math.min(Math.max(Number(a.timeoutSec) || 240, 10), 600) * 1000;
|
|
1621
|
+
while (run.status === "RUNNING" && Date.now() < deadline) {
|
|
1622
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
1623
|
+
run = await api(`${base}/runs/${run.id}`);
|
|
1624
|
+
}
|
|
1625
|
+
return okResult(run.status === "RUNNING" ? { ...run, note: "Прогон ещё идёт — смотри agent_tests_list с runId." } : run);
|
|
1626
|
+
}
|
|
1602
1627
|
case "kb_delete_doc": {
|
|
1603
1628
|
await api(`/api/bots/kb/${a.kbId}/docs/${a.docId}`, { method: "DELETE" });
|
|
1604
1629
|
return okResult(`🗑️ Документ ${a.docId} удалён из базы ${a.kbId}.`);
|