@besales/mcp 1.0.0-beta.5 → 1.0.0-beta.9

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.
Files changed (95) hide show
  1. package/README.md +41 -6
  2. package/dist/auth/oauth-client.d.ts +1 -1
  3. package/dist/auth/oauth-client.js +2 -0
  4. package/dist/auth/oauth-client.js.map +1 -1
  5. package/dist/http/api-client.d.ts +10 -0
  6. package/dist/http/api-client.js +32 -0
  7. package/dist/http/api-client.js.map +1 -1
  8. package/dist/resources/concepts/sandbox.md +8 -1
  9. package/dist/resources/concepts/triggers.md +1 -0
  10. package/dist/resources/docs/platforms.md +58 -1
  11. package/dist/resources/docs/trigger-actions.md +24 -0
  12. package/dist/resources/workflows/iterate-with-sandbox.md +6 -2
  13. package/dist/resources/workflows/platform-setup-from-scratch.md +27 -0
  14. package/dist/schemas/mcp-tools.json +904 -27
  15. package/dist/tools/definitions/agent-design.d.ts +2 -0
  16. package/dist/tools/definitions/agent-design.js +15 -4
  17. package/dist/tools/definitions/agent-design.js.map +1 -1
  18. package/dist/tools/definitions/agent-settings.d.ts +1 -0
  19. package/dist/tools/definitions/agent-settings.js +2 -0
  20. package/dist/tools/definitions/agent-settings.js.map +1 -1
  21. package/dist/tools/definitions/broadcast-analytics.js +1 -1
  22. package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
  23. package/dist/tools/definitions/broadcast-campaigns.d.ts +29 -0
  24. package/dist/tools/definitions/broadcast-campaigns.js +107 -0
  25. package/dist/tools/definitions/broadcast-campaigns.js.map +1 -0
  26. package/dist/tools/definitions/dialogue-export.js +2 -0
  27. package/dist/tools/definitions/dialogue-export.js.map +1 -1
  28. package/dist/tools/definitions/follow-up.d.ts +1 -1
  29. package/dist/tools/definitions/platform-setup-wave.d.ts +1 -1
  30. package/dist/tools/definitions/platform-setup.d.ts +12 -1
  31. package/dist/tools/definitions/task-state.d.ts +1 -1
  32. package/dist/tools/definitions/telegram-outreach-calendar.d.ts +17 -0
  33. package/dist/tools/definitions/telegram-outreach-calendar.js +68 -0
  34. package/dist/tools/definitions/telegram-outreach-calendar.js.map +1 -0
  35. package/dist/tools/definitions/telegram-personal-connect.d.ts +12 -0
  36. package/dist/tools/definitions/telegram-personal-connect.js +61 -0
  37. package/dist/tools/definitions/telegram-personal-connect.js.map +1 -0
  38. package/dist/tools/definitions/telegram-personal-management.d.ts +1 -1
  39. package/dist/tools/definitions/telegram-personal-profile.d.ts +2 -0
  40. package/dist/tools/definitions/telegram-personal-profile.js +14 -0
  41. package/dist/tools/definitions/telegram-personal-profile.js.map +1 -1
  42. package/dist/tools/definitions/telegram-personal-proxies.d.ts +42 -0
  43. package/dist/tools/definitions/telegram-personal-proxies.js +204 -0
  44. package/dist/tools/definitions/telegram-personal-proxies.js.map +1 -0
  45. package/dist/tools/definitions/telegram-proxy-stock.d.ts +34 -0
  46. package/dist/tools/definitions/telegram-proxy-stock.js +129 -0
  47. package/dist/tools/definitions/telegram-proxy-stock.js.map +1 -0
  48. package/dist/tools/definitions/telegram-session-import.d.ts +5 -0
  49. package/dist/tools/definitions/telegram-session-import.js +33 -0
  50. package/dist/tools/definitions/telegram-session-import.js.map +1 -0
  51. package/dist/tools/definitions/trigger-action-item.schema.d.ts +10 -0
  52. package/dist/tools/definitions/trigger-action-item.schema.js +28 -11
  53. package/dist/tools/definitions/trigger-action-item.schema.js.map +1 -1
  54. package/dist/tools/definitions/trigger-upsert.tool.d.ts +1 -0
  55. package/dist/tools/definitions/trigger-upsert.tool.js +13 -0
  56. package/dist/tools/definitions/trigger-upsert.tool.js.map +1 -1
  57. package/dist/tools/definitions.d.ts +119 -9
  58. package/dist/tools/definitions.js +13 -0
  59. package/dist/tools/definitions.js.map +1 -1
  60. package/dist/tools/operation-recovery.d.ts +1 -1
  61. package/dist/tools/operation-recovery.js +1 -1
  62. package/dist/tools/operation-recovery.js.map +1 -1
  63. package/dist/tools/registry-mapping.cases.js +210 -8
  64. package/dist/tools/registry-mapping.cases.js.map +1 -1
  65. package/dist/tools/registry.js +20 -7
  66. package/dist/tools/registry.js.map +1 -1
  67. package/dist/tools/result.d.ts +2 -1
  68. package/dist/tools/result.js +100 -27
  69. package/dist/tools/result.js.map +1 -1
  70. package/dist/types/api-contract.gen.d.ts +2220 -216
  71. package/docs/async-operation-lifecycle.md +13 -2
  72. package/docs/failure-semantics.md +15 -2
  73. package/docs/help-navigation.md +2 -0
  74. package/docs/secret-read-boundary.md +7 -0
  75. package/docs/telegram-personal-management.md +95 -24
  76. package/docs/telegram-personal-proxies.md +135 -0
  77. package/docs/telegram-session-import.md +53 -0
  78. package/package.json +8 -7
  79. package/scripts/body-idempotency-contract.mjs +95 -0
  80. package/scripts/generate-followup-session-contract.mjs +14 -7
  81. package/scripts/generated-output.mjs +9 -0
  82. package/scripts/sync-agent-model-schemas.mjs +11 -11
  83. package/scripts/sync-api-contracts.mjs +99 -40
  84. package/scripts/sync-crm-stage-pool-schema.mjs +6 -7
  85. package/scripts/sync-route-map.mjs +189 -35
  86. package/scripts/sync-sandbox-request-key.mjs +40 -0
  87. package/scripts/sync-telegram-profile-photo.mjs +57 -0
  88. package/scripts/sync-telegram-session-import.mjs +39 -0
  89. package/scripts/sync-tool-inventory.mjs +15 -7
  90. package/scripts/sync-trigger-argument-schema.mjs +31 -14
  91. package/scripts/sync-trigger-event-schema.mjs +11 -6
  92. package/scripts/sync-trigger-step-reference-schema.mjs +21 -0
  93. package/scripts/sync-wave-id-schemas.mjs +7 -6
  94. package/scripts/telegram-personal-profile-mutants.mjs +59 -18
  95. package/scripts/telegram-personal-proxy-mutants.mjs +171 -0
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "title": "besales-mcp Tool Definitions",
4
4
  "version": "1.2.0-draft",
5
- "lastUpdated": "2026-11-09",
5
+ "lastUpdated": "2026-11-12",
6
6
  "description": "MCP tool schemas для besales-mcp npm package. Активная v2-поверхность содержит ICP, Sandbox, Knowledge, prompt operations и stateless Platform Setup Bridge. Setup Pipeline session tools сохранены как Phase 4+ future design, но не входят в active toolset.",
7
7
  "executionModes": {
8
8
  "summary": "Каждая active LLM-операция имеет 2 MCP tools: get_instructions + submit. Claude локально между tools выполняет LLM-вызовы своими моделями. Auto-detection через JWT scope mcp:* → external default.",
@@ -996,7 +996,7 @@
996
996
  },
997
997
  {
998
998
  "name": "besales_sandbox_run_start",
999
- "description": "Start sandbox run для agent (full multi-persona × multi-scenario testing). Queued async. Без вопроса запускай обычный прогон: mode=single_agent и client_mode=scripted (умолчания схемы) — это дешёвый, воспроизводимый прогон для регрессии и проверки кандидата промпта до публикации (candidate_prompt). Перед запуском спроси пользователя одним коротким вопросом с ценой в одну фразу только если нужен client_mode=simulated (LLM играет клиента — дороже и каждый раз по-разному), оба режима клиента (= два прогона) либо mode=workflow (все агенты канала через роутер — шире и дороже).",
999
+ "description": "Start sandbox run для agent (full multi-persona × multi-scenario testing). Queued async. Без вопроса запускай обычный прогон: mode=single_agent и client_mode=scripted (умолчания схемы) — это дешёвый, воспроизводимый прогон для регрессии и проверки кандидата промпта до публикации (candidate_prompt). Перед запуском спроси пользователя одним коротким вопросом с ценой в одну фразу только если нужен client_mode=simulated (LLM играет клиента — дороже и каждый раз по-разному), оба режима клиента (= два прогона) либо mode=workflow (все агенты канала через роутер — шире и дороже). request_key (UUID) — идемпотентность повторного запуска: для повтора того же намерения передай тот же ключ; без поля мост генерирует один ключ на вызов, транспорт внутри вызова использует его повторно. icp_profile_id: UUID — выбранный портрет, null — без выбора, отсутствие — основной портрет агента. Сохрани request_key. При таймауте или 5xx повтори вызов с тем же request_key и тем же намерением: вернётся тот же прогон. Новый ключ — новый платный прогон; другое намерение с прежним ключом даёт START_KEY_CONFLICT.",
1000
1000
  "inputSchema": {
1001
1001
  "type": "object",
1002
1002
  "required": [
@@ -1075,6 +1075,19 @@
1075
1075
  "default": 10
1076
1076
  }
1077
1077
  }
1078
+ },
1079
+ "request_key": {
1080
+ "type": "string",
1081
+ "format": "uuid",
1082
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
1083
+ },
1084
+ "icp_profile_id": {
1085
+ "type": [
1086
+ "string",
1087
+ "null"
1088
+ ],
1089
+ "format": "uuid",
1090
+ "description": "UUID выбранного портрета; null — без выбора; отсутствие — основной портрет агента."
1078
1091
  }
1079
1092
  }
1080
1093
  }
@@ -3341,7 +3354,7 @@
3341
3354
  },
3342
3355
  {
3343
3356
  "name": "besales_agent_clone",
3344
- "description": "Deep-clone an existing agent into a NEW agent on the SAME platform (mirrors the besales GUI clone button). Copies baseSystemPrompt, knowledge namespaces, model/model_lane/runtime config, tools + builtin tools, agent + workspace variable overrides, ICP links, and ALL triggers + actions (with FK remap to new ids). Does NOT copy routing rules (per-router) or per-platform behavior — the clone is inert until wired into the router. Prompt is identical to source; PromptHub auto-bootstraps a fresh version on the first prompt op. Cross-platform clone is not supported — use besales_platform_clone_* for that.",
3357
+ "description": "Deep-clone an existing agent into a NEW agent on the SAME platform (mirrors the besales GUI clone button). Copies baseSystemPrompt, knowledge namespaces, model/model_lane/runtime config, tools + builtin tools, agent + workspace variable overrides, ICP links, and ALL triggers + actions (with FK remap to new ids). Does NOT copy routing rules (per-router) or per-platform behavior — the clone is inert until wired into the router. Prompt is identical to source; PromptHub auto-bootstraps a fresh version on the first prompt op. Cross-platform clone is not supported — use besales_platform_clone_* for that. Если у исходного агента есть необратимые действия, включая закрытие разговора после тишины, требуется отдельное явное согласие человека: explicit_confirmation=true. Без него API вернёт 400 TRIGGER_DANGEROUS_CONFIRMATION_REQUIRED. Не подтверждай за человека.",
3345
3358
  "inputSchema": {
3346
3359
  "type": "object",
3347
3360
  "required": [
@@ -3367,6 +3380,10 @@
3367
3380
  "display_name": {
3368
3381
  "type": "string",
3369
3382
  "description": "Отображаемое имя нового агента; если не задано — зеркалит name."
3383
+ },
3384
+ "explicit_confirmation": {
3385
+ "type": "boolean",
3386
+ "description": "Отдельное согласие человека на копирование необратимых действий, включая закрытие разговора после тишины. При таких действиях требуется true."
3370
3387
  }
3371
3388
  }
3372
3389
  }
@@ -3872,7 +3889,7 @@
3872
3889
  },
3873
3890
  {
3874
3891
  "name": "besales_trigger_upsert",
3875
- "description": "Create trigger, patch trigger metadata, or replace its full action set (replace_actions=true) for an agent. Without replace_actions existing actions are not bulk-replaced; webhook, operator, silent AI, CRM, calendar, outbound and follow-up actions require explicit_confirmation. В ответе вместо самих шагов и условий приходит их количество (actionsCount / activationsCount): эхо повторяло отправленное целиком и уносило контекст на каждой правке, а правят их десятками подряд. Текущий состав читается через besales_platform_context_get. Включённое действие, сохраняющее почту, названную клиентом (шаг SAVE_CONTACT_INFO с полем email ровно {{slots.email}}), записывается только с allow_repeat_in_conversation=true, иначе 422: первая попытка заняла бы право до закрытия переписки, и исправленный адрес сохранить было бы нельзя. Действию, записывающему значение из переписки (поле CRM без шаблона — input_type ai_text или ai_dropdown; заметка с input_type=ai_text; переменная с value_source=MODEL; поле школы из ai_fields с вариантами options), повтор рекомендован, но не обязателен: частичное извлечение занимает право, и названное позже без allow_repeat_in_conversation=true не запишется. В getcourseCreateDealConfig для GETCOURSE_CREATE_DEAL можно передать reuse_open_invoice=true: переиспользуется только открытый счёт с продуктом из предложения шага; нового заказа нет. Срок давности счёта: по умолчанию не старше 14 суток; open_invoice_age=ANY_AGE — без срока, WITHIN_MAX_AGE — 14 суток. Отсутствующий ключ получает 14 суток, в том числе у перенесённых шагов; ключ умолчания при сохранении удаляется. Количество открытых счетов считается в пределах выбранного срока. ru/en/es/id/uz используют подпись поля и двух вариантов на языке пользователя. Упорядоченный список уникальных ответственных сотрудников своего подключения amoCRM. Пропуск ключа сохраняет прежний пул цепочки; [] или null снимают. При полной замене действий передай прочитанный пул явно. Ссылки — UUID из каталога операторов CRM, а не номера пользователей. Голосовые шаги: канон stepType=VOICE_INITIATE_OUTBOUND_CALL / VOICE_TRANSFER_CALL и config. Старые initiateOutboundCall/initiateOutboundCallConfig и transferCall/transferCallConfig принимаются как ввод. Конфликты и непустой чужой конфиг отклоняются до HTTP; снимается только служебное эхо верхнего уровня, вложенные поля сохраняются. Редактирование не выполняет звонок или перевод. При replace_actions=true явно сохраняй обе оси SILENT_MODE: config.silence_bot и config.silence_followups. Пропущенная ось получает true, а не прежнее значение. Для старого конверта — silenceBot/silenceFollowUps. Для автоматического запуска по событию передай trigger вместо scope и строкового condition верхнего уровня. NEW_CONVERSATION — начало новой переписки; CONTACT_MESSAGE — сообщение клиента; OPERATOR_REPLY — ответ живого оператора; AGENT_REPLY — после ответа бота клиенту, пустой или молчаливый ход события не даёт. Шаги событийного триггера статичные: без arguments, {{args.*}} и полей «заполняет ИИ» — автозапуск не получает значений ИИ. Для шагов с оператором или отправкой требуется explicit_confirmation=true. Горизонт allow_repeat_in_conversation — ПЕРЕПИСКА. В trigger.condition можно использовать conversation.lastActionFailureCode, если сервер его знает.",
3892
+ "description": "Create trigger, patch trigger metadata, or replace its full action set (replace_actions=true) for an agent. Without replace_actions existing actions are not bulk-replaced; webhook, operator, silent AI, CRM, calendar, outbound and follow-up actions require explicit_confirmation. В ответе вместо самих шагов и условий приходит их количество (actionsCount / activationsCount): эхо повторяло отправленное целиком и уносило контекст на каждой правке, а правят их десятками подряд. Текущий состав читается через besales_platform_context_get. Включённое действие, сохраняющее почту, названную клиентом (шаг SAVE_CONTACT_INFO с полем email ровно {{slots.email}}), записывается только с allow_repeat_in_conversation=true, иначе 422: первая попытка заняла бы право до закрытия переписки, и исправленный адрес сохранить было бы нельзя. Действию, записывающему значение из переписки (поле CRM без шаблона — input_type ai_text или ai_dropdown; заметка с input_type=ai_text; переменная с value_source=MODEL; поле школы из ai_fields с вариантами options), повтор рекомендован, но не обязателен: частичное извлечение занимает право, и названное позже без allow_repeat_in_conversation=true не запишется. В getcourseCreateDealConfig для GETCOURSE_CREATE_DEAL можно передать reuse_open_invoice=true: переиспользуется только открытый счёт с продуктом из предложения шага; нового заказа нет. Срок давности счёта: по умолчанию не старше 14 суток; open_invoice_age=ANY_AGE — без срока, WITHIN_MAX_AGE — 14 суток. Отсутствующий ключ получает 14 суток, в том числе у перенесённых шагов; ключ умолчания при сохранении удаляется. Количество открытых счетов считается в пределах выбранного срока. ru/en/es/id/uz используют подпись поля и двух вариантов на языке пользователя. Упорядоченный список уникальных ответственных сотрудников своего подключения amoCRM. Пропуск ключа сохраняет прежний пул цепочки; [] или null снимают. При полной замене действий передай прочитанный пул явно. Ссылки — UUID из каталога операторов CRM, а не номера пользователей. Голосовые шаги: канон stepType=VOICE_INITIATE_OUTBOUND_CALL / VOICE_TRANSFER_CALL и config. Старые initiateOutboundCall/initiateOutboundCallConfig и transferCall/transferCallConfig принимаются как ввод. Конфликты и непустой чужой конфиг отклоняются до HTTP; снимается только служебное эхо верхнего уровня, вложенные поля сохраняются. Редактирование не выполняет звонок или перевод. При replace_actions=true явно сохраняй обе оси SILENT_MODE: config.silence_bot и config.silence_followups. Пропущенная ось получает true, а не прежнее значение. Для старого конверта — silenceBot/silenceFollowUps. Для автоматического запуска по событию передай trigger вместо scope и строкового condition верхнего уровня. NEW_CONVERSATION — начало новой переписки; CONTACT_MESSAGE — сообщение клиента; OPERATOR_REPLY — ответ живого оператора; AGENT_REPLY — после ответа бота клиенту, пустой или молчаливый ход события не даёт. Шаги событийного триггера статичные: без arguments, {{args.*}} и полей «заполняет ИИ» — автозапуск не получает значений ИИ. Для шагов с оператором или отправкой требуется explicit_confirmation=true. Горизонт allow_repeat_in_conversation — ПЕРЕПИСКА. В trigger.condition можно использовать conversation.lastActionFailureCode, если сервер его знает. Правка одного шага: нетронутые шаги присылай как { stepId } (id — из besales_platform_context_get, раздел agents_full), изменённый — { stepId, stepType, config } с полной настройкой из снимка; HTTP-запрос и шаг со скрытыми полями — только { stepId }, пропуск скрытого шага запрещён. После записи id шагов меняются — перед следующей правкой перечитай снимок. Подробно — besales://docs/trigger-actions.",
3876
3893
  "inputSchema": {
3877
3894
  "type": "object",
3878
3895
  "required": [
@@ -4889,6 +4906,23 @@
4889
4906
  }
4890
4907
  ],
4891
4908
  "description": "Совместимый ввод голосового конфига. Используй один config или одно прежнее имя; relation вместе с input, даже null, отклоняется до HTTP."
4909
+ },
4910
+ "stepId": {
4911
+ "description": "Ссылка на сохранённый шаг этого триггера (id из besales_platform_context_get)",
4912
+ "type": "string",
4913
+ "format": "uuid",
4914
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
4915
+ },
4916
+ "onError": {
4917
+ "type": "string",
4918
+ "enum": [
4919
+ "STOP",
4920
+ "SKIP",
4921
+ "RETRY"
4922
+ ]
4923
+ },
4924
+ "stopOnSuccess": {
4925
+ "type": "boolean"
4892
4926
  }
4893
4927
  },
4894
4928
  "additionalProperties": true,
@@ -11954,7 +11988,7 @@
11954
11988
  },
11955
11989
  {
11956
11990
  "name": "besales_platform_create_init",
11957
- "description": "v1.5 Increment 5b: создать platform provisioning сессию (Setup URL pattern) для API-key канала. Секреты НЕ передаются через MCP — пользователь вводит их на setup_page_url. Возвращает { setup_ref, setup_page_url, expires_at, required_secret_fields }. OAuth-каналы (Instagram/Avito) — besales_platform_create_oauth_init; TelegramPersonal не поддержан. Scope: mcp:platform-setup.",
11991
+ "description": "v1.5 Increment 5b: создать platform provisioning сессию (Setup URL pattern) для API-key канала. Секреты НЕ передаются через MCP — пользователь вводит их на setup_page_url. Возвращает { setup_ref, setup_page_url, expires_at, required_secret_fields }. OAuth-каналы (Instagram/Avito) — besales_platform_create_oauth_init; TelegramPersonal не поддержан; номера в существующий канал — besales_platform_telegram_personal_connect_link. Scope: mcp:platform-setup.",
11958
11992
  "inputSchema": {
11959
11993
  "type": "object",
11960
11994
  "required": [
@@ -15619,6 +15653,186 @@
15619
15653
  ]
15620
15654
  }
15621
15655
  },
15656
+ {
15657
+ "name": "besales_broadcast_campaign_list",
15658
+ "description": "Список кампаний рассылок с поиском, статусом и курсором. Scope: read:campaigns.",
15659
+ "inputSchema": {
15660
+ "type": "object",
15661
+ "properties": {
15662
+ "workspace_id": {
15663
+ "type": "string",
15664
+ "format": "uuid"
15665
+ },
15666
+ "status": {
15667
+ "type": "string",
15668
+ "enum": [
15669
+ "DRAFT",
15670
+ "SCHEDULED",
15671
+ "RUNNING",
15672
+ "PAUSED",
15673
+ "COMPLETED",
15674
+ "ARCHIVED"
15675
+ ]
15676
+ },
15677
+ "search": {
15678
+ "type": "string"
15679
+ },
15680
+ "cursor": {
15681
+ "type": "string",
15682
+ "format": "uuid"
15683
+ },
15684
+ "limit": {
15685
+ "type": "integer",
15686
+ "minimum": 1,
15687
+ "maximum": 100
15688
+ }
15689
+ },
15690
+ "required": [],
15691
+ "additionalProperties": false
15692
+ }
15693
+ },
15694
+ {
15695
+ "name": "besales_broadcast_campaign_get",
15696
+ "description": "Карточка кампании по ID: настройки, статус, расписание запуска и части кампании. Scope: read:campaigns.",
15697
+ "inputSchema": {
15698
+ "type": "object",
15699
+ "properties": {
15700
+ "workspace_id": {
15701
+ "type": "string",
15702
+ "format": "uuid"
15703
+ },
15704
+ "campaign_id": {
15705
+ "type": "string",
15706
+ "format": "uuid"
15707
+ }
15708
+ },
15709
+ "required": [
15710
+ "campaign_id"
15711
+ ],
15712
+ "additionalProperties": false
15713
+ }
15714
+ },
15715
+ {
15716
+ "name": "besales_broadcast_campaign_create",
15717
+ "description": "Создать черновик кампании с существующим шаблоном и аудиторией. Для повтора того же создания используй прежний idempotency_key. Scope: manage:campaigns.",
15718
+ "inputSchema": {
15719
+ "type": "object",
15720
+ "properties": {
15721
+ "workspace_id": {
15722
+ "type": "string",
15723
+ "format": "uuid"
15724
+ },
15725
+ "name": {
15726
+ "type": "string",
15727
+ "minLength": 1,
15728
+ "maxLength": 160
15729
+ },
15730
+ "description": {
15731
+ "type": [
15732
+ "string",
15733
+ "null"
15734
+ ]
15735
+ },
15736
+ "template_id": {
15737
+ "type": "string",
15738
+ "format": "uuid"
15739
+ },
15740
+ "audience_id": {
15741
+ "type": "string",
15742
+ "format": "uuid"
15743
+ },
15744
+ "idempotency_key": {
15745
+ "type": "string",
15746
+ "minLength": 1,
15747
+ "maxLength": 128,
15748
+ "pattern": "^[!-~]+$"
15749
+ }
15750
+ },
15751
+ "required": [
15752
+ "name",
15753
+ "template_id",
15754
+ "audience_id",
15755
+ "idempotency_key"
15756
+ ],
15757
+ "additionalProperties": false
15758
+ }
15759
+ },
15760
+ {
15761
+ "name": "besales_broadcast_campaign_update",
15762
+ "description": "Изменить имя, описание, шаблон или аудиторию кампании до запуска. Прочитай текущую карточку. Сервер проверяет права и состояние кампании. Scope: manage:campaigns.",
15763
+ "inputSchema": {
15764
+ "type": "object",
15765
+ "properties": {
15766
+ "workspace_id": {
15767
+ "type": "string",
15768
+ "format": "uuid"
15769
+ },
15770
+ "campaign_id": {
15771
+ "type": "string",
15772
+ "format": "uuid"
15773
+ },
15774
+ "name": {
15775
+ "type": "string",
15776
+ "minLength": 1,
15777
+ "maxLength": 160
15778
+ },
15779
+ "description": {
15780
+ "type": [
15781
+ "string",
15782
+ "null"
15783
+ ]
15784
+ },
15785
+ "template_id": {
15786
+ "type": "string",
15787
+ "format": "uuid"
15788
+ },
15789
+ "audience_id": {
15790
+ "type": "string",
15791
+ "format": "uuid"
15792
+ }
15793
+ },
15794
+ "required": [
15795
+ "campaign_id"
15796
+ ],
15797
+ "additionalProperties": false
15798
+ }
15799
+ },
15800
+ {
15801
+ "name": "besales_broadcast_campaign_schedule",
15802
+ "description": "Установить время автоматического запуска кампании в очереди BeSales или снять его. В указанное время могут уйти сообщения реальным получателям. Согласуй время и аудиторию перед включением. Scopes: manage:campaigns, launch:campaigns для включения.",
15803
+ "inputSchema": {
15804
+ "type": "object",
15805
+ "properties": {
15806
+ "workspace_id": {
15807
+ "type": "string",
15808
+ "format": "uuid"
15809
+ },
15810
+ "campaign_id": {
15811
+ "type": "string",
15812
+ "format": "uuid"
15813
+ },
15814
+ "scheduled_at": {
15815
+ "type": [
15816
+ "string",
15817
+ "null"
15818
+ ],
15819
+ "format": "date-time",
15820
+ "description": "Момент запуска с UTC-смещением или null для снятия расписания."
15821
+ },
15822
+ "explicit_confirmation": {
15823
+ "type": "boolean",
15824
+ "const": true,
15825
+ "description": "Передай true после явного подтверждения пользователем момента запуска или его отмены."
15826
+ }
15827
+ },
15828
+ "required": [
15829
+ "campaign_id",
15830
+ "scheduled_at",
15831
+ "explicit_confirmation"
15832
+ ],
15833
+ "additionalProperties": false
15834
+ }
15835
+ },
15622
15836
  {
15623
15837
  "name": "besales_ai_costs_get",
15624
15838
  "description": "Фактический расход моделей рабочей области: summary, tasks и breakdown. group_by/page/limit есть только у breakdown, и там group_by обязателен. Период разбирается строго: параметр не своего режима, mode=days без days и диапазон без одной границы — отказ с именем параметра, а не молчаливый ответ за всё время; days при mode=range принимается и не действует — окно задают границы. Границы диапазона — дата-время С часовым поясом. unpricedEvents остаются неизвестной стоимостью, а не нулём. Видят владелец и администраторы. Scope: read:ai-costs.",
@@ -18519,12 +18733,12 @@
18519
18733
  "minLength": 1,
18520
18734
  "maxLength": 500,
18521
18735
  "pattern": "\\S",
18522
- "description": "Необязательный текст: 1–500 знаков после удаления пробелов по краям. Без text система подбирает разные английские апелляции для каждого номера."
18736
+ "description": "Необязательный текст. По умолчанию система подбирает разные английские апелляции для каждого номера."
18523
18737
  },
18524
18738
  "explicit_confirmation": {
18525
18739
  "type": "boolean",
18526
18740
  "const": true,
18527
- "description": "Явное согласие человека на необратимую отправку апелляции от номера."
18741
+ "description": "Только после явного согласия человека: номер отправит апелляцию @SpamBot от своего имени; отменить отправку нельзя."
18528
18742
  }
18529
18743
  },
18530
18744
  "oneOf": [
@@ -18761,7 +18975,7 @@
18761
18975
  },
18762
18976
  {
18763
18977
  "name": "besales_platform_telegram_personal_profile_bulk",
18764
- "description": "Изменить профили своих личных номеров Telegram пачкой. Меняются СВОИ номера канала, не клиенты: имя first_name, фамилия last_name, описание bio, дата рождения birthday (null снимает) и ники. Фото через этот инструмент не меняется — только в приложении. Требует manage:channels. Поля профиля одинаковы для всех выбранных номеров; пропуск поля сохраняет прежнее значение. Номера выбираются account_ids (1–100 уникальных UUID v4) либо all:true — ровно одно. Ники — один из двух режимов либо ни одного: usernames (по номерам: account_id и новый username; account_ids и all не передаются) или username_base (основа ника; номера выбираются account_ids или all). Оба режима ников сразу отвергаются до запроса. Ники необратимо освобождают прежние ники у Telegram: перед вызовом покажи человеку список номеров и новые значения и получи ответ «делать?»; явное explicit_confirmation не требуется. Операция идёт заданием фермы: ответ — принятие (job_id, state, total), а не итог; итог по каждому номеру смотри в besales_platform_telegram_personal_profile_job. Обязателен стабильный idempotency_key (1–200 видимых ASCII-символов без пробелов): повтор того же намерения — с тем же ключом и аргументами; при неизвестном исходе новый ключ автоматически не создавай.",
18978
+ "description": "Изменить профили своих личных номеров Telegram пачкой. Меняются СВОИ номера канала, не клиенты: имя first_name, фамилия last_name, описание bio, дата рождения birthday (null снимает) и ники. Фото: передай stored_file_id из besales_file_upload_request → besales_file_upload_status (дождись READY) — одно фото для всех выбранных номеров. Статичный JPEG, PNG или WebP до 5 МиБ из библиотеки этой рабочей области; пропуск сохраняет фото. При загрузке укажи file_type:IMAGE и source:USER_UPLOAD, без owner_kind/owner_id. FILE_NOT_FOUND (404) — загрузи файл в рабочую область канала; TELEGRAM_AVATAR_INVALID (400) или TELEGRAM_AVATAR_TOO_LARGE (413) — выбери корректное фото до 5 МиБ; TELEGRAM_AVATAR_CHANGED (409) — выбери файл заново. Для изменённого намерения нужен новый ключ. Требует manage:channels. Поля профиля одинаковы для всех выбранных номеров; пропуск поля сохраняет прежнее значение. Номера выбираются account_ids (1–100 уникальных UUID v4) либо all:true — ровно одно. Ники — один из двух режимов либо ни одного: usernames (по номерам: account_id и новый username; account_ids и all не передаются) или username_base (основа ника; номера выбираются account_ids или all). Оба режима ников сразу отвергаются до запроса. Ники необратимо освобождают прежние ники у Telegram: перед вызовом покажи человеку список номеров и новые значения и получи ответ «делать?»; явное explicit_confirmation не требуется. Операция идёт заданием фермы: ответ — принятие (job_id, state, total), а не итог; итог по каждому номеру смотри в besales_platform_telegram_personal_profile_job. Обязателен стабильный idempotency_key (1–200 видимых ASCII-символов без пробелов): повтор того же намерения — с тем же ключом и аргументами; при неизвестном исходе новый ключ автоматически не создавай.",
18765
18979
  "inputSchema": {
18766
18980
  "type": "object",
18767
18981
  "additionalProperties": false,
@@ -18882,6 +19096,12 @@
18882
19096
  "minLength": 1,
18883
19097
  "maxLength": 200,
18884
19098
  "pattern": "^[!-~]+$"
19099
+ },
19100
+ "stored_file_id": {
19101
+ "type": "string",
19102
+ "format": "uuid",
19103
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
19104
+ "description": "Одно фото для выбранных номеров: stored_file_id из besales_file_upload_request → besales_file_upload_status. Статичный JPEG, PNG или WebP до 5 МиБ из библиотеки этой рабочей области. Пропуск сохраняет фото."
18885
19105
  }
18886
19106
  },
18887
19107
  "allOf": [
@@ -18971,6 +19191,11 @@
18971
19191
  "required": [
18972
19192
  "username_base"
18973
19193
  ]
19194
+ },
19195
+ {
19196
+ "required": [
19197
+ "stored_file_id"
19198
+ ]
18974
19199
  }
18975
19200
  ]
18976
19201
  }
@@ -19003,26 +19228,660 @@
19003
19228
  }
19004
19229
  }
19005
19230
  }
19006
- }
19007
- ],
19008
- "resources": [
19231
+ },
19009
19232
  {
19010
- "uri": "besales://concepts/icp",
19011
- "name": "ICP Concept Reference",
19012
- "description": "Что такое ICP, segments / personas / scenarios.",
19013
- "mimeType": "text/markdown"
19233
+ "name": "besales_platform_telegram_personal_proxy_import_link",
19234
+ "description": "Выдать ссылку для массовой загрузки прокси личного Telegram в пул канала. Требует manage:channels; профиль platform. Ссылку отдать человеку: логины и пароли он вводит на защищённой странице после входа в приложение, не в чате. Ссылка одноразовая, живёт до expires_at. В ответе session_id, setup_page_url, expires_at; итог читай через besales_platform_telegram_personal_proxy_import_status. Создание ссылки ещё не означает загрузку прокси. Не передавай строки прокси через MCP.",
19235
+ "inputSchema": {
19236
+ "type": "object",
19237
+ "additionalProperties": false,
19238
+ "required": [
19239
+ "channel_id"
19240
+ ],
19241
+ "properties": {
19242
+ "workspace_id": {
19243
+ "type": "string",
19244
+ "format": "uuid"
19245
+ },
19246
+ "channel_id": {
19247
+ "type": "string",
19248
+ "format": "uuid"
19249
+ }
19250
+ }
19251
+ }
19014
19252
  },
19015
19253
  {
19016
- "uri": "besales://concepts/triggers",
19017
- "name": "Actions & Triggers Reference",
19018
- "description": "agent_actions, step types, condition language.",
19019
- "mimeType": "text/markdown"
19254
+ "name": "besales_platform_telegram_personal_proxy_import_status",
19255
+ "description": "Прочитать итог загрузки прокси личного Telegram по session_id и channel_id. Требует manage:channels (контракт защищённого импорта); профили readonly и platform. Возвращает только sessionId, status, expiresAt и summary: total, pending, accepted, duplicates, invalid, checkFailed, rejected, registered. Строк, логинов и паролей нет. COMPLETED — обработка завершена, итог смотри в счётчиках; AWAITING_INPUT — ждёт человека, SUBMITTING/PROCESSING — в работе, UNKNOWN — исход неизвестен, повтори чтение позже; EXPIRED/CANCELLED — сессия закрыта. Ничего не меняет.",
19256
+ "inputSchema": {
19257
+ "type": "object",
19258
+ "additionalProperties": false,
19259
+ "required": [
19260
+ "channel_id",
19261
+ "session_id"
19262
+ ],
19263
+ "properties": {
19264
+ "workspace_id": {
19265
+ "type": "string",
19266
+ "format": "uuid"
19267
+ },
19268
+ "channel_id": {
19269
+ "type": "string",
19270
+ "format": "uuid"
19271
+ },
19272
+ "session_id": {
19273
+ "type": "string",
19274
+ "format": "uuid"
19275
+ }
19276
+ }
19277
+ }
19020
19278
  },
19021
19279
  {
19022
- "uri": "besales://concepts/sandbox",
19023
- "name": "Sandbox Reference",
19024
- "description": "Что такое sandbox, какие сценарии тестирует.",
19025
- "mimeType": "text/markdown"
19280
+ "name": "besales_platform_telegram_personal_proxy_delete",
19281
+ "description": "Удалить свободный прокси из пула канала личного Telegram. Требует manage:channels; профиль platform. Удаление необратимо: покажи человеку канал и proxy_id и получи явное согласие, затем передай explicit_confirmation:true. Без подтверждения отказ до HTTP. 204 — прокси удалён; 409 TELEGRAM_PROXY_NOT_EMPTY — сначала переключите номера на другой прокси; 404 TELEGRAM_PROXY_NOT_FOUND — прокси не найден. Логины, пароли, host и port через MCP не принимаются.",
19282
+ "inputSchema": {
19283
+ "type": "object",
19284
+ "additionalProperties": false,
19285
+ "required": [
19286
+ "channel_id",
19287
+ "proxy_id",
19288
+ "explicit_confirmation"
19289
+ ],
19290
+ "properties": {
19291
+ "workspace_id": {
19292
+ "type": "string",
19293
+ "format": "uuid"
19294
+ },
19295
+ "channel_id": {
19296
+ "type": "string",
19297
+ "format": "uuid"
19298
+ },
19299
+ "proxy_id": {
19300
+ "type": "string",
19301
+ "format": "uuid"
19302
+ },
19303
+ "explicit_confirmation": {
19304
+ "type": "boolean",
19305
+ "const": true,
19306
+ "description": "Явное согласие человека на удаление прокси."
19307
+ }
19308
+ }
19309
+ }
19310
+ },
19311
+ {
19312
+ "name": "besales_platform_telegram_personal_account_proxy_change",
19313
+ "description": "Переключить свой личный номер Telegram на существующий прокси пула канала. Требует manage:channels; профиль platform. Номер переподключится: покажи человеку номер и целевой прокси и получи явное согласие, затем передай explicit_confirmation:true. Обязательны channel_id, account_id, proxy_id, стабильный action_id (UUID) и явный country_change_confirmed; значение по умолчанию не подставляй. Ответ — квитанция message, action_id, state, code?, retry_after_ms?. Успех только state=SUCCEEDED; UNKNOWN/PENDING не объявляй успехом, FAILED/EXPIRED — отказ. При повторе того же намерения сохраняй action_id и все аргументы, новый ключ автоматически не создавай. 404 TELEGRAM_PROXY_NOT_FOUND — целевой прокси не найден. При смене страны без согласия передай отказ человеку, автоматически согласие не повышай. Логины, пароли, host, port и edit-proxy через MCP не принимаются.",
19314
+ "inputSchema": {
19315
+ "type": "object",
19316
+ "additionalProperties": false,
19317
+ "required": [
19318
+ "channel_id",
19319
+ "account_id",
19320
+ "action_id",
19321
+ "proxy_id",
19322
+ "country_change_confirmed",
19323
+ "explicit_confirmation"
19324
+ ],
19325
+ "properties": {
19326
+ "workspace_id": {
19327
+ "type": "string",
19328
+ "format": "uuid"
19329
+ },
19330
+ "channel_id": {
19331
+ "type": "string",
19332
+ "format": "uuid"
19333
+ },
19334
+ "account_id": {
19335
+ "type": "string",
19336
+ "format": "uuid"
19337
+ },
19338
+ "action_id": {
19339
+ "type": "string",
19340
+ "format": "uuid",
19341
+ "description": "Стабильный UUID намерения: создай один раз, сохрани для повтора с теми же аргументами."
19342
+ },
19343
+ "proxy_id": {
19344
+ "type": "string",
19345
+ "format": "uuid"
19346
+ },
19347
+ "country_change_confirmed": {
19348
+ "type": "boolean",
19349
+ "description": "Явное решение человека о смене страны: true подтверждает, false не подтверждает. Обязательное поле без значения по умолчанию."
19350
+ },
19351
+ "explicit_confirmation": {
19352
+ "type": "boolean",
19353
+ "const": true,
19354
+ "description": "Явное согласие человека: номер переподключится."
19355
+ }
19356
+ }
19357
+ }
19358
+ },
19359
+ {
19360
+ "name": "besales_platform_telegram_personal_proxy_stock_list",
19361
+ "description": "Прочитать общий запас прокси пространства. Требует read:channels; профили readonly и platform. Фильтры status, country_code (две заглавные буквы), search (до 200 знаков), cursor (UUID), limit (1–100, сервер по умолчанию 50). nextCursor продолжает список; counts, freeProxies, countryCounts и freeCountryCounts относятся ко всему пулу без фильтров. Занятость — occupiedSlots, ёмкость — maxAccounts; accountsCount не показывает свободные места. Данные о стране — IPinfo (https://ipinfo.io). Запаса ещё нет — пустой список и нули. Логины и пароли не возвращаются.",
19362
+ "inputSchema": {
19363
+ "type": "object",
19364
+ "additionalProperties": false,
19365
+ "required": [],
19366
+ "properties": {
19367
+ "workspace_id": {
19368
+ "type": "string",
19369
+ "format": "uuid"
19370
+ },
19371
+ "status": {
19372
+ "type": "string",
19373
+ "enum": [
19374
+ "ACTIVE",
19375
+ "CHECKING",
19376
+ "ERROR",
19377
+ "INACTIVE"
19378
+ ]
19379
+ },
19380
+ "country_code": {
19381
+ "type": "string",
19382
+ "pattern": "^[A-Z]{2}$"
19383
+ },
19384
+ "search": {
19385
+ "type": "string",
19386
+ "maxLength": 200
19387
+ },
19388
+ "cursor": {
19389
+ "type": "string",
19390
+ "format": "uuid"
19391
+ },
19392
+ "limit": {
19393
+ "type": "integer",
19394
+ "minimum": 1,
19395
+ "maximum": 100
19396
+ }
19397
+ }
19398
+ }
19399
+ },
19400
+ {
19401
+ "name": "besales_platform_telegram_personal_proxy_stock_import_link",
19402
+ "description": "Выдать ссылку массового импорта в общий запас прокси пространства. Требует manage:channels и ключ вида MCP: ядро проверяет живой ключ, создателя и его свежую роль CHANNEL_MANAGE, аудит пишет до вызова фермы. Профиль platform. Логины и пароли человек вводит на защищённой странице после входа, не в чате. Одноразовая ссылка действует до expires_at; в ответе session_id, setup_page_url, expires_at, без setup_ref. До 50 строк, 1–3 номера на прокси. Выдача ссылки не означает загрузку; итог — besales_platform_telegram_personal_proxy_stock_import_status. После обрыва автоматически новую ссылку не создавай.",
19403
+ "inputSchema": {
19404
+ "type": "object",
19405
+ "additionalProperties": false,
19406
+ "required": [],
19407
+ "properties": {
19408
+ "workspace_id": {
19409
+ "type": "string",
19410
+ "format": "uuid"
19411
+ }
19412
+ }
19413
+ }
19414
+ },
19415
+ {
19416
+ "name": "besales_platform_telegram_personal_proxy_stock_import_status",
19417
+ "description": "Прочитать состояние и счётчики импорта в общий запас по session_id. Требует manage:channels и ключ вида MCP со свежей ролью CHANNEL_MANAGE создателя; профили readonly и platform. Только sessionId, status, expiresAt, summary (total, pending, accepted, duplicates, invalid, checkFailed, rejected, registered), без строк прокси. COMPLETED — обработка завершена, смотри счётчики; UNKNOWN не означает успех, повтори чтение позже; EXPIRED/CANCELLED — закрыта.",
19418
+ "inputSchema": {
19419
+ "type": "object",
19420
+ "additionalProperties": false,
19421
+ "required": [
19422
+ "session_id"
19423
+ ],
19424
+ "properties": {
19425
+ "workspace_id": {
19426
+ "type": "string",
19427
+ "format": "uuid"
19428
+ },
19429
+ "session_id": {
19430
+ "type": "string",
19431
+ "format": "uuid"
19432
+ }
19433
+ }
19434
+ }
19435
+ },
19436
+ {
19437
+ "name": "besales_platform_telegram_personal_proxy_stock_delete",
19438
+ "description": "Удалить свободный прокси из общего запаса пространства. Требует manage:channels и ключ вида MCP: ядро проверяет живой ключ, создателя и его свежую роль CHANNEL_MANAGE, аудит пишет до вызова фермы. Профиль platform. Удаление необратимо: покажи человеку пространство и proxy_id, получи явное согласие и передай explicit_confirmation:true. Без него отказ до HTTP. 204 — удалён; 409 TELEGRAM_PROXY_NOT_EMPTY — идёт операция, повторить позже; 404 TELEGRAM_PROXY_NOT_FOUND — не найден; 503 не означает успех.",
19439
+ "inputSchema": {
19440
+ "type": "object",
19441
+ "additionalProperties": false,
19442
+ "required": [
19443
+ "proxy_id",
19444
+ "explicit_confirmation"
19445
+ ],
19446
+ "properties": {
19447
+ "workspace_id": {
19448
+ "type": "string",
19449
+ "format": "uuid"
19450
+ },
19451
+ "proxy_id": {
19452
+ "type": "string",
19453
+ "format": "uuid"
19454
+ },
19455
+ "explicit_confirmation": {
19456
+ "type": "boolean",
19457
+ "const": true,
19458
+ "description": "Явное согласие человека на удаление прокси из запаса."
19459
+ }
19460
+ }
19461
+ }
19462
+ },
19463
+ {
19464
+ "name": "besales_platform_telegram_personal_proxy_stock_check",
19465
+ "description": "Проверить прокси общего запаса по proxy_id, обновить здоровье и страну. Требует manage:channels и ключ вида MCP: ядро проверяет живой ключ, создателя и его свежую роль CHANNEL_MANAGE, аудит пишет до вызова фермы. Профиль platform. 200 — результат проверки, 202 CHECKING — проверка ещё идёт, не объявляй прокси рабочим. Данные о стране — IPinfo (https://ipinfo.io).",
19466
+ "inputSchema": {
19467
+ "type": "object",
19468
+ "additionalProperties": false,
19469
+ "required": [
19470
+ "proxy_id"
19471
+ ],
19472
+ "properties": {
19473
+ "workspace_id": {
19474
+ "type": "string",
19475
+ "format": "uuid"
19476
+ },
19477
+ "proxy_id": {
19478
+ "type": "string",
19479
+ "format": "uuid"
19480
+ }
19481
+ }
19482
+ }
19483
+ },
19484
+ {
19485
+ "name": "besales_platform_telegram_personal_proxy_stock_check_all",
19486
+ "description": "Поставить на проверку все прокси общего запаса пространства. Требует manage:channels и ключ вида MCP: ядро проверяет живой ключ, создателя и его свежую роль CHANNEL_MANAGE, аудит пишет до вызова фермы. Профиль platform. queued — сколько поставлено в очередь, не число рабочих прокси. Итог перечитай через besales_platform_telegram_personal_proxy_stock_list.",
19487
+ "inputSchema": {
19488
+ "type": "object",
19489
+ "additionalProperties": false,
19490
+ "required": [],
19491
+ "properties": {
19492
+ "workspace_id": {
19493
+ "type": "string",
19494
+ "format": "uuid"
19495
+ }
19496
+ }
19497
+ }
19498
+ },
19499
+ {
19500
+ "name": "besales_platform_telegram_personal_proxies",
19501
+ "description": "Прочитать прокси существующего канала личного Telegram. Требует read:channels; профили readonly и platform. Фильтры status, country_code (две заглавные буквы), search (до 200 знаков), cursor (UUID), limit (1–100, сервер по умолчанию 50). nextCursor продолжает список; counts, freeProxies, countryCounts и freeCountryCounts относятся ко всему пулу без фильтров. Занятость — occupiedSlots, ёмкость — maxAccounts; accountsCount не показывает свободные места. Данные о стране — IPinfo (https://ipinfo.io). Для явной пары используй proxy_id, свободный прокси выбирай с учётом occupiedSlots, статуса и ёмкости.",
19502
+ "inputSchema": {
19503
+ "type": "object",
19504
+ "additionalProperties": false,
19505
+ "required": [
19506
+ "channel_id"
19507
+ ],
19508
+ "properties": {
19509
+ "workspace_id": {
19510
+ "type": "string",
19511
+ "format": "uuid"
19512
+ },
19513
+ "channel_id": {
19514
+ "type": "string",
19515
+ "format": "uuid"
19516
+ },
19517
+ "status": {
19518
+ "type": "string",
19519
+ "enum": [
19520
+ "ACTIVE",
19521
+ "CHECKING",
19522
+ "ERROR",
19523
+ "INACTIVE"
19524
+ ]
19525
+ },
19526
+ "country_code": {
19527
+ "type": "string",
19528
+ "pattern": "^[A-Z]{2}$"
19529
+ },
19530
+ "search": {
19531
+ "type": "string",
19532
+ "maxLength": 200
19533
+ },
19534
+ "cursor": {
19535
+ "type": "string",
19536
+ "format": "uuid"
19537
+ },
19538
+ "limit": {
19539
+ "type": "integer",
19540
+ "minimum": 1,
19541
+ "maximum": 100
19542
+ }
19543
+ }
19544
+ }
19545
+ },
19546
+ {
19547
+ "name": "besales_platform_telegram_personal_proxy_take_from_stock",
19548
+ "description": "Забрать прокси из общего запаса пространства в канал целиком, всё или ничего. Требует manage:channels и ключ вида MCP: ядро проверяет живой ключ, создателя и его свежую роль CHANNEL_MANAGE, аудит пишет до вызова фермы. Профиль platform. Перед вызовом покажи человеку, какие прокси (или сколько и из какой страны) и в какой канал переносишь, и получи «да». Поля explicit_confirmation нет. Ровно одна форма: proxy_ids (1–50 разных UUID) или count с необязательной country_code. count — число прокси: сколько ПРОКСИ забрать; у прокси 1–3 места (maxAccounts). При country_code прокси без определённой страны не участвуют; страны не смешиваются: нехватка означает отказ, без добора из других стран. Под N номеров выбирай proxy_ids из списка запаса по местам: заранее вычти места явных пар, затем выбери конкретные ACTIVE свободные прокси нужной страны, пока сумма maxAccounts не покроет недостачу. Если мест не хватает, не вызывай перенос. action_id (UUID) создаётся один на намерение и передаётся только заголовком X-Idempotency-Key. Новое намерение человека — новый action_id. Повтор того же намерения — тот же ключ и аргументы, в том числе при 503 (исход неизвестен). NOT_ENOUGH/REFUSED — ничего не перенесено, исправь причину; отказ ключом не запоминается. Изменение набора прокси согласуй как новое намерение с новым action_id. При IDEMPOTENCY_REQUEST_MISMATCH для того же намерения восстанови прежние аргументы и сохрани action_id; для нового намерения создай новый action_id после согласия человека.",
19549
+ "inputSchema": {
19550
+ "type": "object",
19551
+ "additionalProperties": false,
19552
+ "required": [
19553
+ "channel_id",
19554
+ "action_id"
19555
+ ],
19556
+ "properties": {
19557
+ "workspace_id": {
19558
+ "type": "string",
19559
+ "format": "uuid"
19560
+ },
19561
+ "channel_id": {
19562
+ "type": "string",
19563
+ "format": "uuid"
19564
+ },
19565
+ "action_id": {
19566
+ "type": "string",
19567
+ "format": "uuid"
19568
+ },
19569
+ "proxy_ids": {
19570
+ "type": "array",
19571
+ "items": {
19572
+ "type": "string",
19573
+ "format": "uuid"
19574
+ },
19575
+ "minItems": 1,
19576
+ "maxItems": 50,
19577
+ "uniqueItems": true
19578
+ },
19579
+ "count": {
19580
+ "type": "integer",
19581
+ "minimum": 1,
19582
+ "maximum": 50,
19583
+ "description": "Число прокси, не мест. Под номера выбирай proxy_ids по maxAccounts."
19584
+ },
19585
+ "country_code": {
19586
+ "type": "string",
19587
+ "pattern": "^[A-Z]{2}$"
19588
+ }
19589
+ },
19590
+ "oneOf": [
19591
+ {
19592
+ "required": [
19593
+ "proxy_ids"
19594
+ ],
19595
+ "not": {
19596
+ "anyOf": [
19597
+ {
19598
+ "required": [
19599
+ "count"
19600
+ ]
19601
+ },
19602
+ {
19603
+ "required": [
19604
+ "country_code"
19605
+ ]
19606
+ }
19607
+ ]
19608
+ }
19609
+ },
19610
+ {
19611
+ "required": [
19612
+ "count"
19613
+ ],
19614
+ "not": {
19615
+ "required": [
19616
+ "proxy_ids"
19617
+ ]
19618
+ }
19619
+ }
19620
+ ]
19621
+ }
19622
+ },
19623
+ {
19624
+ "name": "besales_platform_telegram_personal_proxy_return_to_stock",
19625
+ "description": "Вернуть свободный прокси канала в общий запас пространства. Требует manage:channels и ключ вида MCP: ядро проверяет живой ключ, создателя и его свежую роль CHANNEL_MANAGE, аудит пишет до вызова фермы. Профиль platform. Перед вызовом покажи человеку, какой прокси из какого канала возвращаешь в общий запас пространства, и получи «да». Поля explicit_confirmation нет. Обязательный action_id (UUID) создаётся один на намерение и передаётся только заголовком X-Idempotency-Key, тело отсутствует. Новое намерение человека — новый action_id. Повтор того же намерения — тот же ключ и аргументы; при 503 исход неизвестен, сохрани их. При IDEMPOTENCY_REQUEST_MISMATCH для того же намерения восстанови прежние аргументы и сохрани action_id; для нового намерения создай новый action_id после согласия человека. TELEGRAM_PROXY_NOT_EMPTY — сначала освободи прокси; TELEGRAM_PROXY_ADDRESS_IN_USE — такой адрес уже в запасе, предложи удалить этот прокси из канала; NOT_FOUND — перечитай список.",
19626
+ "inputSchema": {
19627
+ "type": "object",
19628
+ "additionalProperties": false,
19629
+ "required": [
19630
+ "channel_id",
19631
+ "proxy_id",
19632
+ "action_id"
19633
+ ],
19634
+ "properties": {
19635
+ "workspace_id": {
19636
+ "type": "string",
19637
+ "format": "uuid"
19638
+ },
19639
+ "channel_id": {
19640
+ "type": "string",
19641
+ "format": "uuid"
19642
+ },
19643
+ "proxy_id": {
19644
+ "type": "string",
19645
+ "format": "uuid"
19646
+ },
19647
+ "action_id": {
19648
+ "type": "string",
19649
+ "format": "uuid"
19650
+ }
19651
+ }
19652
+ }
19653
+ },
19654
+ {
19655
+ "name": "besales_platform_telegram_personal_connect_link",
19656
+ "description": "Выдать ссылку подключения номеров в существующий канал личного Telegram. Требует manage:channels, ключ MCP и свежую роль CHANNEL_MANAGE создателя на канал; профиль platform. channel_id обязателен. proxy_plan необязателен: ровно pairs (1–50 пар phone E.164 и proxy_id; разные телефоны, не больше трёх пар на один прокси) или country_code. При country_code прокси без определённой страны не участвуют; страны не смешиваются: нехватка означает отказ, без добора из других стран. План только заполняет страницу, не бронирует, не переносит и не подключает. Пары хранят исходный proxy_id: адрес только для показа, обратного разрешения адреса нет; пропавший id блокирует старт до правки человеком. Занятость проверяет страница при старте. Коды Telegram и пароль 2FA вводит человек на защищённой странице после входа, не в чате. В ответе setup_page_url и expires_at, без setup_ref и телефонов. Итог — besales_platform_telegram_personal_accounts. После обрыва автоматически новую ссылку не создавай.",
19657
+ "inputSchema": {
19658
+ "type": "object",
19659
+ "additionalProperties": false,
19660
+ "required": [
19661
+ "channel_id"
19662
+ ],
19663
+ "properties": {
19664
+ "workspace_id": {
19665
+ "type": "string",
19666
+ "format": "uuid"
19667
+ },
19668
+ "channel_id": {
19669
+ "type": "string",
19670
+ "format": "uuid"
19671
+ },
19672
+ "proxy_plan": {
19673
+ "oneOf": [
19674
+ {
19675
+ "type": "object",
19676
+ "additionalProperties": false,
19677
+ "required": [
19678
+ "pairs"
19679
+ ],
19680
+ "properties": {
19681
+ "pairs": {
19682
+ "type": "array",
19683
+ "minItems": 1,
19684
+ "maxItems": 50,
19685
+ "uniqueItems": true,
19686
+ "description": "Разные телефоны E.164; один proxy_id не больше трёх раз. Исходный id сохраняется, адрес обратно в id не разрешается.",
19687
+ "items": {
19688
+ "type": "object",
19689
+ "additionalProperties": false,
19690
+ "required": [
19691
+ "phone",
19692
+ "proxy_id"
19693
+ ],
19694
+ "properties": {
19695
+ "phone": {
19696
+ "type": "string",
19697
+ "pattern": "^\\+[1-9]\\d{6,14}$"
19698
+ },
19699
+ "proxy_id": {
19700
+ "type": "string",
19701
+ "format": "uuid"
19702
+ }
19703
+ }
19704
+ }
19705
+ }
19706
+ }
19707
+ },
19708
+ {
19709
+ "type": "object",
19710
+ "additionalProperties": false,
19711
+ "required": [
19712
+ "country_code"
19713
+ ],
19714
+ "properties": {
19715
+ "country_code": {
19716
+ "type": "string",
19717
+ "pattern": "^[A-Z]{2}$"
19718
+ }
19719
+ }
19720
+ }
19721
+ ]
19722
+ }
19723
+ }
19724
+ }
19725
+ },
19726
+ {
19727
+ "name": "besales_platform_telegram_personal_session_import_link",
19728
+ "description": "Выдать ссылку для загрузки до 50 файлов сессий Telegram в существующий канал. Требует manage:channels; профиль platform. Человек открывает ссылку, входит в приложение и выбирает импорт файлов, прокси на файл или автоназначение в браузере. MCP файлы, манифест, api_hash и пароли не принимает. Используется существующая страница подключения, TTL 15 минут. В ответе setup_page_url и expires_at; operation_id=null и import_status_available=false: ядро пока не выдаёт безопасный id операции и пофайловый статус для MCP. Итог сверить в браузере и через besales_platform_telegram_personal_accounts. Выдача ссылки не означает импорт. После обрыва автоматически новую ссылку не создавай.",
19729
+ "inputSchema": {
19730
+ "type": "object",
19731
+ "properties": {
19732
+ "workspace_id": {
19733
+ "type": "string",
19734
+ "format": "uuid",
19735
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
19736
+ },
19737
+ "channel_id": {
19738
+ "type": "string",
19739
+ "format": "uuid",
19740
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
19741
+ }
19742
+ },
19743
+ "required": [
19744
+ "channel_id"
19745
+ ],
19746
+ "additionalProperties": false
19747
+ }
19748
+ },
19749
+ {
19750
+ "name": "besales_platform_telegram_personal_outreach_calendar_get",
19751
+ "description": "Прочитать календарь рассылок личного Telegram-канала. Scope manage:channels. Вернёт переключатель, часы отправки, часовой пояс канала, рабочие дни с лимитами первых сообщений на номер и дату паузы.",
19752
+ "inputSchema": {
19753
+ "type": "object",
19754
+ "properties": {
19755
+ "workspace_id": {
19756
+ "type": "string",
19757
+ "format": "uuid",
19758
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
19759
+ },
19760
+ "platform_id": {
19761
+ "type": "string",
19762
+ "format": "uuid",
19763
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
19764
+ }
19765
+ },
19766
+ "required": [
19767
+ "platform_id"
19768
+ ],
19769
+ "additionalProperties": false
19770
+ }
19771
+ },
19772
+ {
19773
+ "name": "besales_platform_telegram_personal_outreach_calendar_set",
19774
+ "description": "Заменить календарь рассылок личного Telegram-канала. Scope manage:channels. Сначала прочитай календарь и сохрани нужные значения. enabled=false возвращает стандартный режим. Часы внутри 10:00–19:00 в поясе канала. weekday от 1 (понедельник) до 7 (воскресенье); пропущенные дни закрыты, max_per_number=null оставляет день без дополнительного лимита. pause_until — абсолютная дата ISO 8601 с часовым поясом либо null.",
19775
+ "inputSchema": {
19776
+ "type": "object",
19777
+ "properties": {
19778
+ "workspace_id": {
19779
+ "type": "string",
19780
+ "format": "uuid",
19781
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
19782
+ },
19783
+ "platform_id": {
19784
+ "type": "string",
19785
+ "format": "uuid",
19786
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
19787
+ },
19788
+ "calendar": {
19789
+ "type": "object",
19790
+ "properties": {
19791
+ "enabled": {
19792
+ "type": "boolean"
19793
+ },
19794
+ "start_hour": {
19795
+ "type": "integer",
19796
+ "minimum": 10,
19797
+ "maximum": 18
19798
+ },
19799
+ "end_hour": {
19800
+ "type": "integer",
19801
+ "minimum": 11,
19802
+ "maximum": 19
19803
+ },
19804
+ "days": {
19805
+ "minItems": 1,
19806
+ "maxItems": 7,
19807
+ "type": "array",
19808
+ "items": {
19809
+ "type": "object",
19810
+ "properties": {
19811
+ "weekday": {
19812
+ "type": "integer",
19813
+ "minimum": 1,
19814
+ "maximum": 7
19815
+ },
19816
+ "max_per_number": {
19817
+ "anyOf": [
19818
+ {
19819
+ "type": "integer",
19820
+ "minimum": 1,
19821
+ "maximum": 1000
19822
+ },
19823
+ {
19824
+ "type": "null"
19825
+ }
19826
+ ]
19827
+ }
19828
+ },
19829
+ "required": [
19830
+ "weekday",
19831
+ "max_per_number"
19832
+ ],
19833
+ "additionalProperties": false
19834
+ }
19835
+ },
19836
+ "pause_until": {
19837
+ "anyOf": [
19838
+ {
19839
+ "type": "string",
19840
+ "format": "date-time",
19841
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
19842
+ },
19843
+ {
19844
+ "type": "null"
19845
+ }
19846
+ ]
19847
+ }
19848
+ },
19849
+ "required": [
19850
+ "enabled",
19851
+ "start_hour",
19852
+ "end_hour",
19853
+ "days",
19854
+ "pause_until"
19855
+ ],
19856
+ "additionalProperties": false
19857
+ }
19858
+ },
19859
+ "required": [
19860
+ "platform_id",
19861
+ "calendar"
19862
+ ],
19863
+ "additionalProperties": false
19864
+ }
19865
+ }
19866
+ ],
19867
+ "resources": [
19868
+ {
19869
+ "uri": "besales://concepts/icp",
19870
+ "name": "ICP Concept Reference",
19871
+ "description": "Что такое ICP, segments / personas / scenarios.",
19872
+ "mimeType": "text/markdown"
19873
+ },
19874
+ {
19875
+ "uri": "besales://concepts/triggers",
19876
+ "name": "Actions & Triggers Reference",
19877
+ "description": "agent_actions, step types, condition language.",
19878
+ "mimeType": "text/markdown"
19879
+ },
19880
+ {
19881
+ "uri": "besales://concepts/sandbox",
19882
+ "name": "Sandbox Reference",
19883
+ "description": "Что такое sandbox, какие сценарии тестирует.",
19884
+ "mimeType": "text/markdown"
19026
19885
  },
19027
19886
  {
19028
19887
  "uri": "besales://concepts/handoff",
@@ -19242,7 +20101,7 @@
19242
20101
  }
19243
20102
  ],
19244
20103
  "summary": {
19245
- "total_tools": 306,
20104
+ "total_tools": 328,
19246
20105
  "tools_by_category": {
19247
20106
  "workspace_and_help": 18,
19248
20107
  "agent_configuration": 15,
@@ -19250,10 +20109,10 @@
19250
20109
  "icp": 11,
19251
20110
  "knowledge_and_content": 52,
19252
20111
  "crm_and_data_sources": 32,
19253
- "channels_and_credentials": 26,
20112
+ "channels_and_credentials": 43,
19254
20113
  "dialogues_and_contacts": 35,
19255
20114
  "automation": 5,
19256
- "outbound_and_analytics": 72
20115
+ "outbound_and_analytics": 77
19257
20116
  },
19258
20117
  "external_execution_pairs": [
19259
20118
  "besales_icp_analysis_get_instructions / submit",
@@ -19465,6 +20324,24 @@
19465
20324
  "besales_followup_sequence_list",
19466
20325
  "besales_followup_step_stats"
19467
20326
  ]
19468
- }
20327
+ },
20328
+ "newly_added_in_PROXYMCP1M": [
20329
+ "besales_platform_telegram_personal_proxy_import_link",
20330
+ "besales_platform_telegram_personal_proxy_import_status",
20331
+ "besales_platform_telegram_personal_proxy_delete",
20332
+ "besales_platform_telegram_personal_account_proxy_change"
20333
+ ],
20334
+ "newly_added_in_PROXYPOOL1M": [
20335
+ "besales_platform_telegram_personal_proxy_stock_list",
20336
+ "besales_platform_telegram_personal_proxy_stock_import_link",
20337
+ "besales_platform_telegram_personal_proxy_stock_import_status",
20338
+ "besales_platform_telegram_personal_proxy_stock_delete",
20339
+ "besales_platform_telegram_personal_proxy_stock_check",
20340
+ "besales_platform_telegram_personal_proxy_stock_check_all",
20341
+ "besales_platform_telegram_personal_proxies",
20342
+ "besales_platform_telegram_personal_proxy_take_from_stock",
20343
+ "besales_platform_telegram_personal_proxy_return_to_stock",
20344
+ "besales_platform_telegram_personal_connect_link"
20345
+ ]
19469
20346
  }
19470
20347
  }