rules-mcp
Allows fetching 1C exchange rules from a Bitbucket repository and parsing them to answer questions about the rules directly in chat.
Allows fetching 1C exchange rules from a Gitea repository and parsing them to answer questions about the rules directly in chat.
Allows fetching 1C exchange rules from a GitHub repository and parsing them to answer questions about the rules directly in chat.
Allows fetching 1C exchange rules from a GitLab repository and parsing them to answer questions about the rules directly in chat.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@rules-mcpПокажи расхождения в правилах обмена для УПП_ЕРП"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
rules-mcp — правила обмена 1С в чате
MCP-сервер, который разбирает боевые правила обмена 1С (Конвертация данных 2.0) и отвечает на вопросы о них прямо в чате Open WebUI: как работает конкретный обмен, что создаётся у приёмника, где расхождение с конфигурацией.
Правила обмена — это XML на десятки мегабайт со встроенным кодом обработчиков. Прочитать их целиком нельзя, искать по ним вслепую — терять каскады и протекающие ветки. Сервер разбирает их один раз в индекс и отвечает точечно.
Разбор — обычная программа, языковая модель в нём не участвует и токены на него не тратятся. Токены уходят только на то, что инструмент вернул в чат.
Поддерживается КД 2.0 (
ExchangeRules.xml+RegistrationRules.xml). Конвертация данных 3 (EnterpriseData) — другой формат, здесь не поддерживается.Только стандартная библиотека Python для разбора, одна зависимость для MCP.
Индекс живёт в памяти, базы данных нет. 36 МБ правил разбираются за секунду.
Что умеет
Инструмент | Отвечает на вопрос |
| Какие есть направления, документы, процессы |
| Что происходит с документом при обмене — от регистрации до приёмника; где стоит каждый вызов правила; что из этого при обмене через план не сработает |
| Одно правило конвертации целиком: признаки, реквизиты, табличные части, каскады, замечания проверки |
| Где вообще упоминается реквизит, алгоритм или фрагмент логики |
| Полный текст обработчика правила, реквизита, табличной части или общего события конвертации — постранично, с номерами строк |
| Запросы обработчика: пакет, параметры, временные таблицы |
| Что в правилах сломано или при обмене через план не сработает — без конфигураций |
| Что правила ждут от конфигурации приёмника — для сверки |
| Забрать свежие правила из репозитория сейчас, не дожидаясь часа |
Инструменты намеренно общие, а не готовые отчёты: пользователь спрашивает как угодно, а ответ складывает модель.
search_rules отвечает отдельными строками, и по одной строке нельзя судить о
том, при каких условиях ветка выгрузки выбирает правило конвертации. Поэтому у
каждого попадания есть номер строки, а рядом стоит get_rule_handler: он отдаёт
весь обработчик целиком, страницами, с теми же номерами строк. Если показано не
всё, в ответе будет «следующая строка» — молча обрезанного текста не бывает.
trace_document сразу говорит, где стоит вызов каждого правила конвертации:
обработчик и номер строки в той же нумерации. Закомментированные вызовы не
показываются; правило, заданное в свойствах ветки, а не вызовом в коде, так и
помечено. Для вызовов через общие алгоритмы — обе строки: где ветка зовёт
алгоритм и где в алгоритме стоит вызов. Рядом с процессами ветки — откуда
каждая метка: своя у ветки или пришла от вызываемого правила. Метка чужого
правила не значит, что ветка выгружает этот процесс.
Отбор по правилу в search_rules понимает код, наименование и имя объекта —
как get_rule_handler. Коды правил регистрации числовые, поэтому их удобнее
называть именем документа; если правил у документа несколько, ищется по всем.
get_rule_queries делает механическую часть, в которой легко ошибиться руками:
делит пакет на отдельные запросы, сопоставляет Результат[n] с номером запроса в
пакете, показывает, где создаётся каждая временная таблица и от каких она зависит.
Текст, собранный не из строкового литерала, а выражением, полным не выдаётся —
такой запрос помечается неполным. Вычисляемый номер элемента пакета не
угадывается, а выносится отдельно как неопределённый.
Инструменты видят не только правила, но и общие алгоритмы с именованными
запросами: ветка выгрузки часто зовёт Выполнить(Алгоритмы.Имя), а сам вызов
правила конвертации стоит внутри алгоритма. В правилах УПП → ЕРП так спрятаны
34 вызова, и без обхода алгоритмов часть документов приёмника просто не видна.
И ещё обработчики отдельных реквизитов правил конвертации. Там лежит условие
заполнения реквизита — не то же самое, что условие выбора правила: признак может
влиять на то, чем заполнится склад, и никак не влиять на то, какое правило
сработает. Таких обработчиков по корпусу 2115, они есть у 489 правил конвертации.
Карточка правила (get_conversion_rule) показывает у реквизита с обработчиком его
код, перечень обработчиков в get_rule_handler перечисляет такие реквизиты, а
прочитать обработчик можно тем же get_rule_handler с параметром prop — кодом
реквизита или именем приёмника. Имя приёмника внутри правила бывает не
единственным (в шапке и в табличной части), тогда в ответе перечень — выберите код.
search_rules ищет и по ним; у такого попадания есть поля «реквизит» и «код
реквизита».
Проверка правил и поведение БСП
check_rules находит в правилах то, что видно без конфигураций и баз:
ошибки: обращение к алгоритму, которого нет, или к алгоритму другого режима (выгрузки вместо загрузки); ссылку на несуществующее правило конвертации; повтор кода;
ветки, которые при обмене через план работают не так, как выглядят: вторая ветка на тот же тип (не исполняется — БСП берёт первую), произвольный отбор, выборка и «Отказ» в «перед обработкой правила» (не исполняются), ветка на объект, который не регистрируется к обмену;
правила конвертации, на которые никто не ссылается, и объекты, которые уходят только ссылкой (в приёмник попадают лишь поля поиска);
формы поиска в приёмнике, дающие дубли или слияние объектов;
запись объекта в «после загрузки» — проведение дважды.
У каждого замечания — адрес для get_rule_handler (правило, обработчик, строка,
код реквизита) и чем оно грозит. Замечание в алгоритме, который никто не
вызывает, понижено: на обмен оно не влияет.
Проверки перенесены из kd2-rules-mcp (Егор Доронченко, MIT) — те, которым не нужны структуры конфигураций. Там же — обоснования строками кода БСП 3.1.12. Утверждения о ветках выгрузки мы дополнительно сверили с кодом БСП 2.3. Где наша реализация отличается, она точнее на этом корпусе: закомментированный вызов и ссылка из отключённого реквизита вызовом не считаются, явная выгрузка из обработчика реквизита — это выгрузка объекта целиком. Справочник поведения БСП для модели — BSP_BEHAVIOR.md.
Из той же работы — что разбор видит весь код правил: обработчик поиска, обработчики реквизитов «при выгрузке» и «после выгрузки», обработчики табличных частей и общие события конвертации (в УПП → ЕРП одно из них — 9 167 строк). До версии 3.0.0 они в индекс не попадали.
Ради чего всё затевалось
Правила целиком состоят из ссылок на реквизиты и типы двух конфигураций. Проверить их в одиночку нельзя. Но если рядом подключён сервер, читающий конфигурации 1С (например rlm-tools-bsl), появляется проверка, которую иначе делают руками:
1. rules-mcp → «правила пишут вот в эти реквизиты приёмника, вот их типы»
2. сервер конфигураций → «а вот что реально есть у этого объекта»
3. модель → сравнивает и показывает расхожденияРеквизита нет, он переименован или сменил тип — обмен на этом не падает, он молча не переносит данные. Это самая дорогая и самая незаметная поломка обмена.
Серверы друг друга не знают и ничего друг о друге не предполагают — разворачиваются и чинятся независимо. Связывает их модель: когда и как идти во второй сервер, написано в PROMPT.md и в разделе «Сверка с конфигурацией» KNOWLEDGE.md.
Related MCP server: onec-meta-mcp
Как должны лежать правила
Папка на направление обмена, внутри выгрузка из Конвертации данных:
<корень или подкаталог репозитория>/
├── УПП_ERP/
│ ├── ExchangeRules.xml правила выгрузки (ПВД) и конвертации (ПКО)
│ ├── RegistrationRules.xml правила регистрации (ПРО)
│ └── CorrespondentExchangeRules.xml не читается
├── ERP_УПП/
│ └── …
└── Розница_ERP/
└── …Направление определяется по файлу ExchangeRules.xml; папка без него молча
пропускается. Имена папок могут быть на кириллице или латиницей — стороны
обмена берутся из самих правил, а не из имени папки, поэтому «УПП → ЕРП»,
«упп erp», «из розницы в ерп» и «УПП_ERP» распознаются одинаково.
Порядок сторон значим: УПП_ERP и ERP_УПП — разные направления с разными
правилами, и сервер их не путает.
Как выкладывать новые правила
Сервис читает одну ветку репозитория — заданную в GITLAB_BRANCH — и в ней
одну папку, заданную в RULES_SUBDIR. Чего нет в этой ветке и этой папке,
для сервиса не существует.
Новое направление
Выгрузить из Конвертации данных
ExchangeRules.xmlиRegistrationRules.xml.Положить в новую папку прямо в каталоге правил, без вложенности:
src/rules/Розница_ERP/ExchangeRules.xml. Папку глубже сервис не увидит.Влить в боевую ветку.
Подождать до часа или попросить в чате «обнови правила».
Обновление существующего направления
Заменить файлы в той же папке. Не заводить рядом УПП_ERP_новые или
УПП_ERP_v2: на две папки с одним направлением сервис отвечает «направление
понято неоднозначно», а старая так и остаётся в ответах.
Ветки в git
Рабочую ветку под новые правила заводить можно — сервис её не увидит, пока изменения не влиты в боевую. Это и есть защита от черновиков в чате.
Переключить сервис на другую ветку — поменять
GITLAB_BRANCHв.envи пересоздать контейнер:docker compose up -d rules-mcp. Клон удалять не надо.Смотреть в чате и боевые правила, и черновые — второй экземпляр сервиса: своя ветка, свой том, своё подключение и отдельная модель в Open WebUI. Один экземпляр на две ветки не настраивается.
Проверить, что подхватилось
Спросить в чате «какие есть направления обмена». Новое направление в списке, в «версии правил» — нужная ветка и последний коммит из GitLab, поля «внимание» нет.
Что видно | Причина |
Коммит последний, а направления нет | Папка не в каталоге правил или вложена глубже; файл назван не |
Коммит старый, «внимания» нет | Правила лежат в другой ветке и не влиты в боевую; либо не прошёл час |
«внимание: не прочитаны: <папка> — …» | Файл битый или пересохранён в другой кодировке. По этой папке отвечают прежние правила, остальные обновились |
«направление понято неоднозначно» | Две папки с одним и тем же направлением |
«без версии (каталог не под git)» | Сервис не подключён к репозиторию: не задан |
Установка
Вариант 1. Docker рядом с Open WebUI (рекомендуется)
Добавьте в ваш docker-compose.yml (или возьмите готовый фрагмент из
docker-compose.yml):
services:
rules-mcp:
build: ./rules-mcp # или image: ghcr.io/…, если соберёте свой
environment: # значения — в .env, здесь не править
GITLAB_REPO: ${GITLAB_REPO:-}
GITLAB_TOKEN: ${GITLAB_TOKEN:-}
GITLAB_BRANCH: ${GITLAB_BRANCH:-}
RULES_SUBDIR: ${RULES_SUBDIR:-}
REFRESH_INTERVAL: ${REFRESH_INTERVAL:-3600}
volumes:
- rules-clone:/data # клон переживает перезапуск контейнера
restart: unless-stopped
networks: [ai]
open-webui:
# ваш существующий сервис; нужно добавить только это
environment:
WEBUI_SECRET_KEY: ${WEBUI_SECRET_KEY}
networks: [ai]
volumes:
rules-clone:
networks:
ai:git clone https://github.com/kopyshok/rules-mcp.git
cat rules-mcp/.env.example >> .env # дописать к своему .env; заполнить адрес, токен, ветку
docker compose up -d --build rules-mcp
docker compose logs -f rules-mcpСекции ports намеренно нет: наружу сервис публиковать не надо, Open WebUI
дотянется до него по внутренней сети. Это же снимает вопрос доступа извне.
Вариант 2. Без Docker
git clone https://github.com/kopyshok/rules-mcp.git && cd rules-mcp
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
export RULES_DIR=/путь/к/каталогу/с/направлениями
export REFRESH_INTERVAL=0 # работать с тем, что уже на диске
python server.pyНужен Python 3.10+ и установленный git, если правила берутся из репозитория.
Настройки
Все настройки — через переменные окружения. Образец: .env.example.
Переменная | По умолчанию | Смысл |
| пусто | Адрес репозитория с правилами по HTTPS. Пусто — работать с тем, что уже лежит в |
| пусто | Токен на чтение репозитория |
| пусто | Ветка с правилами. Пусто — ветка по умолчанию |
| пусто | Подкаталог внутри репозитория, если папки направлений лежат не в корне |
|
| Период опроса, секунды. |
|
| Каталог с направлениями. При работе из репозитория клон кладётся в |
|
| Адрес прослушивания |
Несмотря на имена, GITLAB_* работают с любым git-сервером — GitHub, Gitea,
Bitbucket. Имена оставлены такими, потому что писалось под GitLab.
Подключение к GitLab
1. Токен на чтение
Лучше deploy-токен: он привязан к репозиторию, а не к человеку, и не отвалится, когда сотрудник уйдёт.
Settings → Repository → Deploy tokens → Add token
Name:
rules-mcpExpires: можно оставить пустым
Scopes: только
read_repository
GitLab покажет имя пользователя и сам токен один раз. Сервису нужен только токен — имя пользователя он подставляет сам.
Личный токен (Settings → Access Tokens, область read_repository) тоже
подойдёт, если deploy-токены запрещены политикой.
2. Адрес репозитория
Только HTTPS. SSH не поддерживается — в контейнере нет ключей и известных хостов, и заводить их ради чтения одного репозитория не стоит.
GITLAB_REPO=https://gitlab.example.ru/exchange/rules.git
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxxТокен не надо вписывать в адрес — сервис подставит его сам при обращении. Так он не попадает ни в логи, ни в вывод команд.
Если GitLab на нестандартном порту, укажите его в адресе как обычно:
https://gitlab.example.ru:8443/exchange/rules.git.
3. Ветка с правилами
GITLAB_BRANCH=mainУказывайте ветку явно. Если оставить пусто, берётся ветка по умолчанию — а она в репозиториях с правилами часто оказывается черновой. Аналитики будут читать не то, что стоит на продуктиве, и не узнают об этом.
Заведите отдельную ветку под боевые правила (prod, production, release) и
укажите её. Сервис работает ровно с ней: git fetch и git reset идут по
указанной ветке, изменения в других ветках его не трогают.
Ветка видна в ответе каждого инструмента — поле «версия правил»:
ветка prod, коммит d54877b от 08.09.2026Так человек в чате всегда видит, на какой версии правил построен ответ.
4. Правила лежат не в корне
RULES_SUBDIR=exchange/rulesКлонируется репозиторий целиком, но папки направлений ищутся в этом
подкаталоге. Путь указывается от корня репозитория, через /.
5. Проверка
docker compose logs rules-mcp # клонирование и стартЕсли токена не хватает или ветки нет, сервис не падает: он продолжает отвечать на прежнем индексе, а в каждый ответ добавляется поле «внимание» с текстом ошибки. Это видно прямо в чате — молчаливой рассинхронизации не будет.
Подключение к Open WebUI
Родная поддержка MCP появилась в Open WebUI 0.6.31. На версиях старее понадобится обновление либо прослойка mcpo.
Настройки → Админ → Интеграции → Внешние серверы инструментов → Добавить:
Поле | Значение |
Тип | MCP (Streamable HTTP) |
Адрес |
|
Авторизация | None |
Три места, где спотыкаются:
Тип должен быть MCP, не OpenAPI. Если вписать MCP-настройки в подключение типа OpenAPI, интерфейс уходит в бесконечную загрузку. Лечится удалением подключения и повторным добавлением.
Адрес — имя контейнера, а не
localhost. Глобальные подключения выполняются самим Open WebUI, иlocalhostвнутри его контейнера означает его же, а не сервер.Авторизация именно None. Выбранный «Bearer» с пустым ключом шлёт пустой заголовок, и соединение рвётся.
В Open WebUI должен быть задан WEBUI_SECRET_KEY, иначе подключения слетают
при каждом пересоздании контейнера.
Чтобы люди не включали инструмент вручную
Глобальный инструмент в чате сам не появляется — каждому пришлось бы включать его в меню интеграций. Вместо этого соберите модель:
Рабочая область → Модели → Создать
базовая модель — ваша обычная;
системная подсказка — готовый текст в PROMPT.md;
знания — KNOWLEDGE.md (инструменты, порядок вызова, разобранный пример) и BSP_BEHAVIOR.md (как БСП исполняет правила), плюс методичка и карта процессов, если они у вас есть;
инструменты —
rules-mcpи сервер конфигураций, включены принудительно;доступ — нужной группе.
Пользователь выбирает модель из списка, и у него уже всё настроено.
Обновление правил
Три пути, все работают вместе:
Автоматически раз в
REFRESH_INTERVALсекунд. Если коммит не сменился, индекс не пересобирается — проверка стоит несколько килобайт трафика.Из чата — попросить «обнови правила», модель вызовет
refresh_rules. Нужен, когда только что выложили релиз и ждать час не хочется. Пароля нет: если коммит не сменился, вызов ничего не пересобирает, поэтому лишний вызов безвреден.Перезапуском контейнера — индекс собирается заново при старте.
Индекс подменяется целиком и только после того, как новый успешно собран. Пока он строится, сервер продолжает отвечать на старом. Если забрать правила не удалось, старый индекс остаётся в работе.
Если не читается одна папка (битый XML, не та кодировка), остальные направления всё равно обновляются. По битой остаётся прежняя версия, а в поле «внимание» указано, какая папка и что с ней.
Если что-то не работает
Симптом | Причина |
Open WebUI не видит сервер | Адрес |
Интерфейс виснет при добавлении | Выбран тип OpenAPI вместо MCP |
Соединение сразу рвётся | Авторизация «Bearer» с пустым ключом; нужна None |
Подключения слетают после пересоздания | Не задан |
«направлений: 0» | Не тот |
В ответах поле «внимание» | Не проходит обновление: протух токен, нет ветки, недоступна сеть — или не читается папка направления. Текст ошибки там же |
«версия правил: без версии (каталог не под git)» | Не задан |
Модель не зовёт инструменты | Вопрос к модели, а не к серверу. Проверьте на модели с надёжным вызовом инструментов |
Посмотреть, что сервер вообще отдаёт:
docker compose exec rules-mcp python -c "
import asyncio
from fastmcp import Client
async def m():
async with Client('http://127.0.0.1:8000/mcp') as c:
for t in await c.list_tools(): print(t.name)
print((await c.call_tool('exchange_overview', {})).data)
asyncio.run(m())"Как устроено внутри
rules_index.py — разбор XML и индекс. Только стандартная библиотека. Правила регистрации, ветки выгрузки, правила конвертации со всеми свойствами и табличными частями, каскады в подчинённые правила, функциональные блоки (процессы), которыми разработчики помечают ветки, общие алгоритмы и именованные запросы.
query_extract.py — разбор запросов в коде обработчиков: многострочные литералы 1С, деление пакета, параметры, временные таблицы и их зависимости. Тоже только стандартная библиотека, от индекса не зависит.
checks.py — проверки правил для
check_rules. Только стандартная библиотека, работает поверх индекса; замечания считаются один раз на версию правил.server.py — инструменты, работа с git, фоновое обновление. Тонкая обёртка: разрешить направление, вызвать функцию индекса, добавить версию правил. Вся логика лежит в
rules_index.py, чтобы её можно было проверять тестами без установленногоfastmcp.
Отбор регистрации разворачивается в читаемое дерево условий вместо XML:
(ИЛИ:
(И:
ВидОперации = ПокупкаКомиссия
ВидПоступления = ПоОрдеру
Контрагент.НеЯвляетсяРезидентом = Истина
)
…
)Ответы по умолчанию сжатые: тексты обработчиков отдаются только по запросу
(get_conversion_rule с verbose=true), состав справочников приёмника — отдельным
вызовом. Иначе один ответ съедает контекст чата.
Исключение — get_rule_handler: он для того и сделан, чтобы отдавать текст целиком.
Половина обработчиков короче 170 знаков и приходит одним куском; крупных, больше
20 000 знаков, во всём корпусе четыре десятка, и только им нужны страницы. Самый
большой — около 100 000 знаков.
Проверка
python test_rules_index.py /путь/к/каталогу/с/направлениями
python test_reading.py
python test_query_extract.py
python test_checks.pytest_rules_index.py проверяет на настоящих правилах: направления распознаются с
учётом порядка сторон, ветки выгрузки не зовут несуществующих правил конвертации,
отбор регистрации разбирается, каскады не зацикливаются, справочники без своей
ветки выгрузки находятся через подчинённые правила.
test_reading.py — чтение и поиск: все крупные обработчики читаются страницами и
собираются знак в знак, номер строки из поиска годится для чтения, закомментированный
вызов правила в выдачу не попадает, многозначное имя правила даёт ошибку с перечнем,
а не молчаливый выбор. То же для обработчиков реквизитов: все читаются и
собираются, находятся по коду и по имени приёмника, повторяющееся имя приёмника
даёт ошибку с перечнем, поиск по ним отсеивает закомментированные строки.
Места вызовов правил в trace_document по всему корпусу указывают на живую
строку с вызовом и не теряют ни одного вызова; метки процессов ветки делятся
на свои и пришедшие без потерь; отбор поиска по имени объекта даёт то же, что
по кодам его правил.
Там же с 3.0.0: каждый текст с кодом из XML правил находится среди обработчиков индекса — пропущенный вид обработчика больше не пройдёт молча.
test_checks.py — проверки: на маленьких искусственных правилах каждая
срабатывает где надо и молчит рядом (закомментированное, строка в кавычках,
отключённое); на боевых — известные факты корпуса, сверенные с файлами вручную.
test_query_extract.py — разбор запросов по всему корпусу без исключений, номера
элементов пакета совпадают с присваиваниями Результат[n], вычисляемые номера не
угадываются, у неполного запроса текста нет.
Версии
Номер версии — три числа через точку: основная.дополнительная.исправление.
основная растёт, когда ответ инструмента меняется так, что прежняя системная подсказка или база знаний перестают ему соответствовать;
дополнительная — новый инструмент или параметр, старое работает как раньше;
исправление — ошибка исправлена, поведение по описанию не менялось.
Текущая версия записана в server.py и видна в каждом ответе сервиса («версия
сервиса») — так из чата видно, что именно развёрнуто. История — в
CHANGELOG.md.
Лицензия
MIT — см. LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Official Microsoft MCP Server to query Microsoft Entra data using natural language
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
MCP server for Gainium — manage trading bots, deals, and balances via AI assistants
MCP server enabling AI agents to manage Bitrix24 features via standardized protocol
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceMCP server providing tools for interacting with 1С:Напарник AI, including asking questions, syntax explanation, code review, and documentation search. Also serves as a web chat interface and OpenAI-compatible API gateway.108AGPL 3.0
- FlicenseNot gradedqualityBmaintenanceMCP server for searching and analyzing 1C enterprise metadata and BSL code using a SQLite backend. Enables querying configuration structure, code routines, and performing compliance checks via natural language.-
- AlicenseNot gradedqualityDmaintenanceMCP server for RAG-based search over 1C Enterprise configuration documentation, enabling natural language queries to find objects like справочники, документы, and отчеты.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server that provides read-only access to 1C:Enterprise configuration metadata extracted into SQLite, enabling LLMs to inspect objects, modules, and validate 1C queries.MIT