Bitrix24 MCP Bridge
by DarWiM
README.md
# Bitrix24 MCP Bridge
Локальный MCP-сервер, дающий ИИ-агенту доступ к задачам, проектам и чатам Bitrix24 (чтение
и — для вызовов из каталога — выполнение действий) — в объёме прав пользователя, через
браузерное расширение, переиспользующее живую сессию. Без прав администратора и без
официального REST-вебхука.
```
ИИ-агент ─stdio─► MCP-клиент ─UDS(bridge.sock)─► daemon ─WS(127.0.0.1:39917, токен+Origin)─► Расширение (вкладка портала)
│ fetch + свежий sessid + cookie
▼
Bitrix24 (задачи / группы / чаты)
```
## Быстрый старт
```bash
# 1. Настроить портал через npx — без глобальной установки (интерактивно): токен +
# первый портал + config.json + actions.json + расширение
npx -y bitrix24-mcp-bridge setup
# 2. Зарегистрировать сервер у MCP-клиента (пример — Claude Code); каждый запуск идёт через npx
claude mcp add bitrix24-bridge -s user -- npx -y bitrix24-mcp-bridge
```
Пакет опубликован в npm registry как [`bitrix24-mcp-bridge`](https://www.npmjs.com/package/bitrix24-mcp-bridge)
(бинарь внутри называется `bitrix24-bridge`, но `npx bitrix24-mcp-bridge` резолвит его напрямую,
т.к. в `package.json` он объявлен под обоими именами). Глобальная установка (`npm i -g
bitrix24-mcp-bridge`) тоже работает и чуть быстрее стартует (без резолва npx при каждом
запуске MCP-клиента) — тогда в шаге 2 подставь `-- bitrix24-bridge` вместо `-- npx -y
bitrix24-mcp-bridge`.
Затем — два ручных шага, которые нельзя автоматизировать:
1. **Загрузить расширение.** `chrome://extensions` → включить **Developer mode** →
**Load unpacked** → выбрать `~/.bitrix24-mcp-bridge/extension/`.
2. **Открыть залогиненную вкладку** нужного портала и держать её открытой.
Готово. Агент видит инструменты `bitrix_*`; `bitrix_status` покажет, какие порталы
подключены. Bun нужен только мейнтейнерам — конечному пользователю он не требуется.
### Что делает `setup`
- **Первый запуск** (нет `config.json`): спрашивает origin портала и его alias,
генерирует общий токен (`crypto.randomBytes(32)`), пишет
`~/.bitrix24-mcp-bridge/config.json`, кладёт стартовый `actions.json`
(каталог методов) и **материализует расширение** в
`~/.bitrix24-mcp-bridge/extension/` (статичные JS-бандлы + `config.json` +
`manifest.json`, собранный под ваши порталы).
- **Повторный запуск** (config уже есть): открывает меню правки —
`[a]` добавить портал, `[r]` удалить, `[e]` изменить origin, `[d]` сменить
портал по умолчанию, `[p]` порт, `[t]` ротировать токен, `[u]` обновить
расширение из установленного пакета, `[q]` выход.
**Обновление пакета** почти полностью автоматическое:
- **Каталог** — новые записи дописываются в ваш `~/.bitrix24-mcp-bridge/actions.json` при следующем
старте (в stderr — `[catalog] added N new entries…`). Ваши записи и правки не трогаются, а запись,
которую вы удалили сами, назад не возвращается: доставленные ключи помечаются в
`catalog-state.json`, поэтому удаление считается решением, а не пробелом.
- **Файлы расширения** в `~/.bitrix24-mcp-bridge/extension/` обновляются там же автоматически, если
версия пакета изменилась (`[extension] refreshed …`), — запускать `setup` → `[u]` вручную больше не нужно.
- **Один ручной шаг остаётся:** нажать «Обновить» на расширении в `chrome://extensions` и перезагрузить
вкладку портала. Программно это сделать нельзя — Chrome перечитывает файлы unpacked-расширения только
сам. Пока этого не сделано, `bitrix_status` возвращает `warning` с версиями моста и расширения, так
что рассинхрон виден сразу, а не всплывает необъяснимой ошибкой.
**Мультипортальность** поддержана: каждый портал — отдельная запись, а в манифесте
расширения `matches`/`host_permissions` перечисляют ровно сконфигурированные origin'ы
(least-privilege на origin).
daemon читает `config.json` только при старте, поэтому `setup` сам останавливает работающий
daemon после любой правки, затрагивающей конфиг — следующий вызов агента поднимет новый daemon с
актуальным конфигом. Если daemon почему-то не остановился (не было соединения), останови его
вручную (`pkill -f -- --daemon`). Дополнительно:
- сменили набор порталов (add/remove/edit) → **перезагрузить расширение** в `chrome://extensions`;
- сменили порт или токен → **переоткрыть вкладку** портала.
## Инструменты
Помимо `bitrix_help` / `bitrix_status` / `bitrix_call`, мост регистрирует типизированные обёртки
над каталогом (разумные дефолты + схема параметров). Регистрируются только те, чьё имя есть в
`actions.json`. Точная выборка — через необязательный `params` (мержится последним, перекрывает
дефолты). Каждый принимает необязательный `portal` (alias; по умолчанию — из `config.json`).
Обёртки в основном read-only; мутирующие помечены ⚠. `bitrix_call` выполняет любой разрешённый
каталогом вызов, включая мутирующие.
| Инструмент | Назначение |
|---|---|
| `bitrix_help` | справка по API/params (= `docs/api-notes.md`) |
| `bitrix_status` | какие порталы сконфигурированы и подключены |
| `bitrix_call` | любой разрешённый вызов из каталога по имени (в т.ч. мутирующий) |
| *Задачи* | |
| `bitrix_tasks_list` / `bitrix_task_get` | список задач / карточка |
| `bitrix_task_get_v2` | карточка через v2-подсистему (JSON) |
| `bitrix_task_scrum_info` | scrum-инфо (спринт / эпик / story points) |
| `bitrix_task_files` | файлы задачи |
| `bitrix_task_views_count` | счётчик просмотров |
| `bitrix_task_subtasks` / `bitrix_task_related` | подзадачи / связанные задачи |
| *Проекты* | |
| `bitrix_projects_list` / `bitrix_project_get` | рабочие группы / проекты |
| *Чаты* | |
| `bitrix_chats_recent` | недавние чаты (REST) |
| `bitrix_recent_load` / `bitrix_recent_tail` | недавние по секции (в т.ч. `tasksTask` — чаты задач) + листание |
| `bitrix_chat_load` | открыть чат по `dialogId`/`chatId` |
| `bitrix_chat_messages` | последние сообщения чата |
| `bitrix_chat_history` | листать историю вглубь |
| `bitrix_chat_get_dialog_id` | резолв dialogId по externalId |
| `bitrix_chat_mark_read` ⚠ / `bitrix_chat_read_all` ⚠ | пометить сообщения / все чаты прочитанными |
| *Люди / поиск* | |
| `bitrix_user_get` | карточка пользователя |
| `bitrix_entity_selector` / `bitrix_entity_search` | загрузка селектора / текстовый поиск сущностей |
| `bitrix_entity_chat` | chatId чата связанного объекта (задача/группа/CRM) через `im.chat.get` |
`bitrix_help` — единственный источник конвенций params (select/filter/order/пагинация,
имена полей). Он отдаёт `docs/api-notes.md`, так что любому агенту не нужен доступ к репозиторию.
## Архитектура
Модель — **один долгоживущий daemon + N тонких клиентов**:
- **daemon** (`bitrix24-bridge --daemon`) владеет тремя ресурсами: WS-портом
`127.0.0.1:39917`, подключениями расширений (маршрутизация запросов по `Origin`
вкладки к нужному порталу) и Unix-domain-сокетом
`~/.bitrix24-mcp-bridge/bridge.sock` (права `0600`).
- **MCP-клиент** (`bitrix24-bridge`, без флагов) — то, что запускает ваш MCP-хост по
stdio. Это тонкий UDS-клиент: он **сам поднимает daemon**, если сокета ещё нет, и
подключается к нему.
Зачем так: раньше каждый MCP-клиент пытался открыть WS-порт сам, и второй экземпляр
(или health-probe хоста) падал с конфликтом порта. Теперь порт держит только daemon, а
любое число клиентов и проб сосуществуют через сокет. Daemon **сам завершается по
простою** (~5 минут без клиентов).
### Состояния (что видит агент)
- **unconfigured** — `config.json` ещё нет. Сервер всё равно стартует по stdio и
регистрирует только `bitrix_help` + `bitrix_status`, которые направляют выполнить
`bitrix24-bridge setup`. Настройка **никогда** не происходит в чате.
- **configured, вкладка закрыта** — портал сконфигурирован, но нет открытой залогиненной
вкладки → `bitrix_status` покажет портал как не подключённый; откройте вкладку.
- **live** — вкладка открыта, расширение подключено, вызовы проходят.
### Конфигурация
Runtime-домашняя папка — `~/.bitrix24-mcp-bridge/` (или `$BITRIX24_MCP_BRIDGE_HOME`).
В ней: `config.json`, `actions.json`, `bridge.sock`, `extension/`.
Разрешение настроек слоями (побеждает верхний): **env → `.env` (только для разработки)
→ `~/.bitrix24-mcp-bridge/config.json`**. Каталог методов по умолчанию берётся из
`~/.bitrix24-mcp-bridge/actions.json`; явный `BITRIX_CATALOG` (или `catalog` в config)
по-прежнему поддержан.
## Безопасность и модель доверия
Это research/PoC-инструмент в публичном репозитории. Прочтите перед использованием.
**Граница доверия — локальная машина.** daemon слушает только `127.0.0.1`, требует токен
первым сообщением и проверяет `Origin` (защита от cross-site WebSocket hijacking). Но сама
привилегия — живая аутентифицированная сессия Bitrix24 — физически в расширении, а не в
сервере. Отсюда:
- **Граница — это allowlist каталога, не режим чтения.** Мост выполняет только именованные
вызовы из `actions.json` — теперь среди них могут быть мутирующие. Общий локальный токен
(риск G7) в write-режиме означает: процесс, знающий токен и порт демона, может выполнять
эти действия в объёме прав пользователя. Внутри разрешённого действия значения `params`
не инспектируются — для мутирующего вызова это означает полный контроль агента над телом
запроса в рамках этого действия. Держи `actions.json` под контролем — это и есть
граница возможностей агента.
- **Токен — единственная защита loopback-WS.** Генерируйте длинный и случайный —
`setup` использует `crypto.randomBytes(32)`. Токен отсекает случайные подключения, но
не является границей против локального атакующего: любой локальный процесс, знающий
токен, может управлять мостом в объёме сессии.
- **Токен и WS живут только в ISOLATED-мире расширения.** Страница портала (MAIN world)
не может прочитать `config.json` расширения, потому что запись помечена
`use_dynamic_url: true` — URL ресурса непредсказуем со страницы. Подробности — в
[`extension/README.md`](extension/README.md).
- **UDS-граница — права ФС.** Сокет `bridge.sock` создаётся с режимом `0600`.
- **Origin-allowlist.** daemon отклоняет WS-подключения, чей `Origin` не входит в
сконфигурированный набор порталов.
**Вывод:** запускайте только на доверенной машине, где вы контролируете локальные процессы;
не используйте на общих или недоверенных хостах.
Полный операционный гайд и диагностика — **[docs/RUNBOOK.md](docs/RUNBOOK.md)**.
## Разработка
Bun — инструмент разработчика/мейнтейнера (конечному пользователю не нужен).
```bash
bun install
bun run src/index.ts # MCP-клиент (default); сам поднимет daemon
bun run src/index.ts --daemon # daemon вручную
bun run src/index.ts setup # интерактивная настройка
bun test # юнит-тесты (bun:test)
bun run typecheck # tsc --noEmit (сервер + extension)
bun run build:dist # бандл сервера → dist/cli.js
bun run build:ext # dev-сборка расширения → extension/dev/ (загружаемое)
bun run sync:runtime # применить репо-изменения к живому daemon (см. ниже)
```
`.env` — **только dev-оверрайды** (gitignored). Токен / origin / порт берутся из общего
`~/.bitrix24-mcp-bridge/config.json` (через `loadConfig`) — дублировать их в `.env` не нужно, иначе
dev-токен разойдётся с daemon. Осмысленно держать там лишь `BITRIX_CATALOG` (указывает
dev-сборку/daemon на репозиторный `actions.json`). В проде весь конфиг — в
`~/.bitrix24-mcp-bridge/config.json`, который пишет `setup`.
**Репо ≠ живой daemon.** Daemon, к которому ходят агенты, читает **runtime-папку**
(`~/.bitrix24-mcp-bridge/actions.json` + запущенный `dist/cli.js`), а не файлы репозитория. После
правки каталога или кода сервера выполни **`bun run sync:runtime`**: она пересоберёт бандл, скопирует
репо-`actions.json` в runtime-папку и погасит daemon (следующий вызов агента поднимет свежий). Без
этого новые инструменты/методы агенту не видны.
Дистрибуция: `bin` `bitrix24-bridge` → `dist/cli.js`; npm-хук `prepare` при установке
собирает и `dist/cli.js`, и статичные бандлы расширения (`extension/dist/`), которые
`setup` затем копирует в runtime-домашнюю папку. Публикуемые файлы перечислены в `files`
(`dist`, `extension/dist`, `docs/api-notes.md`, `actions.example.json`).
### Релизы
Версионирование и публикация автоматизированы (conventional commits →
[release-please](.github/workflows/release-please.yml)): бот ведёт release-PR с bump'ом версии и
`CHANGELOG.md`; при его мерже создаётся GitHub Release/тег и пакет публикуется в npm через **OIDC
Trusted Publisher** (с provenance, без токенов). CI ([`.github/workflows/ci.yml`](.github/workflows/ci.yml))
гоняет `typecheck` + тесты на push/PR. Ручная до-публикация застрявшего релиза — `workflow_dispatch`
на `release-please`.
## Документация
- [docs/RUNBOOK.md](docs/RUNBOOK.md) — установка, настройка, повседневная работа, диагностика
- [docs/api-notes.md](docs/api-notes.md) — карта API Bitrix24 для агента (единый источник для `bitrix_help`)
- [docs/reconnaissance.md](docs/reconnaissance.md) — capture, транспорт записи каталога, расширение `actions.json`
- [extension/README.md](extension/README.md) — устройство расширения и модель доверия
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues