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 ищет и по ним; у такого попадания есть поля «реквизит» и «код
реквизита».
Ради чего всё затевалось
Правила целиком состоят из ссылок на реквизиты и типы двух конфигураций. Проверить их в одиночку нельзя. Но если рядом подключён сервер, читающий конфигурации 1С (например rlm-tools-bsl), появляется проверка, которую иначе делают руками:
1. rules-mcp → «правила пишут вот в эти реквизиты приёмника, вот их типы»
2. сервер конфигураций → «а вот что реально есть у этого объекта»
3. модель → сравнивает и показывает расхожденияРеквизита нет, он переименован или сменил тип — обмен на этом не падает, он молча не переносит данные. Это самая дорогая и самая незаметная поломка обмена.
Серверы друг друга не знают и ничего друг о друге не предполагают — разворачиваются и чинятся независимо. Связывает их модель: когда и как идти во второй сервер, написано в PROMPT.md и в разделе «Сверка с конфигурацией» KNOWLEDGE.md.
Related MCP server: bsl-context
Как должны лежать правила
Папка на направление обмена, внутри выгрузка из Конвертации данных:
<корень или подкаталог репозитория>/
├── УПП_ERP/
│ ├── ExchangeRules.xml правила выгрузки (ПВД) и конвертации (ПКО)
│ ├── RegistrationRules.xml правила регистрации (ПРО)
│ └── CorrespondentExchangeRules.xml не читается
├── ERP_УПП/
│ └── …
└── Розница_ERP/
└── …Направление определяется по файлу ExchangeRules.xml; папка без него молча
пропускается. Имена папок могут быть на кириллице или латиницей — стороны
обмена берутся из самих правил, а не из имени папки, поэтому «УПП → ЕРП»,
«упп erp», «из розницы в ерп» и «УПП_ERP» распознаются одинаково.
Порядок сторон значим: УПП_ERP и ERP_УПП — разные направления с разными
правилами, и сервер их не путает.
Установка
Вариант 1. Docker рядом с Open WebUI (рекомендуется)
Добавьте в ваш docker-compose.yml (или возьмите готовый фрагмент из
docker-compose.yml):
services:
rules-mcp:
build: ./rules-mcp # или image: ghcr.io/…, если соберёте свой
environment:
GITLAB_REPO: https://gitlab.example.ru/exchange/rules.git
GITLAB_TOKEN: ${GITLAB_TOKEN}
GITLAB_BRANCH: main
RULES_SUBDIR: ""
REFRESH_INTERVAL: "3600"
REFRESH_PASSWORD: ${RULES_REFRESH_PASSWORD}
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
cp rules-mcp/.env.example .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 (инструменты, порядок вызова, разобранный пример), плюс методичка и карта процессов, если они у вас есть;
инструменты —
rules-mcpи сервер конфигураций, включены принудительно;доступ — нужной группе.
Пользователь выбирает модель из списка, и у него уже всё настроено.
Обновление правил
Три пути, все работают вместе:
Автоматически раз в
REFRESH_INTERVALсекунд. Если коммит не сменился, индекс не пересобирается — проверка стоит несколько килобайт трафика.Из чата — инструмент
refresh_rulesс паролем. Нужен, когда только что выложили релиз и ждать час не хочется. Пароль спрашивается у человека, чтобы модель не запускала обновление сама.Перезапуском контейнера — индекс собирается заново при старте.
Индекс подменяется целиком и только после того, как новый успешно собран. Пока он строится, сервер продолжает отвечать на старом. Если забрать правила не удалось, старый индекс остаётся в работе.
Если что-то не работает
Симптом | Причина |
Open WebUI не видит сервер | Адрес |
Интерфейс виснет при добавлении | Выбран тип OpenAPI вместо MCP |
Соединение сразу рвётся | Авторизация «Bearer» с пустым ключом; нужна None |
Подключения слетают после пересоздания | Не задан |
«направлений: 0» | Не тот |
В ответах поле «внимание» | Не проходит обновление: протух токен, нет ветки, недоступна сеть. Текст ошибки там же |
Модель не зовёт инструменты | Вопрос к модели, а не к серверу. Проверьте на модели с надёжным вызовом инструментов |
Посмотреть, что сервер вообще отдаёт:
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С, деление пакета, параметры, временные таблицы и их зависимости. Тоже только стандартная библиотека, от индекса не зависит.
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.pytest_rules_index.py проверяет на настоящих правилах: направления распознаются с
учётом порядка сторон, ветки выгрузки не зовут несуществующих правил конвертации,
отбор регистрации разбирается, каскады не зацикливаются, справочники без своей
ветки выгрузки находятся через подчинённые правила.
test_reading.py — чтение и поиск: все крупные обработчики читаются страницами и
собираются знак в знак, номер строки из поиска годится для чтения, закомментированный
вызов правила в выдачу не попадает, многозначное имя правила даёт ошибку с перечнем,
а не молчаливый выбор. То же для обработчиков реквизитов: все читаются и
собираются, находятся по коду и по имени приёмника, повторяющееся имя приёмника
даёт ошибку с перечнем, поиск по ним отсеивает закомментированные строки.
Места вызовов правил в trace_document по всему корпусу указывают на живую
строку с вызовом и не теряют ни одного вызова; метки процессов ветки делятся
на свои и пришедшие без потерь; отбор поиска по имени объекта даёт то же, что
по кодам его правил.
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.102AGPL 3.0
- FlicenseNot gradedqualityAmaintenanceMCP server that validates AI-generated 1C:Enterprise (BSL) code against the real platform API. Catches unknown enum values, wrong argument counts, and missing type members by parsing the platform syntax-helper (shcntx_ru.hbk) — independent Rust implementation with built-in expression validator.24-
- 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