# Шлюз коннекторов (MCP)

Шлюз позволяет Коворку и связанным приложениям Вайбкод вызывать инструменты сервисов, подключённых к порталу. Работает по протоколу MCP Streamable HTTP без сессий.

**Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** ключ устройства Коворка или допущенного приложения

## Кто может вызывать

Коворк использует ключи устройства с назначением `cowork-desktop`. Приложению нужны явно выданный действующий `vibe:connectors` и действующее приложение с персональным ключом приложения или OAuth-ключом приложения. Владелец и портал должны совпадать с ключом. Пока функция не включена для портала, маршруты отвечают `404 ROUTE_NOT_FOUND`. При включённой функции остальные ключи получают `403 CONNECTOR_KEY_NOT_ALLOWED`.

Приложение действует от лица владельца ключа, а не зрителя страницы или пользователя из заголовков. Оно видит только общие подключения `PORTAL`, разрешённые правилом администратора и правами владельца. Скоуп не создаёт подключения и правила. Точный белый список: `GET /v1/connectors`, `POST /v1/connectors/mcp`, `GET /v1/connectors/write-tickets/{id}` и `GET /v1/me`; остальные ручки и операции хоста, включая заявки и управление подключениями, закрыты.

Допущенное приложение получает `data.connectorHost` в [`GET /v1/me`](/docs/keys-auth/me): `host = VIBE_APP`, `applicationId`, `connectionScope = PORTAL`, `mcpUrl = /v1/connectors/mcp` и `confirmationMode = web_owner`. Отсутствие блока не выдаёт доступ. Допуск и права проверяются заново при каждом запросе.

Пока функция выключена, путь отвечает `404 ROUTE_NOT_FOUND` на любой запрос — до проверки ключа, метода и тела. Если функция включена только для части порталов или сотрудников, ключ вне этого круга получает тот же `404` сразу после проверки ключа.

## Запрос

`POST /v1/connectors/mcp`

`POST /v1/connectors/mcp` принимает одно сообщение JSON-RPC 2.0 до 256 КиБ, пакет сообщений отклоняется. Методы: `initialize`, `notifications/initialized`, `ping`, `tools/list`, `tools/call`. Когда функция включена, `GET` и `DELETE` Коворка отвечают `405`, приложения — `403 CONNECTOR_KEY_NOT_ALLOWED`.

```bash
curl https://vibecode.bitrix24.tech/v1/connectors/mcp \
  -H "Authorization: Bearer YOUR_COWORK_DESKTOP_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## Инструменты, оплата и подтверждение записи

Мета-инструменты: `connectors_available`, `connectors_find_tools` и `connectors_run_tool`; отдельный инструмент имеет имя `slug__tool`. Недоступный инструмент возвращает `UNKNOWN_TOOL`. Для результата принятой операции BRIDGE используйте `connectors_get_result`.

Успешный платный вызов списывает баланс текущего портала; владелец ключа указан в проводке, приложение и ключ — в журнале вызовов. Сохраняется существующий мягкий суточный лимит с границей дня UTC. Бесплатные вызовы и отказы не списывают баланс. `ACCOUNT_FROZEN`, `INSUFFICIENT_BALANCE`, `DAILY_CAP_REACHED` и `COMPANY_BUDGET_EXHAUSTED` закрывают исполнение до вызова вендора.

Для WRITE нужны правило администратора `READ_WRITE`, ключ с правом записи и включённая для портала функция записи. Приложению требуется одобрение владельца в веб-кабинете, заголовок версии десктопа не нужен. Минимальная версия десктопа, включая пустую версию, закрывающую запись, действует только для Коворка. Хост читает собственный билет через [API хоста](./connectors-host.md), ждёт решения человека и повторяет вызов с теми же аргументами и ключом. Одобрение потребляется один раз. Платный отказ до исполнения не потребляет уже одобренный билет. Чувствительные аргументы и секреты вендора не попадают в карточку подтверждения или журнал администратора.

## Коды ошибок

| HTTP | Код | Когда |
|---|---|---|
| 400 | JSON-RPC `-32600` | в запросе пакет сообщений: шлюз принимает одно сообщение |
| 401 | `MISSING_API_KEY`, `INVALID_API_KEY`, `KEY_INACTIVE`, `KEY_EXPIRED` | ключ не передан, неизвестен, отключён или истёк |
| 403 | `CONNECTOR_KEY_NOT_ALLOWED` | ключ не от устройства Коворка или допущенного приложения, либо метод приложения вне белого списка |
| 403 | `OWNER_BLOCKED` | владелец ключа заблокирован или больше не активен на портале |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | ключ в режиме только чтения |
| 404 | `ROUTE_NOT_FOUND` | функция не включена для портала или сотрудника |
| 405 | `METHOD_NOT_ALLOWED` | метод Коворка не `POST` |
| 413 | `PAYLOAD_TOO_LARGE` | тело запроса больше 256 КиБ |
| 429 | `RATE_LIMITED` | превышен платформенный потолок 300 запросов в минуту по одному ключу, у каждого ключа свой счётчик. Действующее для вашего ключа значение — в заголовке `x-ratelimit-limit` (потолок делится на реплики) |
| 503 | `CONNECTOR_VAULT_NOT_CONFIGURED` | коннекторы не настроены на сервере |

Ошибки инструментов приходят в ответе `tools/call` с `isError: true` и кодом в `_meta["vibe/error"].code`.

## Операции BRIDGE

Каждый запуск BRIDGE, включая вызов через `connectors_run_tool`, требует UUID в `params._meta["vibe/idempotencyKey"]`. Это метаданные, а не аргумент инструмента. После таймаута или потери ответа повторяйте то же действие с теми же UUID, аргументами и ключом. Для нового действия создавайте другой UUID. Повтор UUID с другими данными даёт `CONNECTOR_OPERATION_CONFLICT`; автоматически повторять такой отказ нельзя.

### Быстрый READ

Синтетические инструменты `bridge_test` иллюстрируют контракт. Для своего коннектора используйте имя и схему аргументов из обнаружения. Быстрый READ сразу возвращает итоговый результат инструмента:

```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"bridge_test__quick_read","arguments":{},"_meta":{"vibe/idempotencyKey":"123e4567-e89b-42d3-a456-426614174000"}}}
```

```json
{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"ok\":true}"}]}}
```

### Pending и получение результата

Долгий вызов возвращает pending без `isError`. Это не ошибка вендора и не окончательный успех. Вызывайте `connectors_get_result` через `tools/call` на том же `POST /v1/connectors/mcp`; отдельного V1-адреса для результата нет:

```json
{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"The operation is in progress. Retrieve its result later by operationId through connectors_get_result."}],"_meta":{"vibe/operation":{"id":"123e4567-e89b-42d3-a456-426614174000","status":"running","retryAfterMs":1000,"expiresAt":"2026-10-12T13:00:00.000Z","resultTool":"connectors_get_result"}}}}
```

```json
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"connectors_get_result","arguments":{"operationId":"123e4567-e89b-42d3-a456-426614174000"}}}
```

Соблюдайте `retryAfterMs` и интервал не менее секунды. Опрос снова возвращает pending либо итоговый результат инструмента. Закрытие браузера, разрыв соединения и HTTP-таймаут прекращают ожидание, но не принятую работу. Не запускайте новое действие ради получения прежнего результата.

### Платный WRITE

Отправьте WRITE с новым UUID:

```json
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"bridge_test__approved_write","arguments":{},"_meta":{"vibe/idempotencyKey":"123e4567-e89b-42d3-a456-426614174001"}}}
```

Если требуется подтверждение, читайте билет через `GET /v1/connectors/write-tickets/{id}`, дождитесь одобрения владельца в веб-кабинете и повторите тот же вызов с теми же UUID и аргументами. Идентификатор JSON-RPC-запроса может измениться; UUID действия должен сохраниться. Возврат существующей операции выполняется до новой проверки оплаты и WRITE-подтверждения. Потребление подтверждения и резервирование операции атомарны: отказ допуска не расходует подтверждение и не запускает работу. Поэтому потерянный ответ запуска можно повторить без дополнительного эффекта и списания.

### Владение, сроки и оплата

Для результата нужны прежние хост, ключ, портал Битрикс24, подключение и поколение авторизации, а также действующие права. Общий владелец не даёт другому приложению или ключу доступ. Переподключение или отзыв доступа скрывает старый результат и запрещает новый запуск под прежней авторизацией. Служебное восстановление продолжает расчёт уже принятой работы: валидный успешный платный результат оплачивается один раз, даже если его содержимое больше недоступно пользователю. Опрос и повтор не создают нового списания.

| Ограничение | Значение |
|---|---|
| Срок выполнения | 1 час |
| Доступность результата | 24 часа после завершения |
| Запись защиты от повторов | 7 дней |
| Активные операции | 20 на ключ; 100 на портал Битрикс24 и коннектор |
| Опрос результата | 60 запросов в минуту на ключ; интервал не менее секунды |
| Жёсткий размер результата | 256 КиБ |

Цена фиксируется при резервировании операции. Успешное завершение относится к дню завершения по UTC с мягким суточным лимитом; одновременно принятые работы могут превысить этот лимит. До окончательного расчёта журнал показывает **Выполняется** без суммы оплаты. Завершение сохраняет исходное время вызова и привязку к хосту/приложению. Истёкший результат нельзя восстановить новым UUID; сохранённая запись защиты запрещает повторное исполнение старой операции.

### Ошибки операций

Отказы инструмента приходят внутри HTTP 200 с `isError: true` и `_meta["vibe/error"].code`. `CONNECTOR_OPERATION_CONFLICT` — неповторяемый конфликт (HTTP-представление 409); `CONNECTOR_OPERATION_NOT_FOUND` — нейтральный неповторяемый отказ (HTTP-представление 404), в том числе для недоступного этому пользователю результата. Отсутствующие или неверные метаданные повтора дают `INVALID_ARGUMENTS`. Ограничения допуска дают `BUSY`, транспортный таймаут — `VENDOR_UNAVAILABLE`; ни один из них не доказывает отмену принятой внешней работы. Не превращайте неопределённость в новый WRITE. Существующие ошибки авторизации, недоступного инструмента и оплаты сохраняют силу.
