bitrix24-mcp-bridge 0.1.1 → 0.2.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 CHANGED
@@ -1,8 +1,9 @@
1
1
  # Bitrix24 MCP Bridge
2
2
 
3
- Локальный MCP-сервер, дающий ИИ-агенту **read-only** доступ к задачам, проектам и чатам
4
- Bitrix24 — в объёме прав пользователя, через браузерное расширение, переиспользующее
5
- живую сессию. Без прав администратора и без официального REST-вебхука.
3
+ Локальный MCP-сервер, дающий ИИ-агенту доступ к задачам, проектам и чатам Bitrix24 (чтение
4
+ и — для вызовов из каталога — выполнение действий) — в объёме прав пользователя, через
5
+ браузерное расширение, переиспользующее живую сессию. Без прав администратора и без
6
+ официального REST-вебхука.
6
7
 
7
8
  ```
8
9
  ИИ-агент ─stdio─► MCP-клиент ─UDS(bridge.sock)─► daemon ─WS(127.0.0.1:39917, токен+Origin)─► Расширение (вкладка портала)
@@ -64,17 +65,38 @@ daemon после любой правки, затрагивающей конфи
64
65
 
65
66
  ## Инструменты
66
67
 
67
- Все — read-only, каждый принимает необязательный параметр `portal` (alias; по умолчанию —
68
- портал по умолчанию из `config.json`):
68
+ Помимо `bitrix_help` / `bitrix_status` / `bitrix_call`, мост регистрирует типизированные обёртки
69
+ над каталогом (разумные дефолты + схема параметров). Регистрируются только те, чьё имя есть в
70
+ `actions.json`. Точная выборка — через необязательный `params` (мержится последним, перекрывает
71
+ дефолты). Каждый принимает необязательный `portal` (alias; по умолчанию — из `config.json`).
72
+ Обёртки в основном read-only; мутирующие помечены ⚠. `bitrix_call` выполняет любой разрешённый
73
+ каталогом вызов, включая мутирующие.
69
74
 
70
75
  | Инструмент | Назначение |
71
76
  |---|---|
72
- | `bitrix_help` | справка по API/params (то же, что `docs/api-notes.md`) |
73
- | `bitrix_status` | какие порталы сконфигурированы и какие сейчас подключены |
74
- | `bitrix_call` | любой разрешённый вызов из каталога по имени |
75
- | `bitrix_tasks_list` / `bitrix_task_get` | задачи |
77
+ | `bitrix_help` | справка по API/params (= `docs/api-notes.md`) |
78
+ | `bitrix_status` | какие порталы сконфигурированы и подключены |
79
+ | `bitrix_call` | любой разрешённый вызов из каталога по имени (в т.ч. мутирующий) |
80
+ | *Задачи* | |
81
+ | `bitrix_tasks_list` / `bitrix_task_get` | список задач / карточка |
82
+ | `bitrix_task_get_v2` | карточка через v2-подсистему (JSON) |
83
+ | `bitrix_task_scrum_info` | scrum-инфо (спринт / эпик / story points) |
84
+ | `bitrix_task_files` | файлы задачи |
85
+ | `bitrix_task_views_count` | счётчик просмотров |
86
+ | `bitrix_task_subtasks` / `bitrix_task_related` | подзадачи / связанные задачи |
87
+ | *Проекты* | |
76
88
  | `bitrix_projects_list` / `bitrix_project_get` | рабочие группы / проекты |
77
- | `bitrix_chats_recent` / `bitrix_chat_messages` | чаты и история сообщений |
89
+ | *Чаты* | |
90
+ | `bitrix_chats_recent` | недавние чаты (REST) |
91
+ | `bitrix_recent_load` / `bitrix_recent_tail` | недавние по секции (в т.ч. `tasksTask` — чаты задач) + листание |
92
+ | `bitrix_chat_load` | открыть чат по `dialogId`/`chatId` |
93
+ | `bitrix_chat_messages` | последние сообщения чата |
94
+ | `bitrix_chat_history` | листать историю вглубь |
95
+ | `bitrix_chat_get_dialog_id` | резолв dialogId по externalId |
96
+ | `bitrix_chat_mark_read` ⚠ / `bitrix_chat_read_all` ⚠ | пометить сообщения / все чаты прочитанными |
97
+ | *Люди / поиск* | |
98
+ | `bitrix_user_get` | карточка пользователя |
99
+ | `bitrix_entity_selector` / `bitrix_entity_search` | загрузка селектора / текстовый поиск сущностей |
78
100
 
79
101
  `bitrix_help` — единственный источник конвенций params (select/filter/order/пагинация,
80
102
  имена полей). Он отдаёт `docs/api-notes.md`, так что любому агенту не нужен доступ к репозиторию.
@@ -124,9 +146,13 @@ Runtime-домашняя папка — `~/.bitrix24-mcp-bridge/` (или `$BITR
124
146
  привилегия — живая аутентифицированная сессия Bitrix24 — физически в расширении, а не в
125
147
  сервере. Отсюда:
126
148
 
127
- - **Read-only — гарантия «доброй воли», а не защита.** Ограничение на чтение — это
128
- denylist мутирующих глаголов (`…add`/`…update`/`…delete`/…) в каталоге; каталог с
129
- мутирующим вызовом просто не загрузится. Значения `params` при этом не инспектируются.
149
+ - **Граница — это allowlist каталога, не режим чтения.** Мост выполняет только именованные
150
+ вызовы из `actions.json` — теперь среди них могут быть мутирующие. Общий локальный токен
151
+ (риск G7) в write-режиме означает: процесс, знающий токен и порт демона, может выполнять
152
+ эти действия в объёме прав пользователя. Внутри разрешённого действия значения `params`
153
+ не инспектируются — для мутирующего вызова это означает полный контроль агента над телом
154
+ запроса в рамках этого действия. Держи `actions.json` под контролем — это и есть
155
+ граница возможностей агента.
130
156
  - **Токен — единственная защита loopback-WS.** Генерируйте длинный и случайный —
131
157
  `setup` использует `crypto.randomBytes(32)`. Токен отсекает случайные подключения, но
132
158
  не является границей против локального атакующего: любой локальный процесс, знающий
@@ -167,6 +193,15 @@ bun run build:ext # dev-сборка пер-пользовател
167
193
  `setup` затем копирует в runtime-домашнюю папку. Публикуемые файлы перечислены в `files`
168
194
  (`dist`, `extension/dist`, `docs/api-notes.md`, `actions.example.json`).
169
195
 
196
+ ### Релизы
197
+
198
+ Версионирование и публикация автоматизированы (conventional commits →
199
+ [release-please](.github/workflows/release-please.yml)): бот ведёт release-PR с bump'ом версии и
200
+ `CHANGELOG.md`; при его мерже создаётся GitHub Release/тег и пакет публикуется в npm через **OIDC
201
+ Trusted Publisher** (с provenance, без токенов). CI ([`.github/workflows/ci.yml`](.github/workflows/ci.yml))
202
+ гоняет `typecheck` + тесты на push/PR. Ручная до-публикация застрявшего релиза — `workflow_dispatch`
203
+ на `release-please`.
204
+
170
205
  ## Документация
171
206
 
172
207
  - [docs/RUNBOOK.md](docs/RUNBOOK.md) — установка, настройка, повседневная работа, диагностика
@@ -1,33 +1,29 @@
1
1
  {
2
- "tasks.list": {
3
- "action": "tasks.task.list",
4
- "method": "POST"
5
- },
6
- "task.get": {
7
- "action": "tasks.task.get",
8
- "method": "POST"
9
- },
10
- "projects.list": {
11
- "action": "socialnetwork.api.workgroup.list",
12
- "method": "POST"
13
- },
14
- "projects.get": {
15
- "action": "socialnetwork.api.workgroup.get",
16
- "method": "POST"
17
- },
18
- "chats.recent": {
19
- "endpoint": "/rest/im.recent.list.json",
20
- "method": "POST",
21
- "params": {
22
- "LIMIT": 50,
23
- "SKIP_OPENLINES": "Y",
24
- "GET_ORIGINAL_TEXT": "Y",
25
- "PARSE_TEXT": "Y",
26
- "WITH_COUNTERS": "N"
27
- }
28
- },
29
- "chat.messages": {
30
- "action": "im.v2.Chat.Message.list",
31
- "method": "POST"
32
- }
2
+ "tasks.list": { "action": "tasks.task.list", "method": "POST" },
3
+ "task.get": { "action": "tasks.task.get", "method": "POST" },
4
+ "task.v2.get": { "action": "tasks.v2.Task.get", "method": "POST", "bodyType": "json" },
5
+ "task.scrum.info": { "action": "tasks.v2.Scrum.getTaskInfo", "method": "POST", "bodyType": "json" },
6
+ "task.files": { "action": "tasks.v2.File.listObjects", "method": "POST", "bodyType": "json" },
7
+ "task.views.count": { "action": "tasks.v2.Task.View.User.count", "method": "POST", "bodyType": "json" },
8
+
9
+ "projects.list": { "action": "socialnetwork.api.workgroup.list", "method": "POST" },
10
+ "projects.get": { "action": "socialnetwork.api.workgroup.get", "method": "POST" },
11
+
12
+ "chats.recent": { "endpoint": "/rest/im.recent.list.json", "method": "POST", "params": { "LIMIT": 50, "SKIP_OPENLINES": "Y", "GET_ORIGINAL_TEXT": "Y", "PARSE_TEXT": "Y", "WITH_COUNTERS": "N" } },
13
+ "chat.load": { "action": "im.v2.Chat.load", "method": "POST", "params": { "messageLimit": 25 } },
14
+ "chat.messages": { "action": "im.v2.Chat.Message.list", "method": "POST" },
15
+ "chat.messages.tail": { "action": "im.v2.Chat.Message.tail", "method": "POST", "params": { "order[id]": "DESC", "limit": 25 } },
16
+ "chat.message.read": { "action": "im.v2.Chat.Message.read", "method": "POST" },
17
+
18
+ "entityselector.load": { "action": "ui.entityselector.load", "method": "POST", "bodyType": "json" },
19
+ "entityselector.search": { "action": "ui.entityselector.doSearch", "method": "POST", "bodyType": "json" },
20
+
21
+ "recent.load": { "action": "im.v2.Recent.load", "method": "POST" },
22
+ "recent.tail": { "action": "im.v2.Recent.tail", "method": "POST" },
23
+ "chat.dialogId": { "action": "im.v2.Chat.getDialogId", "method": "POST" },
24
+ "chat.read.all": { "action": "im.v2.Chat.readAll", "method": "POST" },
25
+ "im.user.get": { "endpoint": "/rest/im.user.get.json", "method": "POST" },
26
+
27
+ "task.subtasks": { "action": "tasks.v2.Task.Relation.Child.list", "method": "POST", "bodyType": "json" },
28
+ "task.related": { "action": "tasks.v2.Task.Relation.Related.list", "method": "POST", "bodyType": "json" }
33
29
  }