@besales/mcp 0.46.0 → 0.47.1
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 +96 -55
- package/dist/auth/connection-store.d.ts +21 -1
- package/dist/auth/connection-store.js +46 -2
- package/dist/auth/connection-store.js.map +1 -1
- package/dist/auth/oauth-client.d.ts +5 -1
- package/dist/auth/oauth-client.js +22 -12
- package/dist/auth/oauth-client.js.map +1 -1
- package/dist/cli.js +14 -5
- package/dist/cli.js.map +1 -1
- package/dist/http/api-client.d.ts +16 -1
- package/dist/http/api-client.js +50 -2
- package/dist/http/api-client.js.map +1 -1
- package/dist/instructions/server-instructions.d.ts +4 -13
- package/dist/instructions/server-instructions.js +76 -274
- package/dist/instructions/server-instructions.js.map +1 -1
- package/dist/prompts/registry.d.ts +15 -0
- package/dist/prompts/registry.js +83 -0
- package/dist/prompts/registry.js.map +1 -0
- package/dist/resources/concepts/feedback-sheets.md +7 -4
- package/dist/resources/concepts/handoff.md +4 -1
- package/dist/resources/concepts/sandbox.md +14 -5
- package/dist/resources/concepts/triggers.md +6 -2
- package/dist/resources/concepts/workbook-classification.md +26 -21
- package/dist/resources/docs/campaigns.md +20 -0
- package/dist/resources/docs/follow-up.md +19 -0
- package/dist/resources/docs/platforms.md +2 -2
- package/dist/resources/docs/routing.md +18 -0
- package/dist/resources/docs/task-state.md +30 -0
- package/dist/resources/docs/trigger-actions.md +28 -0
- package/dist/resources/docs/variables.md +18 -0
- package/dist/resources/registry.js +51 -2
- package/dist/resources/registry.js.map +1 -1
- package/dist/resources/workflows/extract-from-document.md +8 -1
- package/dist/resources/workflows/iterate-with-sandbox.md +5 -2
- package/dist/resources/workflows/platform-setup-from-scratch.md +90 -2
- package/dist/resources/workflows/production-readiness-check.md +22 -18
- package/dist/schemas/mcp-tools.json +1139 -96
- package/dist/server.d.ts +2 -0
- package/dist/server.js +8 -2
- package/dist/server.js.map +1 -1
- package/dist/tasks/task-state-store.d.ts +68 -0
- package/dist/tasks/task-state-store.js +278 -0
- package/dist/tasks/task-state-store.js.map +1 -0
- package/dist/tools/annotations.d.ts +7 -0
- package/dist/tools/annotations.js +16 -0
- package/dist/tools/annotations.js.map +1 -0
- package/dist/tools/contracts.js +7 -1
- package/dist/tools/contracts.js.map +1 -1
- package/dist/tools/definitions/agent-design.d.ts +41 -20
- package/dist/tools/definitions/agent-design.js +189 -19
- package/dist/tools/definitions/agent-design.js.map +1 -1
- package/dist/tools/definitions/analytics.d.ts +40 -0
- package/dist/tools/definitions/analytics.js +233 -0
- package/dist/tools/definitions/analytics.js.map +1 -0
- package/dist/tools/definitions/broadcast-analytics.js +12 -0
- package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
- package/dist/tools/definitions/broadcast-mailing-variants.d.ts +2 -0
- package/dist/tools/definitions/broadcast-mailing-variants.js +10 -0
- package/dist/tools/definitions/broadcast-mailing-variants.js.map +1 -1
- package/dist/tools/definitions/broadcast-scheduler.d.ts +14 -1
- package/dist/tools/definitions/broadcast-scheduler.js +148 -12
- package/dist/tools/definitions/broadcast-scheduler.js.map +1 -1
- package/dist/tools/definitions/contacts.d.ts +15 -0
- package/dist/tools/definitions/contacts.js +84 -0
- package/dist/tools/definitions/contacts.js.map +1 -0
- package/dist/tools/definitions/crm-platform.d.ts +2 -0
- package/dist/tools/definitions/crm-platform.js +75 -5
- package/dist/tools/definitions/crm-platform.js.map +1 -1
- package/dist/tools/definitions/datasource.d.ts +1 -0
- package/dist/tools/definitions/datasource.js +16 -1
- package/dist/tools/definitions/datasource.js.map +1 -1
- package/dist/tools/definitions/dialogue-audit.d.ts +2 -2
- package/dist/tools/definitions/dialogue-audit.js +54 -16
- package/dist/tools/definitions/dialogue-audit.js.map +1 -1
- package/dist/tools/definitions/dialogue-export.d.ts +1 -1
- package/dist/tools/definitions/dialogue-export.js +12 -0
- package/dist/tools/definitions/dialogue-export.js.map +1 -1
- package/dist/tools/definitions/external-api-channels.js +39 -12
- package/dist/tools/definitions/external-api-channels.js.map +1 -1
- package/dist/tools/definitions/follow-up-funnel-test.js +4 -0
- package/dist/tools/definitions/follow-up-funnel-test.js.map +1 -1
- package/dist/tools/definitions/follow-up-setup.js +3 -0
- package/dist/tools/definitions/follow-up-setup.js.map +1 -1
- package/dist/tools/definitions/follow-up.d.ts +2 -1
- package/dist/tools/definitions/follow-up.js +11 -0
- package/dist/tools/definitions/follow-up.js.map +1 -1
- package/dist/tools/definitions/getcourse-anchor-refresh.d.ts +3 -0
- package/dist/tools/definitions/getcourse-anchor-refresh.js +29 -2
- package/dist/tools/definitions/getcourse-anchor-refresh.js.map +1 -1
- package/dist/tools/definitions/getcourse-cold-welcome.d.ts +12 -2
- package/dist/tools/definitions/getcourse-cold-welcome.js +79 -4
- package/dist/tools/definitions/getcourse-cold-welcome.js.map +1 -1
- package/dist/tools/definitions/getcourse-wave.js +14 -0
- package/dist/tools/definitions/getcourse-wave.js.map +1 -1
- package/dist/tools/definitions/help.d.ts +8 -0
- package/dist/tools/definitions/help.js +219 -0
- package/dist/tools/definitions/help.js.map +1 -0
- package/dist/tools/definitions/knowledge.d.ts +27 -5
- package/dist/tools/definitions/knowledge.js +200 -33
- package/dist/tools/definitions/knowledge.js.map +1 -1
- package/dist/tools/definitions/link-tracking.js +9 -0
- package/dist/tools/definitions/link-tracking.js.map +1 -1
- package/dist/tools/definitions/model-comparison.js +6 -0
- package/dist/tools/definitions/model-comparison.js.map +1 -1
- package/dist/tools/definitions/operational-overview.d.ts +3 -0
- package/dist/tools/definitions/operational-overview.js +23 -0
- package/dist/tools/definitions/operational-overview.js.map +1 -0
- package/dist/tools/definitions/operator-workflow.d.ts +20 -0
- package/dist/tools/definitions/operator-workflow.js +114 -0
- package/dist/tools/definitions/operator-workflow.js.map +1 -0
- package/dist/tools/definitions/platform-setup.d.ts +26 -3
- package/dist/tools/definitions/platform-setup.js +209 -7
- package/dist/tools/definitions/platform-setup.js.map +1 -1
- package/dist/tools/definitions/scheduled-tasks.js +2 -0
- package/dist/tools/definitions/scheduled-tasks.js.map +1 -1
- package/dist/tools/definitions/session.js +103 -5
- package/dist/tools/definitions/session.js.map +1 -1
- package/dist/tools/definitions/shared.d.ts +154 -11
- package/dist/tools/definitions/shared.js +67 -9
- package/dist/tools/definitions/shared.js.map +1 -1
- package/dist/tools/definitions/task-state.d.ts +76 -0
- package/dist/tools/definitions/task-state.js +301 -0
- package/dist/tools/definitions/task-state.js.map +1 -0
- package/dist/tools/definitions/trigger-contact-claims.js +2 -0
- package/dist/tools/definitions/trigger-contact-claims.js.map +1 -1
- package/dist/tools/definitions.d.ts +273 -31
- package/dist/tools/definitions.js +12 -0
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/description-localization.d.ts +2 -0
- package/dist/tools/description-localization.js +46 -0
- package/dist/tools/description-localization.js.map +1 -0
- package/dist/tools/incomplete-list.d.ts +23 -0
- package/dist/tools/incomplete-list.js +39 -0
- package/dist/tools/incomplete-list.js.map +1 -0
- package/dist/tools/inventory.d.ts +10 -0
- package/dist/tools/inventory.js +49 -0
- package/dist/tools/inventory.js.map +1 -0
- package/dist/tools/registry-mapping-cases-core.js +197 -2
- package/dist/tools/registry-mapping-cases-core.js.map +1 -1
- package/dist/tools/registry-mapping-cases-platform.js +69 -0
- package/dist/tools/registry-mapping-cases-platform.js.map +1 -1
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.js +60 -8
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/result-envelope.d.ts +46 -0
- package/dist/tools/result-envelope.js +184 -0
- package/dist/tools/result-envelope.js.map +1 -0
- package/dist/tools/result.d.ts +41 -3
- package/dist/tools/result.js +229 -27
- package/dist/tools/result.js.map +1 -1
- package/dist/tools/tool-title.d.ts +2 -0
- package/dist/tools/tool-title.js +12 -0
- package/dist/tools/tool-title.js.map +1 -0
- package/dist/tools/toolsets.d.ts +37 -0
- package/dist/tools/toolsets.js +64 -0
- package/dist/tools/toolsets.js.map +1 -0
- package/dist/tools/verify-with.d.ts +5 -0
- package/dist/tools/verify-with.js +36 -0
- package/dist/tools/verify-with.js.map +1 -0
- package/dist/types/api-contract.gen.d.ts +1433 -74
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.js +64 -8
- package/dist/utils/logger.js.map +1 -1
- package/docs/agent-usage-guide.full.ru.md +20 -15
- package/docs/agent-usage-guide.ru.md +29 -16
- package/docs/async-operation-lifecycle.md +46 -0
- package/docs/connect.ru.md +120 -0
- package/docs/evals/model-behavior-scorecard.md +80 -0
- package/docs/failure-semantics.md +56 -0
- package/docs/help-navigation.md +48 -0
- package/docs/host-compatibility-matrix.md +153 -0
- package/docs/host-setup.md +22 -6
- package/docs/operation-coverage.md +114 -0
- package/docs/pii-policy.md +46 -0
- package/docs/response-size-budget.md +150 -0
- package/docs/task-state.md +58 -0
- package/docs/tool-effects.md +46 -0
- package/docs/tool-surface.md +91 -0
- package/package.json +6 -2
- package/scripts/model-eval-server.js +213 -0
- package/scripts/probe-mcp-protocol.js +134 -0
- package/scripts/run-model-eval.js +447 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Что мост отвечает на сбой
|
|
2
|
+
|
|
3
|
+
## Правило
|
|
4
|
+
|
|
5
|
+
**Совет «попробуйте позже» допустим только там, где повтор доказуемо безопасен.**
|
|
6
|
+
|
|
7
|
+
Отсутствие ответа НЕ доказывает, что операция не состоялась. Запрос мог дойти до сервера,
|
|
8
|
+
выполниться целиком и потерять только обратный путь; отказ 5xx мог произойти уже после записи
|
|
9
|
+
в базу или постановки задачи в очередь. Для читающего вызова это не важно — повторить его
|
|
10
|
+
ничего не стоит. Для меняющего важно всё:
|
|
11
|
+
|
|
12
|
+
| Операция | Что делает повтор после неизвестного исхода |
|
|
13
|
+
|---|---|
|
|
14
|
+
| создание канала, агента, переменной | второй экземпляр, который никто не заказывал |
|
|
15
|
+
| перевыпуск ключа партнёра | отзывает ключ, который партнёр только что получил |
|
|
16
|
+
| импорт и запуск волны | отправляет сообщения людям второй раз |
|
|
17
|
+
| раскатка правки промптов | применяет правки к уже пропатченному тексту |
|
|
18
|
+
| всё, что тратит модель или квоту | платит второй раз |
|
|
19
|
+
|
|
20
|
+
## Как это выражено
|
|
21
|
+
|
|
22
|
+
Признак неоднозначности выводится из уже объявленного у инструмента: `sideEffect !== 'none'`
|
|
23
|
+
и не объявлена идемпотентность. Тогда на **5xx** и на **обрыв связи** уходит ответ вида
|
|
24
|
+
`OUTCOME_UNKNOWN` — без совета повторить и с указанием, чем свериться.
|
|
25
|
+
|
|
26
|
+
⚠️ **Идемпотентность объявляется явно, умолчание — худшее.** Правило «все `*_upsert`
|
|
27
|
+
идемпотентны» неверно: без идентификатора они уходят в создание.
|
|
28
|
+
|
|
29
|
+
Что НЕ считается неоднозначным: 4xx (сервер отверг запрос, не выполнив его), 429 (вызов
|
|
30
|
+
отклонён лимитом), 401/403 (не пропущен вовсе). Там прежние тексты сохранены.
|
|
31
|
+
|
|
32
|
+
## Чем свериться — выводится, а не перечисляется
|
|
33
|
+
|
|
34
|
+
Имя инструмента проверки берётся из имени операции: `*_init` / `*_start` / `*_import` /
|
|
35
|
+
`*_execute` / `*_request` → парный `*_status`, если такой существует. Рукописная таблица
|
|
36
|
+
«операция → проверка» отстала бы от первого же нового асинхронного инструмента, и он остался
|
|
37
|
+
бы без указания ровно там, где цена ошибки максимальна.
|
|
38
|
+
|
|
39
|
+
Пару, которую вывести нельзя (`besales_icp_import_dialogues` → `besales_icp_import_status`,
|
|
40
|
+
`besales_model_comparison_run_start` → `besales_model_comparison_get`, …), объявляет поле
|
|
41
|
+
`verifyWithToolName` у определения; объявленное перекрывает выведенное. Тесты держат два
|
|
42
|
+
инварианта: объявленное имя существует, и инструмент проверки сам ничего не меняет — иначе
|
|
43
|
+
совет «сверьтесь» вносил бы новую побочку поверх неизвестного исхода.
|
|
44
|
+
|
|
45
|
+
Если проверки нет ни выведенной, ни объявленной, текст всё равно не советует повтор: он просит
|
|
46
|
+
свериться состоянием на стороне Besales.
|
|
47
|
+
|
|
48
|
+
## Безопасная структурированная диагностика
|
|
49
|
+
|
|
50
|
+
HTTP-ошибка приходит одновременно как читаемый текст и `structuredContent.error`:
|
|
51
|
+
`code`, HTTP `status`, безопасные `details` и исполнимый `continuation`. Из тела API наружу
|
|
52
|
+
попадает только allowlist: идентификаторы operation/run/agent/draft/workspace, required/missing
|
|
53
|
+
scopes, expiresAt, remediation и `serviceAccountEmail`. Остальные поля, включая секреты и PII,
|
|
54
|
+
отбрасываются. Для `google_sheets_not_shared` текст прямо называет сервисный аккаунт, которому
|
|
55
|
+
нужно открыть доступ. Для 429 сохраняется `Retry-After` в секундах и называется точный ранний
|
|
56
|
+
момент безопасного повтора.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Навигация по справке Besales MCP
|
|
2
|
+
|
|
3
|
+
## Зачем нужен tool-мост
|
|
4
|
+
|
|
5
|
+
Некоторые MCP-хосты показывают модели tools, но не передают список resources или не предлагают
|
|
6
|
+
прочитать resource автоматически. Поэтому справка доступна двумя равноправными путями:
|
|
7
|
+
|
|
8
|
+
- MCP resource по URI `besales://...`;
|
|
9
|
+
- `besales_help_search` и `besales_help_get`, которые читают те же файлы пакета.
|
|
10
|
+
|
|
11
|
+
В ответах tool-моста есть `version`, `source` и `complete`. Это позволяет отличить актуальную
|
|
12
|
+
справку пакета от пересказа модели и понять, был ли получен весь документ или один раздел.
|
|
13
|
+
|
|
14
|
+
## Поиск
|
|
15
|
+
|
|
16
|
+
`besales_help_search({query})` принимает обычную русскую или английскую формулировку. Встроенные
|
|
17
|
+
синонимы связывают лексику пользователя и продукта: «дожим» с follow-up, «волна» с broadcast,
|
|
18
|
+
«бот молчит» с silence/handoff. Ответ разделяет найденные операции (`operations`) и документы
|
|
19
|
+
(`results`). Для операции также возвращаются `score` и `matchedBy`: совпадение по имени или по
|
|
20
|
+
пользовательскому намерению.
|
|
21
|
+
|
|
22
|
+
Все активные инструменты получают короткую русскую формулировку намерения в описании, которое
|
|
23
|
+
публикуется через `tools/list`. Английская часть сохраняется для существующих клиентов и поиска.
|
|
24
|
+
Так модель может найти создание агента, изменение маршрутизации, запуск GetCourse-волны или
|
|
25
|
+
финализацию промпта по обычному русскому запросу без знания технического имени инструмента.
|
|
26
|
+
|
|
27
|
+
Поиск не вызывает API и не читает данные workspace. Если результатов нет, нужно уточнить объект
|
|
28
|
+
или цель, а не угадывать имя инструмента.
|
|
29
|
+
|
|
30
|
+
## Точечное и полное чтение
|
|
31
|
+
|
|
32
|
+
`besales_help_get({uri})` возвращает индекс заголовков. Затем можно запросить один раздел через
|
|
33
|
+
`section` или весь документ через `full=true`. Неоднозначный фрагмент заголовка возвращает список
|
|
34
|
+
кандидатов; отсутствующий раздел возвращает `found=false`.
|
|
35
|
+
|
|
36
|
+
Полная версия остаётся доступной, но для небольшой операции лучше читать один релевантный раздел.
|
|
37
|
+
Содержимое resource и tool-ответа берётся из одного файла, поэтому две копии документа не
|
|
38
|
+
расходятся.
|
|
39
|
+
|
|
40
|
+
## Проверка
|
|
41
|
+
|
|
42
|
+
- `src/tools/definitions/help.spec.ts` проверяет паритет русских и английских намерений, индекс,
|
|
43
|
+
раздел и полное чтение.
|
|
44
|
+
- `src/tools/description-localization.spec.ts` не допускает активный инструмент без русской
|
|
45
|
+
формулировки в опубликованном описании.
|
|
46
|
+
- `src/resources/registry.spec.ts` проверяет ссылки на реальные инструменты во всех resources и
|
|
47
|
+
коротких server instructions.
|
|
48
|
+
- `src/server.spec.ts` проверяет публикацию server instructions через MCP initialize.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Матрица хостов, версий и установки
|
|
2
|
+
|
|
3
|
+
Снимок: 2026-09-11. Это проверяемая граница текущего hardening, а не обещание для любого
|
|
4
|
+
MCP-клиента.
|
|
5
|
+
|
|
6
|
+
## Линии продукта
|
|
7
|
+
|
|
8
|
+
| Линия | MCP | API | Источник API-контракта | Tool schema | Transport |
|
|
9
|
+
|---|---|---|---|---|---|
|
|
10
|
+
| main | `be-sales/mcp`, `codex/mcp-hardening-main-20260910`, `0.46.0` | `be-sales/back-main`, `codex/mcp-hardening-api-main-20260910`, `1.0.1` | loose `animaly/docs/specs/v2/contracts/openapi-besales-api.yaml` → `src/types/api-contract.gen.ts` | tracked `besales-mcp/src/schemas/mcp-tools.json`; build копирует его в dist | local stdio |
|
|
11
|
+
| v2 beta | тот же GitHub repo, отдельная ветка `codex/mcp-hardening-v2-20260910`, `1.0.0-beta.1` | `be-sales/besales-api`, `codex/mcp-hardening-api-v2-20260910`, `0.0.1` | `besales-api/contracts/openapi-besales-api.yaml` → generated types | локальный `src/schemas/mcp-tools.json` + route export | local stdio |
|
|
12
|
+
|
|
13
|
+
Main и v2 не взаимозаменяемы по совпадению имени файла. Изменение переносится только после
|
|
14
|
+
сверки route, DTO, scope, ответа и теста своей пары.
|
|
15
|
+
|
|
16
|
+
Общий loose `docs/specs/v2/contracts/mcp-tools.json` является целью v2 registry publish и больше
|
|
17
|
+
не копируется внутрь main. Это устраняет перезапись канона одной линии контрактом другой; main
|
|
18
|
+
проверяет собственный tracked schema, v2 публикует свой schema в явно выбранные targets.
|
|
19
|
+
|
|
20
|
+
## Поддерживаемые хосты этой итерации
|
|
21
|
+
|
|
22
|
+
| Хост | Проверенная версия | Фактическое поведение | Статус |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| MCP SDK / Inspector | SDK из lockfile, raw stdio | полный initialize; main: 253 tools / 38 resources / 5 prompts, v2: 213 / 38 / 5; schema validation до HTTP | блокирующий protocol gate |
|
|
25
|
+
| Codex CLI / App | `codex-cli 0.153.4` | один сервер `besales`; tools могут грузиться отложенно; resources модели не гарантированы, поэтому есть `besales_help_*` | поддержан |
|
|
26
|
+
| Claude Code | `2.1.220` | stdio подключён; видит tools/resources/prompts; server instructions режет **4123 → 2048 символов** | поддержан с полезным префиксом и help-tools |
|
|
27
|
+
| Claude Desktop | app `1.49585.0` | local stdio; два намеренно разных подключения `besales-tg` и `besales-ksamata`, каждое прибито к своему workspace | поддержан; ручной UI smoke после установки |
|
|
28
|
+
|
|
29
|
+
Новый неизвестный хост не становится блокирующим автоматически. Для него сначала повторяются
|
|
30
|
+
raw initialize/list/read/call и модельная оценка.
|
|
31
|
+
|
|
32
|
+
## Протокольное доказательство main
|
|
33
|
+
|
|
34
|
+
Артефакт: `docs/evidence/2026-09-11-main-wire-protocol.json`.
|
|
35
|
+
|
|
36
|
+
- initialize: `@besales/mcp 0.46.0`, instructions 4123 символа / 6532 UTF-8 байта;
|
|
37
|
+
- capabilities: tools, resources, prompts;
|
|
38
|
+
- tools/list: 253 уникальных имени, 418380 байт;
|
|
39
|
+
- resources/list: 38; каждый URI реально прочитан и снабжён SHA-256;
|
|
40
|
+
- prompts/list: 5;
|
|
41
|
+
- пустой `besales_agent_create` отклонён MCP кодом `-32602` до HTTP: отсутствуют
|
|
42
|
+
`platform_id`, `name`, а `model_lane` не входит в `CHEAP|STANDARD|DEEP`;
|
|
43
|
+
- wire schema сохраняет required, UUID format, enums, вложенные объекты и
|
|
44
|
+
`const: true` + `type: boolean`.
|
|
45
|
+
|
|
46
|
+
Скрипт повторения: `yarn build && yarn host:probe bin/besales-mcp.js <output.json>`.
|
|
47
|
+
|
|
48
|
+
## Протокольное доказательство v2 beta
|
|
49
|
+
|
|
50
|
+
Артефакт в v2 checkout: `docs/evidence/2026-09-11-v2-wire-protocol.json`.
|
|
51
|
+
|
|
52
|
+
- initialize: `@besales/mcp 1.0.0-beta.1`, instructions 4122 символа / 6538 UTF-8 байт;
|
|
53
|
+
- tools/list: 213 уникальных имён, 322105 байт; resources/list: 38; prompts/list: 5;
|
|
54
|
+
- все resources прочитаны, representative schemas сохранены, пустой `besales_agent_create`
|
|
55
|
+
отклонён кодом `-32602` до API теми же обязательными полями;
|
|
56
|
+
- снимок собран из v2 MCP `912a70a`; API-зависимые main tools в него не копировались.
|
|
57
|
+
|
|
58
|
+
## Что видит модель
|
|
59
|
+
|
|
60
|
+
У установленной до hardening main-версии Codex App было 215 активных tools. Старый сервер
|
|
61
|
+
добавлял полный текст инструкций в описание каждого tool: 22385 символов у одного описания,
|
|
62
|
+
4747836 символов суммарно. Это подтверждённый дефект версии, а не лимит MCP.
|
|
63
|
+
|
|
64
|
+
Новая версия передаёт инструкции один раз через initialize. В первых 2048 символах, которые
|
|
65
|
+
оставляет проверенный Claude Code, находятся:
|
|
66
|
+
|
|
67
|
+
1. `besales_workspace_current` и выбор компании по названию;
|
|
68
|
+
2. overview → точечный platform context;
|
|
69
|
+
3. `besales_help_search` → `besales_help_get`;
|
|
70
|
+
4. запрет одинакового повторного read и конкретный следующий шаг;
|
|
71
|
+
5. запрет секретов в чате и начало правила подтверждений.
|
|
72
|
+
|
|
73
|
+
Глубокие правила после этой границы остаются доступны через тот же registry ресурсов и
|
|
74
|
+
`besales_help_search` / `besales_help_get`; модель не зависит от UI resources конкретного хоста.
|
|
75
|
+
|
|
76
|
+
Повторная проверка model-eval 2026-09-11 отозвала прежний сравнительный PASS:
|
|
77
|
+
все 15 baseline-прогонов были заблокированы политикой approvals хоста до выполнения fixture.
|
|
78
|
+
Сопоставимого baseline нет; улучшение времени, токенов или успешности не доказано.
|
|
79
|
+
Current отдельно дал 14/15 успешных маршрутов и чтение справки в 12/15 на пяти fixture-сценариях
|
|
80
|
+
(`gpt-5.6-luna`, reasoning `low`, три повтора). Это не проверка production API или всех workflows.
|
|
81
|
+
Scorer пересчитывает метрики из исходных calls/events и учитывает только успешные ответы;
|
|
82
|
+
approval-blocked read не считается мутацией. UPD-048 открыт до сопоставимой серии.
|
|
83
|
+
Raw JSONL сохранён в `docs/evidence/model-eval-2026-09-11/`.
|
|
84
|
+
|
|
85
|
+
Claude Code debug подтвердил stdio connection и capabilities tools/resources/prompts, а также
|
|
86
|
+
точный лимит instructions 2048. Модельный ответ не получен: аккаунт вернул 429 weekly limit до
|
|
87
|
+
первого token. Это ограничение хоста/аккаунта, не ошибка MCP; raw protocol и command discovery
|
|
88
|
+
остаются валидны. В Claude Code prompts появляются как
|
|
89
|
+
`/mcp__besales__besales_setup_agent` и аналогичные команды. Обычный текстовый запрос остаётся
|
|
90
|
+
основным и полностью эквивалентным входом.
|
|
91
|
+
|
|
92
|
+
## Подключения и дубли
|
|
93
|
+
|
|
94
|
+
Наблюдавшиеся «3 сервера / 642 записи» не являются тремя случайными копиями в одном каталоге:
|
|
95
|
+
|
|
96
|
+
- Codex имеет один `besales`;
|
|
97
|
+
- Claude Code имеет один `besales`;
|
|
98
|
+
- Claude Desktop имеет два purpose-specific сервера для разных workspace.
|
|
99
|
+
|
|
100
|
+
Удалять их автоматически нельзя: это уничтожило бы выбор компании. Случайным дублем считается
|
|
101
|
+
только повтор одного executable, API URL и workspace pin внутри одного host. Миграция:
|
|
102
|
+
|
|
103
|
+
1. оставить по одному имени на уникальную тройку executable/API/workspace;
|
|
104
|
+
2. обновить executable на проверенный пакет;
|
|
105
|
+
3. перезапустить host и вызвать `besales_workspace_current`;
|
|
106
|
+
4. удалить старую запись вручную лишь после успешного smoke новой.
|
|
107
|
+
|
|
108
|
+
Профиль `BESALES_MCP_TOOLSETS` уменьшает поверхность одного сервера и одинаково ограничивает
|
|
109
|
+
list и call; help возвращает скрытые совпадения отдельно, не выдавая их за вызываемые. Профиль не
|
|
110
|
+
заменяет workspace pin и не объединяет разные компании.
|
|
111
|
+
|
|
112
|
+
## Scopes
|
|
113
|
+
|
|
114
|
+
| Линия | Запрашивает MCP | Поддерживает API | Фактически выдаёт |
|
|
115
|
+
|---|---|---|---|
|
|
116
|
+
| main | `mcp:* mcp:platform-setup mcp:funnel-test read:campaigns launch:campaigns read:contacts write:operators` | тот же ratchet-набор | consent-набор с учётом прав пользователя; exchange возвращает `scopes` и `dropped_scopes` |
|
|
117
|
+
| v2 beta | `mcp:* mcp:platform-setup read:contacts` | та же тройка; `read:platform-setup` входит в composite read | consent выдаёт только поддержанный v2-набор |
|
|
118
|
+
|
|
119
|
+
`besales_workspace_current.effective_scopes` берётся из конкретного выбранного credential.
|
|
120
|
+
Union других ключей workspace не используется. 403 сохраняет названный API недостающий scope;
|
|
121
|
+
reconnect добавляет права и не должен сужать прежние. Main и beta не копируют scope-set друг
|
|
122
|
+
друга.
|
|
123
|
+
|
|
124
|
+
## Установка, обновление, отзыв
|
|
125
|
+
|
|
126
|
+
Поддержанный пользовательский путь сейчас — local stdio и browser OAuth:
|
|
127
|
+
|
|
128
|
+
1. host запускает `npx -y @besales/mcp@<проверенная-версия>` либо pinned локальный executable;
|
|
129
|
+
2. `besales-mcp connect` открывает browser consent; секрет в чат не копируется;
|
|
130
|
+
3. `besales-mcp status` и `besales_workspace_current` показывают подключение;
|
|
131
|
+
4. обновление: поменять версию/executable, перезапустить host, повторить raw smoke;
|
|
132
|
+
5. reconnect нужен для протухшего credential или новых scopes, а не для неоднозначного выбора;
|
|
133
|
+
6. отзыв выполняется в настройках подключения, затем проверяется 401 именно этого workspace.
|
|
134
|
+
|
|
135
|
+
Keytar остаётся частью local distribution и хранит ключи в системном credential store. Remote
|
|
136
|
+
HTTP/OAuth не вводится в этом инкременте: для него нет ратифицированной модели размещения,
|
|
137
|
+
tenant routing и миграции локальных ключей. Возвращаться к нему следует, когда появится
|
|
138
|
+
server-side host и отдельный threat model. Перенос аккаунта выполняется новым browser connect;
|
|
139
|
+
credential store не копируется между машинами.
|
|
140
|
+
|
|
141
|
+
## Выпуск
|
|
142
|
+
|
|
143
|
+
- Аддитивные tools/resources/prompts совместимы в minor main и beta build.
|
|
144
|
+
- Новые обязательные поля, default limits и форма результата требуют отдельного rollout.
|
|
145
|
+
- `BESALES_MCP_RESULT_ENVELOPE=on` включает одинаковые text/structuredContent и outputSchema;
|
|
146
|
+
default остаётся off один совместимый релиз.
|
|
147
|
+
- main и `1.0.0-beta.1` не публикуются на один dist-tag.
|
|
148
|
+
- Публикация и деплой в этот документ не входят. После публикации обязателен smoke реально
|
|
149
|
+
установленного пакета после полного restart host; локальный worktree smoke его не заменяет.
|
|
150
|
+
|
|
151
|
+
Официальное отображение prompts в Claude Code: MCP prompt становится командой
|
|
152
|
+
`/mcp__<server>__<prompt>`; resources доступны через `@server:uri`. Источник:
|
|
153
|
+
https://code.claude.com/docs/en/mcp
|
package/docs/host-setup.md
CHANGED
|
@@ -80,9 +80,18 @@ node bin/besales-mcp.js connect # workspace B (re-login in the browser
|
|
|
80
80
|
node bin/besales-mcp.js connections # list all connections, marks the active one
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
The connection index includes the workspace name and a masked account label.
|
|
84
|
+
`besales_workspace_current` refreshes missing or day-old labels through the
|
|
85
|
+
lightweight `/auth/mcp-context` endpoint and reports `current`, `cached`, `stale`,
|
|
86
|
+
or `unknown` with `label_updated_at` and a safe refresh reason. This migrates
|
|
87
|
+
legacy entries without six full overview calls. Reconnecting also refreshes
|
|
88
|
+
credentials and labels, but does not choose between several unpinned workspaces.
|
|
89
|
+
|
|
83
90
|
Workspace-level tools default to the session's workspace; users should not be
|
|
84
|
-
asked to
|
|
85
|
-
|
|
91
|
+
asked to find or type `workspace_id`. Show the names returned by
|
|
92
|
+
`besales_workspace_current`, then pass the selected UUID to `besales_workspace_use`.
|
|
93
|
+
Pin a session with `BESALES_WORKSPACE_ID` in the host's `env` block, or set the
|
|
94
|
+
global default with `besales-mcp use <workspaceId>`.
|
|
86
95
|
See the package README "Multiple Workspaces" section for the full precedence.
|
|
87
96
|
|
|
88
97
|
For MCP protocol smoke without live auth, use the local mock API:
|
|
@@ -120,12 +129,17 @@ BESALES_API_BASE_URL=http://localhost:3000/api/v2 \
|
|
|
120
129
|
BESALES_API_BASE_URL=http://localhost:3000/api/v2 \
|
|
121
130
|
yarn dlx @modelcontextprotocol/inspector --cli --method resources/list \
|
|
122
131
|
node bin/besales-mcp.js
|
|
132
|
+
|
|
133
|
+
BESALES_API_BASE_URL=http://localhost:3000/api/v2 \
|
|
134
|
+
yarn dlx @modelcontextprotocol/inspector --cli --method prompts/list \
|
|
135
|
+
node bin/besales-mcp.js
|
|
123
136
|
```
|
|
124
137
|
|
|
125
138
|
Expected:
|
|
126
139
|
|
|
127
|
-
-
|
|
128
|
-
-
|
|
140
|
+
- 248 tools are listed.
|
|
141
|
+
- 38 resources are listed.
|
|
142
|
+
- 5 optional task prompts are listed.
|
|
129
143
|
- `besales://concepts/external-execution` opens.
|
|
130
144
|
- A direct tool, for example `besales_icp_create`, reaches `ai-aniomaly`.
|
|
131
145
|
- An external pair returns instructions and accepts submit.
|
|
@@ -230,6 +244,8 @@ are present, then run:
|
|
|
230
244
|
|
|
231
245
|
1. One direct tool (`besales_icp_create`).
|
|
232
246
|
2. One external pair (`*_get_instructions` then matching `*_submit`).
|
|
247
|
+
3. A natural-language help request through `besales_help_search`, followed by one section through
|
|
248
|
+
`besales_help_get`. This check is required when the host does not expose resources to the model.
|
|
233
249
|
|
|
234
250
|
For the ICP analysis pair, `besales_icp_analysis_submit` personas must include
|
|
235
251
|
`segment_id`. Use either an existing ICP segment id or the `id` of a segment in
|
|
@@ -243,7 +259,7 @@ session may need an app/session restart before new tools appear.
|
|
|
243
259
|
Codex App can defer MCP tool schemas until the model searches for them. This is
|
|
244
260
|
host behavior, not a `besales-mcp` server problem: `codex mcp list/get besales`
|
|
245
261
|
and MCP Inspector `tools/list` are still the source checks for whether the
|
|
246
|
-
server is installed and exposing all
|
|
262
|
+
server is installed and exposing all 248 tools.
|
|
247
263
|
|
|
248
264
|
User-facing prompts must stay natural. Users should ask for the business action,
|
|
249
265
|
for example:
|
|
@@ -264,7 +280,7 @@ Use this matrix for local validation before staging/prod checks.
|
|
|
264
280
|
|
|
265
281
|
| Host | Config check | Protocol check | Direct tool | External pair |
|
|
266
282
|
|---|---|---|---|---|
|
|
267
|
-
| MCP Inspector | command launches |
|
|
283
|
+
| MCP Inspector | command launches | 248 tools / 38 resources / 5 prompts | `besales_icp_create` | instructions -> submit |
|
|
268
284
|
| Claude Desktop | config JSON has `besales` | server connected | `besales_icp_create` | instructions -> submit |
|
|
269
285
|
| Claude Code | `claude mcp list` has `besales` | `/mcp` connected | `besales_icp_create` | instructions -> submit |
|
|
270
286
|
| Codex CLI | `codex mcp list` has `besales` | new session sees tools | `besales_icp_create` | instructions -> submit |
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Покрытие пользовательских операций
|
|
2
|
+
|
|
3
|
+
Снимок main: 2026-09-11. Единица — пользовательская операция, а не страница UI. Статусы:
|
|
4
|
+
**full** — есть MCP read/write и проверка; **partial** — часть пути требует UI или нет полного
|
|
5
|
+
lifecycle; **missing API** — безопасного `/api/v2` контракта нет; **intentional** — действие
|
|
6
|
+
сознательно не публикуется.
|
|
7
|
+
|
|
8
|
+
## Матрица
|
|
9
|
+
|
|
10
|
+
| Область / операция | MCP | API `/api/v2` | Scope / эффект | Проверка | Статус и решение |
|
|
11
|
+
|---|---|---|---|---|---|
|
|
12
|
+
| workspace / platform / agents | overview, context sections, agent search/get/create/update | есть | setup scopes; read/write | повторный get/context | full |
|
|
13
|
+
| prompt / ICP / sandbox | direct + 7 external pairs + lifecycle | есть | read/write/spend | lint, version, run status/findings | full; draft-bound sandbox см. отдельное решение |
|
|
14
|
+
| knowledge / workbook | CRUD, page read, classification, archive, reindex status | есть | read/write | fingerprint, get/status | full |
|
|
15
|
+
| CRM / pipelines / fields | setup, list/get/upsert, mapping, operators CRM | есть | setup scopes; read/write | health/get/list | full; CRM operator не workspace operator |
|
|
16
|
+
| data sources / 1С | setup/status/list/health/catalog/roles/vectorize | есть | setup scopes; health пишет status | status/health/catalog | partial: catalogs API без cursor |
|
|
17
|
+
| follow-up | sequences, step stats, reactions, funnel test | есть | read/write/spend | list/stats/run status | full для текущего API |
|
|
18
|
+
| outgoing waves / scheduler | preview/import/status, schedules, cohorts, analytics | есть | campaign scopes; spend | status/analytics | partial: несколько legacy lists без cursor |
|
|
19
|
+
| incoming analytics | summary/topics/speed/money/cycle/quality | есть, делегирует UI service | `read:analytics`, read | те же DTO и canonical totals | full для агрегатов; person drill-down отдельно |
|
|
20
|
+
| funnel analytics | meta/summary/cohorts | есть, делегирует UI service | `read:analytics`, read | тот же view/period/grain, что UI | full для основных агрегатов |
|
|
21
|
+
| custom reports | list/get/run | есть | `read:analytics`, read | report definition + grandTotal | full для чтения; person drill-down отдельно |
|
|
22
|
+
| AI ledger / costs | summary/tasks/breakdown | есть, делегирует `AiUsageService` | `read:analytics`, read | ledger totals + unpricedEvents | full для чтения; прайс модели не замена ledger |
|
|
23
|
+
| operational overview | цепочки, расписания, jobs, action errors, условная operator queue | есть | `read:analytics`; queue ещё `read:conversations` | due/heartbeat + drill-down | full для сводки; детальные chats/operators ниже |
|
|
24
|
+
| contacts | search/detail/diagnostics + dialogue transcript | list/detail/messages/state/history есть | contacts/conversations, read | detail/history/diagnostics | full для read-only работы |
|
|
25
|
+
| chats / operator queue | dialogue query/transcript + paginated queue | есть | `read:conversations` | status + PlatformWorkLog evidence | full для чтения и поиска |
|
|
26
|
+
| workspace operators / assignment | list/get/set | есть | read conversations / отдельный `write:operators` | CAS + повторный assignment get | full; CRM operators не смешиваются |
|
|
27
|
+
| message campaigns | waves/scheduler покрывают GetCourse/Wazzup flows | общего transport-neutral v2 adapter нет | campaign read/manage/spend | preview/status/analytics | partial; не смешивать с telephony campaigns |
|
|
28
|
+
| templates / audiences | Wazzup templates only | generic v2 API отсутствует | future campaign scopes | list/get | missing API, P2 |
|
|
29
|
+
| telephony | trigger actions и voice billing не равны управлению | trunks/numbers/calls API есть | read/write telephony | validate/get/call status | partial, P2 MCP definitions |
|
|
30
|
+
| dialogue topics | нет | v2 adapter отсутствует | future conversations read/write | list/get | missing API, P2 |
|
|
31
|
+
| satisfaction | нет | v2 adapter отсутствует | future analytics read | canonical UI query | missing API, P2 |
|
|
32
|
+
| arbitrary message send | нет | внутренние routes есть | внешний side effect | delivery receipt | intentional: не публиковать без отдельного auth/threat model |
|
|
33
|
+
| raw secrets / internal admin | нет | internal only | destructive/security | browser/admin audit | intentional |
|
|
34
|
+
| длительная задача MCP | create/list/get/update/close/delete | локальный owner, API не нужен | workspace-scoped local write | version CAS + fresh object reads | full на одной машине; межмашинного sync нет |
|
|
35
|
+
|
|
36
|
+
«9 analytics endpoints» не подтверждается контрактом как девять MCP-ready операций. После
|
|
37
|
+
проверки main содержит 12 read-only маршрутов incoming/funnel/AI-ledger, три маршрута custom
|
|
38
|
+
reports и отдельный набор broadcast analytics. Они имеют разные зерно, права и семантику и не
|
|
39
|
+
объединяются одним счётчиком.
|
|
40
|
+
|
|
41
|
+
### Зависимости переноса аналитики в ветку v2
|
|
42
|
+
|
|
43
|
+
Ветка v2 проверена отдельно 2026-09-11. В ней отсутствуют доменные сервисы и HTTP-контракты,
|
|
44
|
+
которым делегируют main-адаптеры: `InboundAnalyticsService`, `FunnelAnalyticsService`,
|
|
45
|
+
`AiUsageService` и `CustomReportsService`. Поэтому main MCP definitions не копируются в v2 до
|
|
46
|
+
появления источника данных: оболочка без backend вернула бы пользователю неработающие tools.
|
|
47
|
+
|
|
48
|
+
| Операция main | Что требуется в v2 до переноса | Критерий готовности |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| incoming analytics | canonical summary/topics/speed/money/cycle/quality service + `/api/v2` adapter | одинаковые period/timezone filters и totals с UI fixture |
|
|
51
|
+
| funnel analytics | canonical meta/summary/cohorts service + `/api/v2` adapter | сохранены `view`, `grain`, cohort/period/entry и пустые интервалы |
|
|
52
|
+
| AI ledger | immutable usage ledger query + `/api/v2` adapter | `unpricedEvents` и unknown usage не превращаются в ноль |
|
|
53
|
+
| custom reports | definition list/get/run domain + `/api/v2` adapter | run использует сохранённую схему отчёта и возвращает canonical `grandTotal` |
|
|
54
|
+
|
|
55
|
+
Для каждого блока v2 дополнительно нужны `read:analytics` в auth/OpenAPI/runtime constants,
|
|
56
|
+
route-map generation, scope parity tests и protocol snapshot. До выполнения всех условий статус
|
|
57
|
+
v2 для этих операций — `missing API`, а не частичное покрытие.
|
|
58
|
+
|
|
59
|
+
## Пагинация и полнота
|
|
60
|
+
|
|
61
|
+
| Класс list/read | Состояние | Правило клиента |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| ICP, sandbox runs, agents, variables, dialogues, audits | cursor | передавать query; идти до пустого cursor; page не равна парку |
|
|
64
|
+
| knowledge docs/QA/websites/tables | page + limit | сохранять page/total/hasMore API; не обрезать конвертом |
|
|
65
|
+
| files/tracked clicks | offset + limit | завершать по total/returned count |
|
|
66
|
+
| wave contacts | cursor/limit | contact page не заменяет весь run |
|
|
67
|
+
| CRM pipelines/stages | bounded provider/domain list, API cursor нет | не усекать; при превышении бюджета fail-closed |
|
|
68
|
+
| follow-up step stats/reactions | агрегат по шагам/типам, API cursor нет | не объявлять неизвестный total точным |
|
|
69
|
+
| datasource catalogs, Wazzup templates, feedback sheets | API cursor нет | технический gap; result не считать полным при `_mcpTruncated` |
|
|
70
|
+
| cohorts, schedules, mailing variants | API cursor нет | технический gap; сужать фильтрами, где они есть |
|
|
71
|
+
|
|
72
|
+
`assertCompleteList` запрещает использовать legacy unpaged ответ как полный, когда API вернул
|
|
73
|
+
cursor/hasMore, а caller не запросил страницу. GET-параметры строятся через `URLSearchParams` в
|
|
74
|
+
path; `ApiToolRequest` не имеет отдельного query и молча потерял бы параметры.
|
|
75
|
+
|
|
76
|
+
## Замещающие записи
|
|
77
|
+
|
|
78
|
+
Четыре snapshot-класса защищены `neverTruncate`: trigger actions/platform context, agent variable
|
|
79
|
+
overrides, follow-up config и CRM field mapping. Agent/context имеют sections и detail tools.
|
|
80
|
+
Если полный снимок недоступен, MCP возвращает исполнимый отказ и не выполняет replace. Проверки
|
|
81
|
+
версии/`expected_content` сохраняются; page/sample/stale fingerprint не принимаются за полный
|
|
82
|
+
набор.
|
|
83
|
+
|
|
84
|
+
## Принятые продуктовые решения
|
|
85
|
+
|
|
86
|
+
- Incoming/funnel analytics и AI ledger имеют отдельные API contracts и MCP tools. Broadcast
|
|
87
|
+
totals не используются как заменитель; unknown/unpriced остаются отдельными.
|
|
88
|
+
- Workspace operator queue строится по `PlatformWorkLog`, а не по текущему snapshot status.
|
|
89
|
+
- Generic templates/audiences, topics и satisfaction отложены до появления scoped v2 adapter.
|
|
90
|
+
- Telephony публикуется отдельным профилем после проверки recording/transcript PII и spend;
|
|
91
|
+
существующие телефонные trigger actions не считаются покрытием.
|
|
92
|
+
- Composite prompt edit не добавляется: одиночный `prompt_batch_start` уже даёт durable run,
|
|
93
|
+
idempotency, skippedCount и resume; сначала всё равно нужен полный prompt read.
|
|
94
|
+
|
|
95
|
+
### Оставшиеся области интерфейса
|
|
96
|
+
|
|
97
|
+
Проверено по main API 2026-09-11. Решение «отложено» означает конкретную недостающую границу,
|
|
98
|
+
а не исчезновение области из MCP-плана.
|
|
99
|
+
|
|
100
|
+
| Область | Что уже есть | Чего не хватает | Решение сейчас | Условие пересмотра |
|
|
101
|
+
|---|---|---|---|---|
|
|
102
|
+
| message campaigns | GetCourse/Wazzup waves, cold welcome, scheduler, cohorts и broadcast analytics | единого v2 CRUD/lifecycle для transport-neutral кампании, шаблона и аудитории | не публиковать фиктивный generic tool; продолжать поддержанные специализированные маршруты | scoped v2 adapter с preview, idempotency, pause/cancel/status и delivery verification для каждого транспорта |
|
|
103
|
+
| templates | чтение Wazzup templates в рамках Wazzup wave | общего template list/get/CRUD API и канонической схемы переменных разных каналов | оставить Wazzup-чтение внутри его маршрута | v2 API отделяет channel template от message body, проверяет approval/media/variables и даёт безопасный preview |
|
|
104
|
+
| audiences | файловые когорты и контакты конкретных wave/import flows | самостоятельного audience list/get/definition API с доказуемой полнотой нет | не выдавать импортный файл за сохранённую аудиторию | cursor API, источник/версия выборки, expected count и повторная проверка перед spend |
|
|
105
|
+
| telephony | v2 API для trunks/numbers/calls/call lists/voice agents/telephony campaigns; trigger-actions могут начать звонок | отдельной MCP-поверхности и проверенного профиля для recording/transcript PII, spend и feature flags нет | отложить как самостоятельный профиль; телефонные trigger-actions не считать полным покрытием | threat model, scopes `read:telephony`/`write:telephony`, redaction/retention, spend confirmation и lifecycle eval готовы вместе |
|
|
106
|
+
| dialogue topics | внутренний v1 CRUD, channel assignment и async backfill | scoped `/api/v2` adapter, MCP read/write и status/cancel contract отсутствуют | отложить, не вести модель к внутреннему URL | v2 read/write scopes, cursor list, channel ownership и retained backfill lifecycle |
|
|
107
|
+
| satisfaction | внутренние v1 summary/list и capture/dispatch domain | scoped `/api/v2` analytics adapter и MCP read contract отсутствуют | отложить до read-only adapter; автоматический dispatch наружу не публиковать | period/timezone filters, response-mode/status semantics и unknown totals совпадают с UI fixtures |
|
|
108
|
+
|
|
109
|
+
## Проверка параметров вариантов аналитики
|
|
110
|
+
|
|
111
|
+
`besales_funnel_analytics_get`: meta принимает только platform, cohorts не принимает view
|
|
112
|
+
(всегда cohort), summary поддерживает view. `besales_ai_costs_get`: group_by/page/limit
|
|
113
|
+
доступны только для breakdown. Неприменимые параметры отвергаются до HTTP; фильтр не
|
|
114
|
+
отбрасывается молча. Проверка: `src/tools/definitions/analytics.spec.ts`.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Политика PII в Besales MCP
|
|
2
|
+
|
|
3
|
+
Дата инвентаризации: 2026-09-11. Секреты и PII — разные контуры: browser handoff не отдаёт
|
|
4
|
+
credentials модели, но разрешённые рабочие данные могут оказаться в транскрипте хоста.
|
|
5
|
+
|
|
6
|
+
## Инвентарь
|
|
7
|
+
|
|
8
|
+
| Поверхность | Возможные данные | Зачем нужны | Политика |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| dialogue query/transcript | имя, username/телефон, сообщения, CRM-ссылки | аудит, диагностика, ICP | list по умолчанию краткий; полный transcript только явным get и под `read:conversations` |
|
|
11
|
+
| ICP dialogue samples | реплики, outcome, признаки контакта | анализ сегментов и скрипта | import с anonymize по умолчанию; raw источник не копировать в task state |
|
|
12
|
+
| wave contacts / run contacts | contact ID, messenger, статус доставки, причина отказа | dry-run, восстановление рассылки | scope кампаний; страницы; не эхоить весь вход после записи |
|
|
13
|
+
| findings/evidence | выдержки сообщений, оценки, scenario evidence | объяснить качество | возвращать минимальный фрагмент, нужный для вывода; полный источник получать точечно |
|
|
14
|
+
| link clicks | имя контакта, contact/message IDs, время | атрибуция | описание инструмента явно предупреждает о PII; отдельный scope conversations |
|
|
15
|
+
| workspace labels | название компании, email владельца | выбор подключения | email только маскированный; label cache не хранит raw email |
|
|
16
|
+
| API keys/webhook secrets | credentials | подключение канала | только одноразовый browser reveal; рекурсивно удаляются из MCP result/log |
|
|
17
|
+
| structured errors | operation/object ID, service account email, remediation | продолжение после сбоя | whitelist; неизвестные поля и payload бэкенда наружу не проходят |
|
|
18
|
+
|
|
19
|
+
## Правила
|
|
20
|
+
|
|
21
|
+
1. Tenant/workspace/object ownership проверяет API. Локальный MCP не расширяет scope и не
|
|
22
|
+
объединяет права нескольких ключей.
|
|
23
|
+
2. Поиск и list возвращают идентичность и краткое состояние. Текст диалога, полный prompt,
|
|
24
|
+
evidence и контакты читаются отдельным явным вызовом.
|
|
25
|
+
3. Для анализа без нужды в идентичности используется анонимизация/псевдонимизация. Когда задача
|
|
26
|
+
требует доставку конкретному человеку или разбор конкретного сообщения, удаление ID разрушило
|
|
27
|
+
бы разрешённую функцию; доступ ограничивается scope и минимальным ответом.
|
|
28
|
+
4. MCP не пишет raw dialogue, contact list или findings в локальный progress/task payload.
|
|
29
|
+
Допустимы только IDs созданных сущностей, агрегаты, checkpoints и согласованные ограничения.
|
|
30
|
+
5. Host transcript и telemetry находятся под retention-политикой выбранного хоста. MCP не может
|
|
31
|
+
удалить уже переданный ему текст; поэтому перед полным чтением описания предупреждают о PII,
|
|
32
|
+
а оператор выбирает корпоративный host/retention. Экспорт в сторонний файл выполняется только
|
|
33
|
+
по явной просьбе.
|
|
34
|
+
6. Ошибка не должна удалять полезную безопасную диагностику: `serviceAccountEmail`, operation ID,
|
|
35
|
+
missing scope и remediation сохраняются. Сырые stack, токены, webhookSecret, apiKey и headers
|
|
36
|
+
удаляются.
|
|
37
|
+
7. Локальные логи маскируют email/телефоны/ключи; тесты проверяют вложенные объекты, массивы и
|
|
38
|
+
ошибки, а не только top-level поля.
|
|
39
|
+
|
|
40
|
+
## Retention и удаление
|
|
41
|
+
|
|
42
|
+
API-источники живут по профильным retention/GDPR правилам домена. MCP resources и tool schemas
|
|
43
|
+
не содержат customer PII. Keychain хранит credentials до disconnect/revoke. Кэш подключения
|
|
44
|
+
хранит только workspace ID/name, маскированный account label, scopes и timestamps. Потерянный
|
|
45
|
+
browser reveal не восстанавливается из MCP-транскрипта: пользователь выпускает новый credential
|
|
46
|
+
только осознанно, понимая отзыв прежнего.
|