Skip to main content
Glama
spritelutsk

1C via COM MCP Server

by spritelutsk
README.md
# MCP-сервер 1С через COM (V83.COMConnector)

Внешний MCP-сервер на Python, который подключается к информационной базе 1С через
COM-соединение (`V83.COMConnector`) и выполняет запросы на встроенном языке запросов.
В отличие от подхода с расширением + HTTP-сервисами, здесь **ничего не нужно ставить
в саму базу** — сервер сам открывает внешнее соединение.

> ⚠️ Работает **только на Windows**, где установлена платформа 1С:Предприятие.

## Возможности (инструменты MCP)

| Инструмент | Назначение |
|-----------|-----------|
| `execute_query` | Выполнить запрос на языке запросов 1С, вернуть колонки и строки |
| `list_metadata` | Список объектов метаданных (справочники, документы, регистры, …) |
| `describe_object` | Реквизиты, табличные части и типы объекта по полному имени |
| `execute_script` | Выполнить произвольный код 1С / вычислить выражение (нужна обработка-исполнитель) |
| `connection_info` | Проверить соединение, узнать версию конфигурации и платформы |

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

- Windows + установленная 1С:Предприятие 8.3
- Python 3.10+
- **Совпадение разрядности**: 64-битный Python ↔ 64-битный `comcntr.dll`
  (32-битный ↔ 32-битный). Большинство современных установок — 64 бита.

## Установка

```powershell
cd "D:\Documents\разработка_1С\mcp-1c-com"
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
```

### Регистрация COM-коннектора

Один раз, **от имени администратора**, зарегистрируйте `comcntr.dll` нужной версии:

```powershell
regsvr32 "C:\Program Files\1cv8\8.3.25.1257\bin\comcntr.dll"
```

(путь к версии платформы — свой; берётся последняя установленная)

## Конфигурация

Через переменные окружения. Скопируйте `.env.example` и задайте значения, либо
выставьте переменные прямо в команде запуска / в `.mcp.json` (см. ниже).

**Файловая база:**
```
ONEC_FILE=C:\bases\acc
ONEC_USR=Администратор
ONEC_PWD=пароль
```

**Серверная база:**
```
ONEC_SRVR=server-1c
ONEC_REF=accounting
ONEC_USR=Администратор
ONEC_PWD=пароль
```

**Готовая строка соединения целиком** (имеет приоритет):
```
ONEC_CONNECTION_STRING=File="C:\bases\acc";Usr="Администратор";Pwd="pass"
```

## Запуск вручную (проверка)

```powershell
$env:ONEC_FILE = "C:\bases\acc"
$env:ONEC_USR  = "Администратор"
python server.py
```

Сервер работает по stdio-транспорту MCP. Для интерактивной отладки удобен
`mcp dev server.py` (требует `pip install "mcp[cli]"`).

## Подключение к Claude Code

Добавьте сервер в `.mcp.json` проекта (пример — в `mcp.json.example`):

```json
{
  "mcpServers": {
    "1c-com": {
      "command": "D:\\Documents\\разработка_1С\\mcp-1c-com\\.venv\\Scripts\\python.exe",
      "args": ["D:\\Documents\\разработка_1С\\mcp-1c-com\\server.py"],
      "env": {
        "ONEC_FILE": "C:\\bases\\acc",
        "ONEC_USR": "Администратор",
        "ONEC_PWD": ""
      }
    }
  }
}
```

Либо командой:

```powershell
claude mcp add 1c-com -- "<путь>\.venv\Scripts\python.exe" "<путь>\server.py"
```

## Примеры использования

**Запрос с параметром-датой:**
```json
{
  "query_text": "ВЫБРАТЬ Ссылка, ПРЕДСТАВЛЕНИЕ(Контрагент) КАК Контрагент, СуммаДокумента ИЗ Документ.РеализацияТоваровУслуг КАК Р ГДЕ Р.Дата >= &Дата УПОРЯДОЧИТЬ ПО Р.Дата",
  "params": { "Дата": "2026-01-01" },
  "limit": 100
}
```

**Список справочников:**
```json
{ "kind": "catalogs" }
```

**Описание объекта:**
```json
{ "full_name": "Справочник.Контрагенты" }
```
Вернёт реквизиты с типами (ссылочные — полным именем, напр. `Справочник.ДоговорыКонтрагентов`,
`Перечисление.ЮрФизЛицо`; примитивные — `Строка(12)`, `Число(3)`), табличные части и их реквизиты.

**Выполнение кода / вычисление выражения** (требует обработку-исполнитель, см. ниже):
```json
{ "return_expression": "Справочники.Валюты.НайтиПоКоду(\"980\").Наименование" }
```
```json
{ "code": "Док = Документы.РеализацияТоваровУслуг.НайтиПоНомеру(\"000001\"); Результат = Док.СуммаДокумента;" }
```

## execute_script: обработка-исполнитель и «Защита от опасных действий»

Внешнее COM-соединение **не отдаёт** операторы `Выполнить`/`Вычислить` (это конструкции
языка, а не методы глобального контекста). Поэтому `execute_script` исполняет код внутри
модуля внешней обработки `executor\mcpИсполнитель.epf`, где эти операторы доступны как
обычные операторы языка. Код может присвоить значение переменной `Результат` — оно будет
возвращено.

**Сборка обработки-исполнителя** (если её нет в `executor\`):
```powershell
powershell.exe -NoProfile -File "<skills>\epf-build\scripts\epf-build.ps1" `
  -InfoBasePath "C:\bases\acc" -UserName "Администратор" -Password "..." `
  -SourceFile "executor\src\mcpИсполнитель.xml" -OutputFile "executor\mcpИсполнитель.epf"
```

**Предупреждение безопасности.** Поскольку модуль использует `Выполнить`/`Вычислить`,
платформа при загрузке обработки показывает «Предупреждение безопасности» (через COM это
превращается в ошибку). Чтобы `execute_script` заработал, для пользователя ИБ нужно
**отключить «Защиту от опасных действий»**:

- **Конфигуратор → Администрирование → Пользователи → `<пользователь>` →
  снять флаг «Защита от опасных действий»**, либо
- один раз открыть `executor\mcpИсполнитель.epf` в толстом клиенте 1С и подтвердить
  с галкой «Запомнить выбор».

> В старых режимах совместимости (напр. УТП 1.2) свойство `ЗащитаОтОпасныхДействий`
> пользователя ИБ через COM не записывается — отключайте флаг в Конфигураторе.

Остальные инструменты (`execute_query`, `list_metadata`, `describe_object`,
`connection_info`) работают **без** этой настройки.

## Особенности и ограничения

- **Ссылки возвращаются как UUID.** Чтобы получить читаемое представление,
  добавляйте в запрос `ПРЕДСТАВЛЕНИЕ(Поле) КАК ПолеПредставление`.
- **«Пустая дата» 1С** (`0001-01-01`) отдаётся как `null`.
- Весь COM-доступ идёт через один выделенный поток (COM-объекты 1С привязаны к
  апартаменту), поэтому запросы выполняются последовательно.
- Соединение ленивое и переиспользуется между вызовами.
- Параметры запроса поддерживают примитивы (число, строка, булево) и даты
  (ISO-строка). Передача ссылок параметром не поддерживается — фильтруйте по
  реквизитам/коду/наименованию внутри запроса.
- В `describe_object` ссылочные типы и `Строка(N)`/`Число(d,f)` определяются точно.
  В старых режимах совместимости (УТП 1.2 и т.п.) глобальный конструктор `Тип()`
  через COM недоступен, поэтому `Дата`, `Булево` и безразмерные строки показываются
  как `примитив`.
- `execute_script` требует обработку-исполнитель и отключённую «Защиту от опасных
  действий» (см. отдельный раздел выше).

## Диагностика проблем

**`AttributeError: V83.COMConnector.Connect` / `Библиотека не зарегистрирована`
(TYPE_E_LIBNOTREGISTERED).**
Сам COM-класс зарегистрирован, но не зарегистрирована **библиотека типов** коннектора.
1С-коннектор — dual-интерфейс и резолвит имена методов (`Connect`) через typelib,
поэтому без неё позднее связывание не находит ни одного метода. Лечится повторной
регистрацией `comcntr.dll` **от имени администратора** (regsvr32 ставит и класс, и
typelib):
```powershell
Start-Process regsvr32 -ArgumentList '/s','"C:\Program Files\1cv8\<версия>\bin\comcntr.dll"' -Verb RunAs -Wait
```
Проверка, что typelib появилась: ключ
`HKCR\TypeLib\{98AC3B5B-5323-418F-8F07-E32F231D2393}` должен существовать.

**`Класс не зарегистрирован` (0x80040154)** — не зарегистрирован сам класс
(`regsvr32 comcntr.dll`) либо не совпадает разрядность Python и dll.

**Несколько версий платформы установлено.** `V83.COMConnector` указывает только на одну
версию (последнюю зарегистрированную). Чтобы привязать к конкретной — выполните
`regsvr32` именно её `comcntr.dll`.

## Структура

```
mcp-1c-com/
├── server.py        # MCP-сервер (FastMCP, stdio), определение инструментов
├── onec_com.py      # COM-подключение к 1С, запросы, описание объектов, исполнение кода
├── config.py        # сборка строки соединения из переменных окружения
├── executor/
│   ├── mcpИсполнитель.epf      # собранная обработка-исполнитель для execute_script
│   └── src/                    # её XML-исходники (модуль с ВыполнитьКод/ВычислитьВыражение)
├── requirements.txt
├── .env.example
└── mcp.json.example
```