onec-meta-mcp
by gsbelarus
README.md
# 1C Meta MCP
MCP-сервер на Node.js для поиска по метаданным конфигурации 1С и коду BSL. В проекте нет нативных модулей и обязательного Docker: достаточно Node.js >= 22.13, потому что используется встроенный `node:sqlite`.
## Что нужно выгрузить из 1С
Сервер загружает данные из двух источников, и нужны оба:
1. `metadata/*.txt` — один текстовый файл `Отчет по конфигурации`.
2. `code/` — полная XML-выгрузка конфигурации в файлы.
Без TXT-отчета не загрузятся паспорт конфигурации, список объектов, реквизиты, табличные части, формы, команды и полнотекстовый поиск по описаниям. Без XML-выгрузки не будет GUID, движений по регистрам, прав ролей, предопределенных данных, состава подсистем и исходников BSL.
### Как именно выгрузить данные из 1С
Делайте выгрузку из конфигуратора 1С для той конфигурации, по которой хотите искать.
1. Откройте базу в режиме `Конфигуратор`.
2. Сформируйте `Отчет по конфигурации` в текстовый файл. Обычно это меню `Конфигурация -> Отчет по конфигурации...`.
3. Сохраняйте полный отчет, а не выборочный.
4. Убедитесь, что файл сохранен в текстовом формате Unicode UTF-16LE с BOM.
5. Положите этот файл в папку `metadata/`.
6. Выполните команду `Выгрузить конфигурацию в файлы`. Обычно это меню `Конфигурация -> Выгрузить конфигурацию в файлы...`.
7. В качестве каталога выгрузки укажите папку `code/`.
8. Нужна полная выгрузка, чтобы внутри оказались XML-описания объектов, каталоги модулей и `.bsl`-файлы в `Ext/`.
Практически это должно выглядеть так:
```text
prj1/
metadata/
ОтчетПоКонфигурации.txt
code/
ConfigDumpInfo.xml
Configuration.xml
Catalogs/
Documents/
CommonModules/
Roles/
Subsystems/
EventSubscriptions/
...
```
Сервер ожидает именно такую структуру относительно `DATA_DIR`:
```text
DATA_DIR/
metadata/
*.txt
code/
ConfigDumpInfo.xml
Configuration.xml
... XML и BSL-выгрузка конфигурации ...
```
Требования к данным:
- В `metadata/` должен лежать ровно один `.txt`-файл с отчетом по конфигурации. Имя файла может быть любым.
- В `code/` должна быть полная файловая выгрузка, а не отдельные выборочные каталоги.
- Для загрузки BSL в `code/` должны присутствовать модули вида `Ext/*.bsl`, формы `Forms/*/Ext/Form/Module.bsl`, командные модули и общие модули.
- Для прав ролей нужны файлы `Roles/*/Ext/Rights.xml`.
- Для предопределенных элементов используются `Ext/Predefined.xml` у соответствующих объектов.
Если ваши данные лежат не в `./prj1`, просто укажите правильный путь в `DATA_DIR`.
## Быстрый старт
```powershell
npm install
$env:DATA_DIR = 'C:\Golden\Andersen\1c-meta-mcp\prj1'
npm run dev
```
На первом запуске сервер загружает выгрузку в SQLite, после чего поднимает MCP-эндпоинт `http://localhost:6101/mcp` и UI со статусом загрузки на `http://localhost:6102`.
Полезные команды:
- `npm run dev` — загрузить данные при необходимости и запустить MCP-сервер.
- `npm run load` — только выполнить загрузку и завершиться.
- `npm run serve` — то же поведение, что и `npm run dev`.
- `npm run parity` — сравнить ответы с оригинальным сервером.
- `npm test` — запустить тесты.
Пример конфигурации MCP-клиента:
```json
{
"mcpServers": {
"onec-meta": {
"url": "http://localhost:6101/mcp",
"type": "streamable-http"
}
}
}
```
## Docker
Для `docker compose` подготовьте выгрузку, например так:
```text
data/
prj1/
metadata/
ОтчетПоКонфигурации.txt
code/
ConfigDumpInfo.xml
Configuration.xml
...
```
Дальше:
```bash
docker compose up -d
docker compose logs -f
```
Контейнер монтирует выгрузку 1С в `/data` только на чтение, а SQLite хранит в именованном volume `onec_db_prj1`, поэтому база переживает перезапуск контейнера и обновление образа.
Повторная загрузка после изменения конфигурации:
```bash
FULL_RELOAD=true docker compose up -d --force-recreate
```
Альтернатива — удалить volume с базой и поднять контейнер заново. Для нескольких конфигураций продублируйте сервис в `docker-compose.yml` и задайте отдельные `PROJECT_NAME`, `DATA_DIR`, volume и порт.
Образ основан на `node:22-slim`, запускает TypeScript через `tsx`, использует `tini` как PID 1 и проверяет готовность через `tools/list` по MCP.
## Переменные окружения
| Переменная | По умолчанию | Значение |
|---|---|---|
| `DATA_DIR` | `../prj1` | Корневая папка данных, внутри которой должны быть `metadata/*.txt` и `code/` |
| `PROJECT_NAME` | `prj1` | Метка проекта в qualified names |
| `DB_PATH` | `./onec-meta.db` | Путь к SQLite-базе |
| `MCP_HOST` | `0.0.0.0` | Хост MCP-сервера |
| `MCP_PORT` / `MCP_PATH` | `6101` / `/mcp` | HTTP-эндпоинт MCP |
| `UI_PORT` / `UI_ENABLED` | `6102` / `true` | Веб-панель статуса загрузки и индексации |
| `FULL_RELOAD` | `false` | Принудительно перезагрузить проект, даже если отпечаток TXT-отчета не изменился |
| `LOAD_BSL` | `true` | Загружать модули BSL |
| `LOAD_RIGHTS` | `true` | Загружать права ролей из `Rights.xml` |
| `LOAD_PREDEFINED` | `true` | Загружать предопределенные данные из `Predefined.xml` |
| `CHECKS_DIR` | `./checks` | Папка с YAML-наборами SQL-проверок |
| `ENABLE_ROUTINE_EMBEDDING` / `ENABLE_METADATA_EMBEDDING` | `false` / `false` | Включить семантический индекс для кода и метаданных |
| `EMBEDDING_API_BASE` | `http://localhost:1234/v1` | OpenAI-совместимый endpoint для эмбеддингов |
| `EMBEDDING_MODEL` | `text-embedding-qwen3-embedding-0.6b` | Модель эмбеддингов |
| `HYBRID_FT_WEIGHT` / `HYBRID_VEC_WEIGHT` | `0.3` / `0.7` | Веса гибридного поиска |
## Что умеет сервер
### Фазы 1-2: TXT-отчет
- `get_config_passport` — имя, версия, поставщик и счетчики объектов конфигурации.
- `list_categories`, `list_objects` — обзор объектов с фильтром по происхождению.
- `get_object_structure` — реквизиты, ресурсы, измерения, табличные части, формы и значения перечислений.
- `find_object_usages` — кто использует объект как тип.
- `search_metadata_by_description` — полнотекстовый поиск FTS5 по имени, синониму и комментарию.
- `run_sql_readonly` — защищенный `SELECT` по SQLite для аналитики и проверок.
### Фаза 3: XML-выгрузка
- `find_register_movements` — связи документы ↔ регистры.
- `list_predefined` — предопределенные элементы, включая иерархию плана счетов и флаги.
- `get_subsystem_content` — состав подсистем и принадлежность объектов.
- `list_event_subscriptions` — подписки на события, источник, событие и обработчик.
- `get_role_rights` — права ролей по объектам.
- `find_by_guid` — поиск объекта по UUID.
### Фаза 4: код BSL
- `search_code` — поиск по именам процедур и функций, doc-comment и фильтрам.
- `grep_code` — поиск по телам процедур и функций с номерами строк.
- `get_routine` — исходник процедуры или функции по `routine_id` либо `name + owner`.
- `list_routines` — список процедур и функций модуля с метриками.
- `get_call_graph` — вызывающие и вызываемые процедуры, глубина 1-10.
Загрузка возобновляемая: прогресс хранится по фазам в таблице `load_phases`, поэтому после прерывания сервер продолжает с места остановки. Полная перезагрузка выполняется при `FULL_RELOAD=true` или при изменении TXT-отчета.
## Семантический поиск
`search_code` и `search_metadata_by_description` поддерживают `mode: fulltext | semantic | hybrid`. Если эмбеддинги отключены, используется полнотекстовый режим.
Минимальная конфигурация:
```text
ENABLE_ROUTINE_EMBEDDING=true
ENABLE_METADATA_EMBEDDING=true
EMBEDDING_API_BASE=http://localhost:1234/v1
EMBEDDING_MODEL=text-embedding-qwen3-embedding-0.6b
```
Индексация запускается в фоне после старта сервера. Векторы хранятся в той же SQLite-базе, а смена модели автоматически запускает переиндексацию.
## Проверки соответствия
`list_checks` и `run_checks` выполняют SQL-проверки из `checks/*.yaml`. Каждое правило описывает идентификатор, заголовок, уровень серьезности, категорию и read-only SQL-запрос, строки которого трактуются как нарушения.
Стартовый набор `checks/1c-standards.yaml` включает проверки на:
- префиксы именования кастомных объектов;
- экспортные процедуры без doc-comment;
- слишком длинные процедуры и функции;
- использование `Выполнить()`;
- использование `ВЫБРАТЬ *`;
- отсутствие структуры `#Область`;
- TODO-маркеры;
- административные и интерактивные права удаления;
- неиспользуемые экспортные процедуры;
- доступ к БД на клиенте в формах.
Для новых правил удобно сначала отладить SQL через `run_sql_readonly`, а затем сохранить запрос в YAML-пакет.
## Паритет с оригинальным сервером
`npm run parity` запускает набор сравнительных запросов из `test/parity.ts` против оригинального сервера и этого клона. Результат сохраняется в `test/parity-report.json`. Оба сервера должны быть подняты с одной и той же загруженной конфигурацией.
Известные допустимые расхождения:
- наборы реквизитов могут немного отличаться из-за стандартных реквизитов;
- ранжирование кодового поиска может отличаться между Lucene-подобным поиском и SQLite FTS5 BM25;
- граф вызовов может немного различаться из-за эвристик динамических вызовов.
Результат запуска от 2026-06-08: `13 exact / 1 ranking-info / 3 reference-server bugs / 0 clone defects`.
## Статус
Реализованы фазы 1-4: загрузка TXT-отчета, XML-объектов и кода BSL, права ролей, подписки, предопределенные данные, граф вызовов и инструменты поиска.
Фазы 5-7 требуют отдельной проверки в вашей среде:
```bash
npm install
npx tsc --noEmit
npm run parity
```
Для проверок соответствия можно начать с быстрого smoke-теста через `run_checks` и одно правило, а для семантического поиска — поднять LM Studio или другой OpenAI-совместимый endpoint и отслеживать `get_semantic_index_status`.
## Ограничения
- стандартные реквизиты хранятся в `properties_json`, а не отдельными строками в таблице полей;
- внутренности `Form.xml` уровня контролов, событий и привязок пока не загружаются;
- детали HTTP-сервисов и web-service operations отложены на следующую фазу;
- тексты RLS-условий загружаются только там, где они присутствуют в `Rights.xml`.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing