Skip to main content
Glama
mcp-1c-local-bridge

mcp-1c-local-bridge

by ntappw
README.md
# MCP 1C Local Bridge

MCP-сервер и внешняя обработка 1С, через которые ИИ-агент в любом MCP-клиенте выполняет запросы, выражения
и код в открытом сеансе 1С пользователя. Всё работает на компьютере разработчика:
команды и ответы передаются через каталог в профиле пользователя, промежуточного сервера нет.

[![Инфостарт](https://infostart.ru/bitrix/templates/sandbox_empty/assets/tpl/abo/img/logo.svg)](https://infostart.ru/1c/articles/2831401/)

Статья о проекте на Инфостарте: https://infostart.ru/1c/articles/2831401/

## Как это устроено

```
 MCP-клиент с ИИ-агентом
        | stdio
 MCP-сервер mcp-1c-local-bridge (Python, запускается клиентом на время сессии)
        | файлы JSON
 %TEMP%\mcp-1c-local-bridge\<сеанс>\in, work, out, session.json
        | опрос раз в 0,5 с
 обработка MCPLocalBridge.epf, открытая в клиенте 1С
        | вызов сервера в том же сеансе
 сервер 1С
```

- MCP-сервер кладёт команду файлом в каталог сеанса и ждёт файл ответа.
- Форма обработки раз в полсекунды забирает команды, выполняет их на сервере 1С (или на клиенте) в сеансе
  пользователя и с его правами, пишет ответ и раз в 2 секунды обновляет `session.json` (сердцебиение).
- Обмен идёт на стороне клиента 1С: сервер 1С до компьютера пользователя не достаёт, поэтому каталог - на
  этом компьютере, и данные дальше него не уходят.
- Несколько сессий агента и несколько открытых баз работают одновременно: у каждой открытой формы свой
  каталог сеанса, у каждой команды - свой идентификатор.

## Требования

- Windows с клиентом 1С:Предприятие 8.3: тонкий клиент, а для конфигураций на обычных формах - и толстый
  клиент обычного приложения. Обработка рассчитана на режим совместимости конфигурации от 8.3.14 и не
  использует `Асинх`/`Ждать`; режим совместимости 8.2 - в разделе «Обычное приложение и старые конфигурации».
- В конфигурации разрешены синхронные вызовы: свойство «Режим использования синхронных вызовов расширений
  платформы и внешних компонент» - «Использовать» или «Использовать с предупреждениями». Обработка работает
  с файлами на клиенте синхронными методами.
- У пользователя есть право открывать внешние обработки.
- Python 3.11+ и [uv](https://docs.astral.sh/uv/). MCP-сервер запускается на том же компьютере, что и клиент 1С:
  в Windows или в WSL.

## Установка

```bash
git clone https://github.com/ntappw/mcp-1c-local-bridge.git
cd mcp-1c-local-bridge
uv sync
```

Сервер работает по stdio. Зарегистрируйте его в своём MCP-клиенте: команда запуска -
`<каталог клона>\.venv\Scripts\mcp-1c-local-bridge.exe`, аргументов нет (если сервер запускается в WSL -
`<каталог клона>/.venv/bin/mcp-1c-local-bridge`). Формат настроек у клиентов разный, во многих это JSON
такого вида:

```json
{
  "mcpServers": {
    "1c-local-bridge": {
      "command": "C:\\tools\\mcp-1c-local-bridge\\.venv\\Scripts\\mcp-1c-local-bridge.exe"
    }
  }
}
```

После регистрации перезапустите клиент, чтобы он подхватил сервер.

Каталог обмена по умолчанию - `%TEMP%\mcp-1c-local-bridge` пользователя Windows, MCP-сервер находит его сам.
Другой каталог задаётся переменной окружения `MCP_1C_BRIDGE_DIR` - см.
[Свой каталог обмена](#свой-каталог-обмена).

## Работа

1. Откройте `dist/MCPLocalBridge.epf` в нужной базе: «Файл - Открыть» (Ctrl+O). Форма - HTML-страница:
   состояние моста, база и пользователь, режим выдачи результатов, разрешения агенту и журнал команд.
   В толстом клиенте обычного приложения открывается обычная форма с тем же составом (см. «Обычное приложение
   и старые конфигурации»).
2. Агент вызывает `sessions`, видит сеанс и шлёт команды. Пока форма открыта, сеанс жив; закрыли форму -
   каталог сеанса удаляется, команды больше не принимаются. Если мост открыт в нескольких сеансах (например, одна
   база в двух клиентах), подскажите агенту нужный по идентификатору сеанса: его копирует в буфер обмена ссылка
   «скопировать» в шапке формы, в обычной форме - кнопка «Копировать идентификатор».
3. В журнале по каждой команде видны время, вид, текст, итог, краткий результат и длительность. Строка
   раскрывается щелчком прямо в списке: полный текст команды, параметры, результат, сообщения и ошибка.
   Раскрытые строки и прокрутка не сбрасываются, когда приходят новые команды.
4. «Приостановить» останавливает выполнение: команды ждут в очереди. При открытии формы «Запись в базу»
   выключена, «Код на клиенте» включён; оба переключаются тумблерами на форме.

### Выдача результатов

- **Автоматически** (по умолчанию) - ответ уходит агенту сразу после выполнения команды.
- **С подтверждением** - выполненная команда показывается на форме вместе с результатом, и агент получает его
  только после кнопки «Отдать агенту». «Не отдавать» возвращает агенту статус `denied` без данных. Пока
  результат ждёт решения, следующие команды стоят в очереди. Вызов агента, не дождавшийся решения за
  `timeout`, сообщает, что результат ждёт пользователя, и забирает ответ позже инструментом `result`.

  К решению можно приложить комментарий агенту: при отказе - почему результат не отдан и что исправить в
  запросе, при выдаче - что учесть в результате. Агент получает комментарий вместе с ответом и может сразу
  прислать исправленный запрос. Разрешений на форме комментарий не меняет.

### Свой каталог обмена

По умолчанию обработка и MCP-сервер работают в `%TEMP%\mcp-1c-local-bridge` пользователя Windows, и
настраивать ничего не нужно. Другой каталог можно задать, например, если `%TEMP%` чистится или его проверяет
антивирус. Сами стороны каталог не согласуют, поэтому он задаётся в двух местах:

1. В обработке: в строке «Каталог обмена» нажмите «Изменить» и выберите каталог. Сеанс сразу переезжает в
   него с новым идентификатором, а выбор запоминается для пользователя 1С в этой базе и действует при следующих
   открытиях. Пока каталог не стандартный, форма напоминает, что MCP-серверу нужен тот же. «По умолчанию»
   возвращает стандартный каталог.
2. MCP-серверу: тот же каталог в переменной окружения `MCP_1C_BRIDGE_DIR` - путём, под которым каталог виден
   процессу MCP-сервера. Переменную задают в настройках сервера в MCP-клиенте, обычно в поле `env`:

   ```json
   "1c-local-bridge": {
     "command": "C:\\tools\\mcp-1c-local-bridge\\.venv\\Scripts\\mcp-1c-local-bridge.exe",
     "env": {"MCP_1C_BRIDGE_DIR": "D:\\mcp\\exchange"}
   }
   ```

   После изменения перезапустите клиент. Проверка - инструмент `sessions`: в нём виден сеанс, а если сеансов
   нет - каталог, где их ищет MCP-сервер.

Чтобы вернуться к стандартному каталогу, нажмите «По умолчанию» в обработке и уберите переменную из настроек
MCP-сервера.

Клиент 1С на терминальном сервере (RDP): `%TEMP%` там серверный, и MCP-сервер на вашем компьютере его не
видит. Выберите в обработке каталог на диске своего компьютера, проброшенном в сеанс RDP («Локальные ресурсы -
Диски» в настройках подключения), например `\\tsclient\C\mcp-exchange`, а в `MCP_1C_BRIDGE_DIR` - тот же
каталог локально: `C:\mcp-exchange`. Код агента с `side=client` выполняется при этом на терминальном сервере:
файлы, которые он пишет, остаются там, а не на вашем компьютере.

- MCP-сервер смотрит в один каталог. Если в разных базах выбраны разные каталоги, агент видит сеансы только из
  каталога MCP-сервера.
- Каталог должен быть доступен и клиенту 1С, и MCP-серверу.
- В каталоге обмена MCP-сервер трогает только папки сеансов (имя из 8 шестнадцатеричных символов) и пишет
  файл `.clock`, остальное содержимое не меняет.

### Инструменты

| Инструмент | Что делает |
| --- | --- |
| `sessions` | Открытые сеансы моста: база, пользователь, конфигурация, режим совместимости, состояние, разрешения |
| `ping` | Проверка связи: время сервера 1С, номер сеанса, пользователь |
| `query` | Запрос 1С с параметрами; возвращает все результаты пакета, `row_limit` строк каждого |
| `eval` | `Вычислить(<выражение>)` на сервере или на клиенте |
| `execute` | `Выполнить(<код>)`; результат - значение переменной `Результат` |
| `metadata` | Состав конфигурации с отбором или описание объекта по полному имени, включая объекты расширений |
| `result` | Результат команды, не уложившейся в `timeout` |
| `cancel` | Снять команду, которую обработка ещё не начала |
| `find` | Поиск по индексу метаданных: объекты, реквизиты, измерения, табличные части, значения перечислений, подписки и задания - по имени, синониму, обработчику |
| `usages` | Где используется объект: поля его типа, движения, подписки, планы обмена, подсистемы, функциональные опции и другие связи из метаданных |

У команд есть `session` (идентификатор или часть строки соединения; не нужен, если сеанс один) и `timeout`
(до 280 с). Команда, которую обработка не начала за `timeout`, снимается и уже не выполнится; начатая
выполняется дальше, а вызов возвращает её идентификатор для `result`. Ответ больше 20 000 символов
сохраняется в `~/.cache/mcp-1c-local-bridge/results/`, в ответ инструмента попадают начало и пути к файлам.

### Обычное приложение и старые конфигурации

Конфигурации на обычных формах (УТ 10.3, БП 2.0, УПП, КА 1.1) подключаются двумя способами:

- В тонком клиенте: конфигурация открывается в режиме управляемого приложения, и мост работает как обычно,
  в том числе в режиме совместимости 8.2.
- В толстом клиенте обычного приложения - в том же сеансе, где работает пользователь. Толстый клиент открывает
  у обработки её обычную форму: тот же мост на стандартных элементах - состояние, кнопки, флажки режима выдачи
  и разрешений, журнал команд таблицей и под ним подробности выбранной команды. Команды, выдача с
  подтверждением и комментарием, свой каталог обмена и индекс метаданных работают так же, как в управляемой
  форме; `sessions` показывает у такого сеанса «обычное приложение». Серверный код агента выполняет модуль
  объекта обработки в том же процессе толстого клиента, с тем же откатом транзакции. Отличия от тонкого
  клиента:
  - сообщения `Сообщить()` толстый клиент сразу выводит в окно сообщений 1С, агенту в ответе они не приходят;
  - код на клиенте (`side=client`) работает в толстом клиенте с полным доступом к базе, без транзакции и
    отката: запись из него флажок «Запись в базу» не останавливает, её держит только «Код на клиенте»;
  - выбор каталога обмена и предупреждения - модальные окна: пока такое окно открыто, команды не выполняются.

### Индекс метаданных

`find` и `usages` работают по индексу метаданных сеанса: объекты конфигурации и активных расширений, их поля с
типами, движения, подписки, регламентные задания, составы планов обмена, подсистем, функциональных опций, общих
реквизитов. Первый вызов в сеансе моста просит индекс у обработки, дальше поиск идёт в памяти MCP-сервера и окно
1С не занимает.

Обработка хранит индекс в настройках пользователя этой базы и отдаёт оттуда, пока метаданные те же: версия
конфигурации и расширения, состав объектов и число их полей. Иначе индекс строится заново - порциями до секунды,
между которыми окно 1С отвечает; на форме виден процент. Построение дольше `timeout` не теряется: вызов
сообщает, что индекс строится, повторный ждёт ту же команду. Смену типа или переименование поля без изменения их
числа обработка не замечает: после загрузки таких изменений в базу передайте `refresh=true`.

Кода модулей в индексе нет: из режима Предприятия тексты модулей недоступны, обращения из кода ищутся по
выгрузке конфигурации.

### Значения

Ответ обработки - JSON. Ссылка приходит объектом `{"_type": "Справочник.Контрагенты", "_uuid": "...",
"_presentation": "..."}`, значение перечисления - `{"_type": "Перечисление.X", "_name": "...", ...}`,
дата - строкой `2026-10-21T00:00:00`, `NULL` и `Неопределено` - `null`. Таблица значений, результат запроса
и набор записей регистра - колонками и строками (не больше `row_limit`, по умолчанию 1000), объект
справочника или документа - реквизитами и табличными частями. В формате `table` ссылки показываются
представлениями, в `json` - целиком.

Параметры `query` - объект «имя: значение». Простые значения передаются как есть, массив - списком для
`В (&Список)`, особые значения - объектами:

| Объект | Значение 1С |
| --- | --- |
| `{"_date": "2026-10-21"}` | дата (можно с временем) |
| `{"_type": "Справочник.Контрагенты", "_uuid": "..."}` | ссылка; ссылку из ответа можно передать целиком |
| `{"_type": "Перечисление.ВидыКонтрагентов", "_name": "ЮридическоеЛицо"}` | значение перечисления |
| `{"_predefined": "Справочник.Валюты.Рубль"}` | предопределённое значение |
| `{"_expr": "НачалоГода(ТекущаяДатаСеанса())"}` | выражение, вычисленное на сервере |

Пример кода для `execute`:

```bsl
Выборка = Справочники.Валюты.Выбрать();
Результат = Новый Массив;
Пока Выборка.Следующий() Цикл
	Результат.Добавить(Выборка.Ссылка);
КонецЦикла;
```

## Безопасность и ограничения

- Код агента выполняется в живом сеансе пользователя и с его правами. Пока команда идёт, окно 1С не
  отвечает; ошибка платформы в такой команде может уронить сеанс пользователя. Поэтому долгую операцию
  (обмен, массовую обработку) агенту подсказано запускать не одним `execute`, а фоновым заданием через
  экспортный метод общего модуля конфигурации и опрашивать его состояние короткими командами. Фоновое задание
  идёт в своём сеансе, вне транзакции моста: его запись не откатывается и разрешением «Запись в базу» не
  ограничена, поэтому агенту велено запускать его только с `allow_write=true` и с вашего согласия.
- Серверный код `eval` и `execute` по умолчанию выполняется в транзакции, которая после выполнения
  откатывается: изменения в базе не сохраняются. Откат не отменяет внешних эффектов - файлов, HTTP-запросов,
  почты, запуска фоновых заданий, записей журнала регистрации. Сохранить изменения можно только с
  `allow_write=true` и при включённом на форме разрешении «Запись в базу». Пока оно выключено (так при открытии
  формы), запрос записи тоже выполняется с откатом, а в ответе агенту приходит предупреждение.
- Запись тоже идёт в транзакции: изменения фиксируются, только если код отработал без ошибок, а при ошибке
  откатываются целиком - так же, как в проверочном прогоне с откатом. Если код оставил незавершённую свою
  транзакцию или перехватил ошибку записи внутри неё, запись не фиксируется. `transaction=false` выполняет
  запись без транзакции моста: что код успел записать до ошибки, остаётся. Это нужно долгим операциям -
  транзакция держит блокировки всё время выполнения - и коду, который сам управляет транзакциями или ждёт
  фоновые задания.
- Код на клиенте (`side=client`) выполняется в модуле формы обработки, без транзакции, и только при
  разрешении «Код на клиенте». Разрешения и режим выдачи после такого кода восстанавливаются: сам себе код их
  не включит. В толстом клиенте обычного приложения такой код может читать и писать базу напрямую, и «Запись
  в базу» его не ограничивает.
- Каталог обмена лежит в профиле пользователя Windows (`%TEMP%`). Команду в него может положить любой процесс
  под этой учётной записью - тот же уровень доверия, что и у самого сеанса 1С. Свой каталог выбирайте с такими же
  правами: в общую папку команду сможет положить любой, у кого есть запись туда, и она выполнится в вашем сеансе.
- Если на экране модальное окно 1С (например, ошибка компиляции вызванного модуля), обработка не выполняет
  команды, пока окно не закроют. `sessions` показывает такой сеанс как неотвечающий.
- Если MCP-клиент умеет подтверждать вызовы инструментов, не разрешайте `execute` и `eval` без вопроса: пусть
  каждый их вызов подтверждается вручную.

## Сборка обработки

Исходники обработки - XML-выгрузка в `epf/`, собранный файл - `dist/MCPLocalBridge.epf`. Сборке нужна
лицензия 1С, поэтому скрипт подключает конфигуратор к серверной базе (лучше тестовой или копии); в базу
ничего не загружается:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\build-epf.ps1 -Server <сервер> -Ref <база>
```

Модули `.bsl` хранятся в UTF-8 с BOM и переводами строк CRLF, как их выгружает конфигуратор.

Обычная форма `ФормаОбычная` в выгрузке - двоичный контейнер `Form.bin`. Её модуль и макет лежат текстом в
`epf/ordinary-form`; после правки контейнер пересобирается командой `python3 scripts/pack_ordinary_form.py`,
а тест проверяет, что `Form.bin` собран из текущих исходников.

## Протокол

Формат каталога обмена, команд и ответов - [docs/protocol.md](docs/protocol.md).

## Разработка

```bash
uv run pytest
```

Тесты проверяют MCP-сторону с имитацией обработки в отдельном потоке. Обработку проверяют в 1С: открыть
собранный файл в тестовой базе и прогнать `ping`, `query`, `eval`, `execute`, `metadata`.

## Лицензия

[MIT](LICENSE)

TDQS

B3.4/5.0

Scored across 10 tools

Disambiguation4/5

The tools mostly target clearly different operations: execute/eval/query are separated by code execution, expression evaluation, and 1C query language semantics. Metadata, find, and usages overlap in domain but differ as browse, search, and dependency lookup; descriptions help resolve the remaining ambiguity.

Naming Consistency3/5

All names are lowercase single words, but the set mixes verbs (cancel, eval, execute, find, ping) with nouns (metadata, query, result, sessions, usages). The names are readable and semantically clear, but there is no consistent verb_noun or noun-based convention across the toolset.

Tool Count5/5

Ten tools is well within a reasonable range for a bridge server that must cover code execution, queries, metadata introspection, diagnostics, and asynchronous command lifecycle. Each tool appears to earn its place, including auxiliary tools like result, cancel, ping, and sessions.

Completeness4/5

The surface covers the core domain well: execute/eval/query for 1C operations, metadata/find/usages for introspection, sessions/ping for diagnostics, and result/cancel for async command handling. A minor gap is the lack of a general command-status/list operation, but most workflows can be completed with the existing tools.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues