@besales/mcp 0.38.0 → 0.40.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 CHANGED
@@ -290,10 +290,11 @@ connect each once and pin sessions via `BESALES_WORKSPACE_ID` (or switch the
290
290
  global default with `besales-mcp use <id>`) — see
291
291
  [Multiple Workspaces](#multiple-workspaces).
292
292
 
293
- ## Available tools (169 tools by category)
293
+ ## Available tools (193 tools by category)
294
294
 
295
- Counts are derived from `src/schemas/mcp-tools.json` (`summary.tools_by_category`)
296
- and asserted in `src/tools/registry.spec.ts`:
295
+ Итоговое число выводится из `src/schemas/mcp-tools.json` (`tools.length`) и закреплено в
296
+ `src/tools/registry.spec.ts`. ⚠️ Разбивка по категориям ниже и `summary.tools_by_category`
297
+ ведутся ВРУЧНУЮ и в сумме отстают от итога — тестами они не проверяются:
297
298
 
298
299
  | Category | Tools | Notes |
299
300
  |---|---|---|
@@ -320,9 +321,11 @@ and asserted in `src/tools/registry.spec.ts`:
320
321
  | Context / overview / audit | 3 | `besales_workspace_overview`, `besales_platform_context_get`, `besales_audit_revert` |
321
322
  | Session / workspace binding | 2 | `besales_workspace_use`, `besales_workspace_current` (in-memory per-session, local — no backend) |
322
323
  | Dialogue audit | 2 | `besales_dialogues_query`, `besales_dialogue_transcript` — read-only transcript + trigger-action evidence |
324
+ | Dialogue audit external | 2 | `besales_dialogue_audit_segments_get`, `besales_dialogue_audit_import` — сервер готовит материал ревизора read-only, разбирает клиент, находки возвращаются импортом |
323
325
  | Broadcast analytics | 2 | `besales_broadcast_analytics_get`, `besales_broadcast_cohorts_list` — authoritative read-only aggregates, drill-downs, segment/product catalogs, insights and payment-candidate reports from `/broadcast-analytics`, not transcript-derived counts |
324
326
  | GetCourse waves | 10 | `besales_getcourse_wave_import`, `besales_getcourse_wave_status`, `besales_getcourse_wave_run_start`, `besales_getcourse_wave_run_status`, `besales_getcourse_wave_run_contacts`, `besales_getcourse_wave_run_cancel`, `besales_getcourse_wave_run_batch_start`, `besales_getcourse_wave_run_batch_status`, `besales_getcourse_wave_run_batch_cancel`, `besales_getcourse_wave_run_batch_resume`; durable confirm использует стабильный `launch_key` + `dry_run_hash`, import/run/batch принимают `segment_description` |
325
327
  | Scheduled tasks | 2 | `besales_scheduled_task_list`, `besales_scheduled_task_update` — cron-driven dialogue analysis («суфлёр»): daily summary + hourly status written to the CRM timeline or as a hidden open-line message, never to the client |
328
+ | Link tracking (короткие ссылки) | 6 | `besales_tracked_link_list` / `_create` / `_update` / `_archive` / `_breakdown` / `_clicks` — каталог токенов `{{link:slug}}` для текстов дожимов и рассылок; удаления нет (архивация), правка адреса историю выдач не переписывает |
326
329
  | Follow-up (read) | 2 | `besales_followup_sequence_list`, `besales_followup_step_stats` — read a sequence config before a read-modify-write upsert, and see per-step delivery/skip reasons |
327
330
 
328
331
  Recent capabilities:
@@ -390,7 +393,7 @@ Inspect them locally:
390
393
  yarn dlx @modelcontextprotocol/inspector node bin/besales-mcp.js
391
394
  ```
392
395
 
393
- The Inspector should show 169 tools and 31 resources.
396
+ The Inspector should show 193 tools and 31 resources.
394
397
 
395
398
  ## Codex Dialogue Audit Skill
396
399
 
@@ -434,7 +437,7 @@ Claude Code, and Codex CLI are documented in
434
437
  - This package calls Animaly only through `ai-aniomaly` `/api/v2/*`.
435
438
  - Direct calls to `prompt-services` are intentionally out of scope.
436
439
 
437
- The package exposes 169 active MCP tools from `src/schemas/mcp-tools.json`.
440
+ The package exposes 191 active MCP tools from `src/schemas/mcp-tools.json`.
438
441
 
439
442
  ### Token scopes
440
443
 
@@ -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-07-28",
5
+ "lastUpdated": "2026-08-17",
6
6
  "description": "MCP tool schemas для besales-mcp npm package. Active v1.5 set содержит PromptHub/ICP/Sandbox/Knowledge external-execution operations и stateless Platform Setup Bridge direct tools. 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.",
@@ -3623,6 +3623,48 @@
3623
3623
  "messageConfig": {
3624
3624
  "type": "object",
3625
3625
  "description": "Текст/шаблон касания. Плейсхолдеры {name} календарного шага обязаны резолвиться, иначе шаг пропускается в рантайме."
3626
+ },
3627
+ "getcourse": {
3628
+ "type": "object",
3629
+ "description": "Каналы отправки ШАГА, только GetCourse. К шагу-вебхуку неприменимо.",
3630
+ "properties": {
3631
+ "delivery": {
3632
+ "type": "object",
3633
+ "required": [
3634
+ "mode"
3635
+ ],
3636
+ "description": "Набор каналов шага. Поля нет — набор решает состояние контакта: ответил, значит ровно его канал; молчит, значит все его привязки. 'all' — привязки плюс канал ответа плюс Email/Сайт/Chatium; SMS в него НЕ входит (у отправки один текст на весь набор, SMS нужен свой короткий) и задаётся только через 'explicit' отдельным шагом. Пустое пересечение с разрешёнными каналами площадки — шаг пропускается, цепочка идёт дальше.",
3637
+ "properties": {
3638
+ "mode": {
3639
+ "type": "string",
3640
+ "enum": [
3641
+ "contact",
3642
+ "all",
3643
+ "explicit"
3644
+ ]
3645
+ },
3646
+ "transports": {
3647
+ "type": "array",
3648
+ "description": "Только для mode='explicit'; в остальных режимах поле отвергается как ничего не меняющее.",
3649
+ "items": {
3650
+ "type": "string",
3651
+ "enum": [
3652
+ "Site",
3653
+ "Email",
3654
+ "SMS",
3655
+ "Telegram",
3656
+ "Facebook",
3657
+ "VK",
3658
+ "Chatium",
3659
+ "WhatsApp",
3660
+ "Viber",
3661
+ "MAX"
3662
+ ]
3663
+ }
3664
+ }
3665
+ }
3666
+ }
3667
+ }
3626
3668
  }
3627
3669
  }
3628
3670
  }
@@ -8091,7 +8133,7 @@
8091
8133
  },
8092
8134
  {
8093
8135
  "name": "besales_broadcast_analytics_get",
8094
- "description": "Read-only все данные страницы /broadcast-analytics: отчёты, drill-down, справочники сегментов и продуктов, качество данных и подтверждения оплат. Выбери report; общие фильтры совпадают с UI. Scope: read:analytics.",
8136
+ "description": "Read-only все данные страницы /broadcast-analytics: отчёты, drill-down, справочники сегментов и продуктов, качество данных и подтверждения оплат. Выбери report; общие фильтры совпадают с UI. Scope: read:analytics для агрегатов; отчёты со строками про конкретных людей (recipients, deals, action_failures, indirect_payments, potential_payments, recent_leads, payment_candidates) требуют дополнительно read:conversations — композитный mcp:* покрывает оба.",
8095
8137
  "inputSchema": {
8096
8138
  "type": "object",
8097
8139
  "required": [],
@@ -8213,30 +8255,6 @@
8213
8255
  ],
8214
8256
  "description": "Один или несколько ID именованных вариантов рассылки."
8215
8257
  },
8216
- "mechanism": {
8217
- "oneOf": [
8218
- {
8219
- "type": "string",
8220
- "enum": [
8221
- "wave",
8222
- "cold_welcome"
8223
- ]
8224
- },
8225
- {
8226
- "type": "array",
8227
- "minItems": 1,
8228
- "maxItems": 2,
8229
- "items": {
8230
- "type": "string",
8231
- "enum": [
8232
- "wave",
8233
- "cold_welcome"
8234
- ]
8235
- }
8236
- }
8237
- ],
8238
- "description": "Механизм запуска: wave — доставляет процесс школы (мы штампуем поля сделки), cold_welcome — пишем первыми сами. Оба значения = фильтра нет."
8239
- },
8240
8258
  "product": {
8241
8259
  "oneOf": [
8242
8260
  {
@@ -8452,6 +8470,30 @@
8452
8470
  "include_archived": {
8453
8471
  "type": "boolean",
8454
8472
  "description": "Только для report=payment_candidates."
8473
+ },
8474
+ "mechanism": {
8475
+ "oneOf": [
8476
+ {
8477
+ "type": "string",
8478
+ "enum": [
8479
+ "wave",
8480
+ "cold_welcome"
8481
+ ]
8482
+ },
8483
+ {
8484
+ "type": "array",
8485
+ "minItems": 1,
8486
+ "maxItems": 2,
8487
+ "items": {
8488
+ "type": "string",
8489
+ "enum": [
8490
+ "wave",
8491
+ "cold_welcome"
8492
+ ]
8493
+ }
8494
+ }
8495
+ ],
8496
+ "description": "Механизм запуска: wave — доставляет процесс школы (мы штампуем поля сделки), cold_welcome — пишем первыми сами. Оба значения = фильтра нет."
8455
8497
  }
8456
8498
  }
8457
8499
  }
@@ -8553,30 +8595,6 @@
8553
8595
  }
8554
8596
  ]
8555
8597
  },
8556
- "mechanism": {
8557
- "oneOf": [
8558
- {
8559
- "type": "string",
8560
- "enum": [
8561
- "wave",
8562
- "cold_welcome"
8563
- ]
8564
- },
8565
- {
8566
- "type": "array",
8567
- "minItems": 1,
8568
- "maxItems": 2,
8569
- "items": {
8570
- "type": "string",
8571
- "enum": [
8572
- "wave",
8573
- "cold_welcome"
8574
- ]
8575
- }
8576
- }
8577
- ],
8578
- "description": "Механизм запуска: wave — доставляет процесс школы (мы штампуем поля сделки), cold_welcome — пишем первыми сами. Оба значения = фильтра нет."
8579
- },
8580
8598
  "product": {
8581
8599
  "oneOf": [
8582
8600
  {
@@ -8675,6 +8693,30 @@
8675
8693
  "period"
8676
8694
  ],
8677
8695
  "default": "period"
8696
+ },
8697
+ "mechanism": {
8698
+ "oneOf": [
8699
+ {
8700
+ "type": "string",
8701
+ "enum": [
8702
+ "wave",
8703
+ "cold_welcome"
8704
+ ]
8705
+ },
8706
+ {
8707
+ "type": "array",
8708
+ "minItems": 1,
8709
+ "maxItems": 2,
8710
+ "items": {
8711
+ "type": "string",
8712
+ "enum": [
8713
+ "wave",
8714
+ "cold_welcome"
8715
+ ]
8716
+ }
8717
+ }
8718
+ ],
8719
+ "description": "Механизм запуска: wave — доставляет процесс школы (мы штампуем поля сделки), cold_welcome — пишем первыми сами. Оба значения = фильтра нет."
8678
8720
  }
8679
8721
  }
8680
8722
  }
@@ -9788,7 +9830,7 @@
9788
9830
  },
9789
9831
  {
9790
9832
  "name": "besales_dialogue_audit_findings",
9791
- "description": "Находки прогона — материал для правки промпта. Фильтры: агент, категория, важность, статус разметки человеком (NEW/LIKED/DISLIKED). truncated=true означает обрезанный список. Разметка находок через MCP НЕ выведена: это человеческая оценка работы ревизора. Scope: read:analytics.",
9833
+ "description": "Находки прогона — материал для правки промпта. Фильтры: агент, категория, важность, статус разметки человеком (NEW/LIKED/DISLIKED). truncated=true означает обрезанный список. Разметка находок через MCP НЕ выведена: это человеческая оценка работы ревизора. Scope: read:analytics + read:conversations — находка несёт цитату реплики конкретного человека, а не агрегат (композитный mcp:* покрывает оба).",
9792
9834
  "inputSchema": {
9793
9835
  "type": "object",
9794
9836
  "required": [
@@ -9879,6 +9921,360 @@
9879
9921
  }
9880
9922
  }
9881
9923
  }
9924
+ },
9925
+ {
9926
+ "name": "besales_dialogue_audit_segments_get",
9927
+ "description": "Материал ревизора для разбора СВОЕЙ моделью: методика (хеш), реконструированный промпт агента и транскрипты отрезков с якорями msg=. Страница однородна — один агент и один снимок промпта. Ничего не пишет: водяной знак двигает импорт, поэтому две выдачи подряд вернут одну и ту же страницу. Scope: read:conversations + read:agents.",
9928
+ "inputSchema": {
9929
+ "type": "object",
9930
+ "required": [
9931
+ "platform_id"
9932
+ ],
9933
+ "additionalProperties": false,
9934
+ "properties": {
9935
+ "platform_id": {
9936
+ "type": "string",
9937
+ "format": "uuid",
9938
+ "description": "Канал (платформа)."
9939
+ }
9940
+ }
9941
+ }
9942
+ },
9943
+ {
9944
+ "name": "besales_dialogue_audit_import",
9945
+ "description": "Импорт находок внешнего разбора. Перечисляй ВСЕ разобранные отрезки, включая чистые: тикет — единственное, что двигает их водяной знак. Сервер проверяет свою подпись, пересобирает подготовку и принимает находки через ту же границу якорей, что и внутренний путь. Scope: mcp:platform-setup + read:conversations.",
9946
+ "inputSchema": {
9947
+ "type": "object",
9948
+ "required": [
9949
+ "platform_id",
9950
+ "tickets",
9951
+ "findings"
9952
+ ],
9953
+ "additionalProperties": false,
9954
+ "properties": {
9955
+ "platform_id": {
9956
+ "type": "string",
9957
+ "format": "uuid",
9958
+ "description": "Канал (платформа)."
9959
+ },
9960
+ "client_id": {
9961
+ "type": "string",
9962
+ "minLength": 2,
9963
+ "maxLength": 40,
9964
+ "description": "Кто разбирал: попадает в model прогона как external:<client_id>. По умолчанию claude-code."
9965
+ },
9966
+ "principles_hash": {
9967
+ "type": "string",
9968
+ "minLength": 1,
9969
+ "maxLength": 64,
9970
+ "description": "sha256 методики, по которой шёл разбор. Расхождение с хешем прогона = разбор по другой версии правил."
9971
+ },
9972
+ "tickets": {
9973
+ "type": "array",
9974
+ "minItems": 1,
9975
+ "maxItems": 25,
9976
+ "items": {
9977
+ "type": "string",
9978
+ "minLength": 1
9979
+ },
9980
+ "description": "Тикеты ВСЕХ разобранных отрезков, включая те, где находок нет."
9981
+ },
9982
+ "findings": {
9983
+ "type": "array",
9984
+ "maxItems": 500,
9985
+ "items": {
9986
+ "type": "object",
9987
+ "required": [
9988
+ "ticket",
9989
+ "category",
9990
+ "severity",
9991
+ "title",
9992
+ "description",
9993
+ "primary_message_id"
9994
+ ],
9995
+ "additionalProperties": false,
9996
+ "properties": {
9997
+ "ticket": {
9998
+ "type": "string",
9999
+ "minLength": 1,
10000
+ "description": "Тикет отрезка из выдачи. Непрозрачная подписанная строка: назвать отрезок самому нельзя."
10001
+ },
10002
+ "category": {
10003
+ "type": "string",
10004
+ "enum": [
10005
+ "HALLUCINATION",
10006
+ "WRONG_ACTION",
10007
+ "WRONG_ROUTING",
10008
+ "BAD_TONE",
10009
+ "MISSED_CONTEXT",
10010
+ "RAG_MISS",
10011
+ "SCRIPT_DEVIATION",
10012
+ "PROMPT_VIOLATION",
10013
+ "CUSTOM_RULE_CONFLICT",
10014
+ "OTHER"
10015
+ ],
10016
+ "description": "Категория находки."
10017
+ },
10018
+ "severity": {
10019
+ "type": "string",
10020
+ "enum": [
10021
+ "LOW",
10022
+ "MEDIUM",
10023
+ "CRITICAL"
10024
+ ],
10025
+ "description": "Важность."
10026
+ },
10027
+ "title": {
10028
+ "type": "string",
10029
+ "minLength": 1,
10030
+ "maxLength": 300,
10031
+ "description": "Заголовок находки."
10032
+ },
10033
+ "description": {
10034
+ "type": "string",
10035
+ "minLength": 1,
10036
+ "maxLength": 4000,
10037
+ "description": "Что не так и почему."
10038
+ },
10039
+ "prompt_suggestion": {
10040
+ "type": "string",
10041
+ "maxLength": 4000,
10042
+ "description": "Что поменять в промпте — текст предложения, не патч."
10043
+ },
10044
+ "primary_message_id": {
10045
+ "type": "string",
10046
+ "minLength": 1,
10047
+ "description": "Якорь: значение msg= из транскрипта. Сервер проверяет принадлежность отрезку и новизну по курсору."
10048
+ },
10049
+ "quote": {
10050
+ "type": "string",
10051
+ "maxLength": 4000,
10052
+ "description": "Цитата реплики — доказательство."
10053
+ }
10054
+ }
10055
+ },
10056
+ "description": "Находки разбора; пустой массив — законный результат «претензий нет»."
10057
+ }
10058
+ }
10059
+ }
10060
+ },
10061
+ {
10062
+ "name": "besales_tracked_link_list",
10063
+ "description": "Каталог коротких трекинговых ссылок workspace со сводкой «выдано → клики → ответы → заявки → оплаты». Поле placeholder — готовый токен {{link:slug}} для текстов дожимов, рассылок и шаблонов: вставляется ИМЕННО он, сырой URL мимо трекинга не считается. staticUrl — анонимный короткий адрес для мест без персональной выдачи (промпт агента, письмо школы). Ответ постраничный; hasMore=true означает, что каталог не дочитан. Scope: read:analytics. ⚠️ Токен берётся ТОЛЬКО копированием поля placeholder: собранный вручную токен с неточным слагом вырезается вместе с маркером, и клиент получает фразу без ссылки. В промпт агента токен не кладут — там staticUrl.",
10064
+ "inputSchema": {
10065
+ "type": "object",
10066
+ "required": [],
10067
+ "additionalProperties": false,
10068
+ "properties": {
10069
+ "workspace_id": {
10070
+ "type": "string",
10071
+ "format": "uuid",
10072
+ "description": "Optional override. Normally omit — defaults to the workspace bound to this session."
10073
+ },
10074
+ "include_archived": {
10075
+ "type": "boolean",
10076
+ "description": "Показать и архивные ссылки. Их слаги ЗАНЯТЫ: создание с тем же слагом даст 409. Архивные идут первыми."
10077
+ },
10078
+ "days": {
10079
+ "type": "integer",
10080
+ "minimum": 1,
10081
+ "maximum": 366,
10082
+ "description": "Глубина сводки в днях (по умолчанию 60)."
10083
+ },
10084
+ "limit": {
10085
+ "type": "integer",
10086
+ "minimum": 1,
10087
+ "maximum": 200,
10088
+ "description": "Размер страницы (по умолчанию 50)."
10089
+ },
10090
+ "offset": {
10091
+ "type": "integer",
10092
+ "minimum": 0,
10093
+ "description": "Смещение страницы."
10094
+ }
10095
+ }
10096
+ }
10097
+ },
10098
+ {
10099
+ "name": "besales_tracked_link_create",
10100
+ "description": "Завести трекинговую ссылку: имя, слаг и целевой http(s)-адрес. В ответе приходит placeholder {{link:slug}} — вставляй его в тексты вместо сырого URL, иначе переход не попадёт в аналитику. Слаг НЕИЗМЕНЯЕМ (он уходит в отправленные сообщения) и уникален в workspace; 409 значит, что слаг занят живой ИЛИ архивной ссылкой — архивную восстанавливают besales_tracked_link_update(restore=true), а не заводят новую. Scope: mcp:platform-setup. ⚠️ В тексты вставляется поле placeholder из ответа ДОСЛОВНО, а не собранный вручную токен: неточный слаг вырежется и клиент получит фразу без ссылки.",
10101
+ "inputSchema": {
10102
+ "type": "object",
10103
+ "required": [
10104
+ "name",
10105
+ "slug",
10106
+ "target_url"
10107
+ ],
10108
+ "additionalProperties": false,
10109
+ "properties": {
10110
+ "workspace_id": {
10111
+ "type": "string",
10112
+ "format": "uuid",
10113
+ "description": "Optional override. Normally omit — defaults to the workspace bound to this session."
10114
+ },
10115
+ "name": {
10116
+ "type": "string",
10117
+ "minLength": 1,
10118
+ "maxLength": 200,
10119
+ "description": "Название для аналитики, например «Эфир 1, 15:00»."
10120
+ },
10121
+ "slug": {
10122
+ "type": "string",
10123
+ "pattern": "^[a-zA-Z0-9_-]{1,64}$",
10124
+ "description": "Часть плейсхолдера {{link:slug}}: латиница, цифры, дефис, подчёркивание, до 64 символов. Изменить потом нельзя."
10125
+ },
10126
+ "target_url": {
10127
+ "type": "string",
10128
+ "maxLength": 2048,
10129
+ "description": "Абсолютный http(s)-адрес, куда ведёт ссылка. Только http/https.",
10130
+ "pattern": "^https?://"
10131
+ },
10132
+ "product_code": {
10133
+ "type": "string",
10134
+ "maxLength": 64,
10135
+ "description": "Код продукта для сводки каталога."
10136
+ }
10137
+ }
10138
+ }
10139
+ },
10140
+ {
10141
+ "name": "besales_tracked_link_update",
10142
+ "description": "Изменить название, целевой адрес или код продукта ссылки либо снять её из архива (restore=true). Требуется хотя бы одно изменяемое поле. ⚠️ Правка target_url действует ТОЛЬКО ВПЕРЁД: персональные коды, уже ушедшие людям, остаются на СТАРОМ адресе (каждая выдача хранит снимок адреса на момент отправки, резолвер читает его), новые выдачи получат новый адрес, анонимный staticUrl переключится сразу. Перенаправить тех, кому ссылка уже отправлена, правкой НЕЛЬЗЯ — нужна новая ссылка в новом тексте. Поля ответа сюда не копируются: slug неизменяем, archivedAt не поле записи (архивация — besales_tracked_link_archive), счётчики и placeholder только читаются. Scope: mcp:platform-setup.",
10143
+ "inputSchema": {
10144
+ "type": "object",
10145
+ "required": [
10146
+ "link_id"
10147
+ ],
10148
+ "additionalProperties": false,
10149
+ "properties": {
10150
+ "workspace_id": {
10151
+ "type": "string",
10152
+ "format": "uuid",
10153
+ "description": "Optional override. Normally omit — defaults to the workspace bound to this session."
10154
+ },
10155
+ "link_id": {
10156
+ "type": "string",
10157
+ "format": "uuid",
10158
+ "description": "UUID ссылки из каталога."
10159
+ },
10160
+ "name": {
10161
+ "type": "string",
10162
+ "minLength": 1,
10163
+ "maxLength": 200
10164
+ },
10165
+ "target_url": {
10166
+ "type": "string",
10167
+ "maxLength": 2048,
10168
+ "description": "Новый абсолютный http(s)-адрес. Действует только вперёд: уже отправленные персональные коды остаются на прежней цели (там снимок адреса).",
10169
+ "pattern": "^https?://"
10170
+ },
10171
+ "product_code": {
10172
+ "type": "string",
10173
+ "maxLength": 64
10174
+ },
10175
+ "restore": {
10176
+ "const": true,
10177
+ "type": "boolean",
10178
+ "description": "Снять ссылку из архива. Архивирует besales_tracked_link_archive."
10179
+ }
10180
+ }
10181
+ }
10182
+ },
10183
+ {
10184
+ "name": "besales_tracked_link_archive",
10185
+ "description": "Архивировать ссылку. Удаления у трекинговых ссылок НЕТ и не будет: код уже лежит в отправленных людям сообщениях, и hard-delete превратил бы живую ссылку в 404. Архивная ссылка перестаёт подставляться в новые тексты, но её код продолжает резолвиться, клики считаются, а слаг остаётся занятым. Восстановление — besales_tracked_link_update(restore=true). Требует explicit_confirmation=true после явного подтверждения пользователя. Scope: mcp:platform-setup.",
10186
+ "inputSchema": {
10187
+ "type": "object",
10188
+ "required": [
10189
+ "link_id",
10190
+ "explicit_confirmation"
10191
+ ],
10192
+ "additionalProperties": false,
10193
+ "properties": {
10194
+ "workspace_id": {
10195
+ "type": "string",
10196
+ "format": "uuid",
10197
+ "description": "Optional override. Normally omit — defaults to the workspace bound to this session."
10198
+ },
10199
+ "link_id": {
10200
+ "type": "string",
10201
+ "format": "uuid",
10202
+ "description": "UUID ссылки из каталога."
10203
+ },
10204
+ "explicit_confirmation": {
10205
+ "const": true,
10206
+ "type": "boolean",
10207
+ "description": "Подтверждение пользователя на архивацию ссылки."
10208
+ }
10209
+ }
10210
+ }
10211
+ },
10212
+ {
10213
+ "name": "besales_tracked_link_breakdown",
10214
+ "description": "Разрез одной ссылки по источникам выдачи: WAVE (волна), FOLLOWUP (дожим), CAMPAIGN (кампания), GREETING (приветствие), AGENT (обычный ответ агента) — с воронкой по каждому. Отвечает на вопрос «после чего по ссылке ходят», а не «каким сообщением она ушла». Оплата атрибутируется last-touch по ближайшему клику. Scope: read:analytics.",
10215
+ "inputSchema": {
10216
+ "type": "object",
10217
+ "required": [
10218
+ "link_id"
10219
+ ],
10220
+ "additionalProperties": false,
10221
+ "properties": {
10222
+ "workspace_id": {
10223
+ "type": "string",
10224
+ "format": "uuid",
10225
+ "description": "Optional override. Normally omit — defaults to the workspace bound to this session."
10226
+ },
10227
+ "link_id": {
10228
+ "type": "string",
10229
+ "format": "uuid",
10230
+ "description": "UUID ссылки из каталога."
10231
+ },
10232
+ "days": {
10233
+ "type": "integer",
10234
+ "minimum": 1,
10235
+ "maximum": 366,
10236
+ "description": "Глубина сводки в днях (по умолчанию 60)."
10237
+ }
10238
+ }
10239
+ }
10240
+ },
10241
+ {
10242
+ "name": "besales_tracked_link_clicks",
10243
+ "description": "Лента переходов по ссылке: контакт, сообщение, источник выдачи и время. Клики-предпросмотры мессенджеров отсеяны. ⚠️ Анонимные переходы по staticUrl В ЛЕНТЕ ЕСТЬ — строками с null в chatUserId/contactName/messageId/issuedAt/sourceKind (у анонимного кода человека нет по построению); не считай их людьми, их суммарное число лежит в каталоге полем anonymousClicks. ⚠️ total — число КЛИКОВ (включая повторные и анонимные), а clicked в каталоге — число ВЫДАЧ с первым живым кликом: величины разные и сходиться не обязаны. Постранично: page + page_size (максимум 200). Scope: read:analytics + read:conversations (лента несёт имя контакта и id сообщения; композитный mcp:* покрывает оба).",
10244
+ "inputSchema": {
10245
+ "type": "object",
10246
+ "required": [
10247
+ "link_id"
10248
+ ],
10249
+ "additionalProperties": false,
10250
+ "properties": {
10251
+ "workspace_id": {
10252
+ "type": "string",
10253
+ "format": "uuid",
10254
+ "description": "Optional override. Normally omit — defaults to the workspace bound to this session."
10255
+ },
10256
+ "link_id": {
10257
+ "type": "string",
10258
+ "format": "uuid",
10259
+ "description": "UUID ссылки из каталога."
10260
+ },
10261
+ "days": {
10262
+ "type": "integer",
10263
+ "minimum": 1,
10264
+ "maximum": 366,
10265
+ "description": "Глубина сводки в днях (по умолчанию 60)."
10266
+ },
10267
+ "page": {
10268
+ "type": "integer",
10269
+ "minimum": 1
10270
+ },
10271
+ "page_size": {
10272
+ "type": "integer",
10273
+ "minimum": 1,
10274
+ "maximum": 200
10275
+ }
10276
+ }
10277
+ }
9882
10278
  }
9883
10279
  ],
9884
10280
  "resources": [
@@ -10070,7 +10466,7 @@
10070
10466
  }
10071
10467
  ],
10072
10468
  "summary": {
10073
- "total_tools": 185,
10469
+ "total_tools": 193,
10074
10470
  "tools_by_category": {
10075
10471
  "getcourse_wave": 10,
10076
10472
  "files_upload": 3,
@@ -10109,7 +10505,9 @@
10109
10505
  "broadcast_analytics": 2,
10110
10506
  "scheduled_tasks": 2,
10111
10507
  "follow_up_read": 3,
10112
- "dialogue_audit": 6
10508
+ "dialogue_audit": 6,
10509
+ "link_tracking": 6,
10510
+ "dialogue_audit_external": 2
10113
10511
  },
10114
10512
  "external_execution_pairs": [
10115
10513
  "besales_icp_analysis_get_instructions / submit",
@@ -10301,6 +10699,14 @@
10301
10699
  ],
10302
10700
  "newly_added_in_followup_reactions": [
10303
10701
  "besales_followup_reactions"
10702
+ ],
10703
+ "newly_added_in_link_tracking": [
10704
+ "besales_tracked_link_list",
10705
+ "besales_tracked_link_create",
10706
+ "besales_tracked_link_update",
10707
+ "besales_tracked_link_archive",
10708
+ "besales_tracked_link_breakdown",
10709
+ "besales_tracked_link_clicks"
10304
10710
  ]
10305
10711
  }
10306
10712
  }
@@ -14,6 +14,14 @@ description: Read-only аудит production-переписок BeSales чере
14
14
  > чтобы починить промпт) — это другие инструменты: `besales_dialogue_audit_runs_list` →
15
15
  > `besales_dialogue_audit_findings`. Путать их нельзя: материал и выводы разные.
16
16
 
17
+ > ⭐ Если задача — «разобрать работу агента и починить промпт», а не «найти ложные заявки»,
18
+ > у ревизора с 17.08.2026 есть ВНЕШНИЙ режим, и материал в нём строго богаче сырой выгрузки:
19
+ > `besales_dialogue_audit_segments_get` отдаёт реконструированный промпт агента, механический линт
20
+ > и транскрипт с ПОЛНЫМИ результатами обращений в 1С/CRM (публичная выгрузка отдаёт только
21
+ > `{dealId, dealNumber, skipped}`), с якорями `msg=` и с пометками «НЕ судить» на репликах чужих
22
+ > агентов. Разбираешь своей моделью, возвращаешь через `besales_dialogue_audit_import` — находки
23
+ > ложатся в отчёт ревизора с водяными знаками и дедупом. Цикл замкнутый: выдача → разбор → импорт.
24
+
17
25
  1. Прочитай MCP resource `besales://workflows/audit-dialogues` и следуй ему как source of truth.
18
26
  2. Если период не задан, возьми последние 7 суток и явно зафиксируй допущение.
19
27
  3. Для точного аудита новых заявок фильтруй `GETCOURSE_CREATE_DEAL` через