bsl-ls-mcp
# bsl-ls-mcp
[](https://github.com/Vladimirov-Maxim/bsl-ls-mcp/actions/workflows/ci.yml)
[](LICENSE)



MCP-обёртка над [BSL Language Server](https://github.com/1c-syntax/bsl-language-server)
для статического анализа и навигации по коду 1С (BSL). Один интерфейс наружу —
инструменты `mcp__bsl-ls__*` для агентов и любых MCP-клиентов.
> **Статус проекта.** Инструмент рабочий и используется в бою, но развивается по
> остаточному принципу: делюсь как есть. Активной поддержки, разбора issue и приёма
> правок в срок не обещаю — реагирую по возможности и без гарантий. Форки и адаптация
> под свои задачи только приветствуются.
> Подробности (архитектура, сборка, все настройки, внутренняя механика) — в
> [README_full.md](README_full.md). Здесь — только как запустить и что умеет.
## Что нужно
- Рабочая копия исходников 1С: выгрузка конфигуратора (каталог с `Configuration.xml`) или
проект EDT (каталог `<проект>\src` с `Configuration\Configuration.mdo`) — формат
определяется сам.
- ~14 ГБ свободной RAM — для навигации (граф держится в памяти). Диагностикам индекс
не нужен, им хватает ~2 ГБ на разовый вызов.
- Java 21+ (BSL LS 1.0.x) или собранный бандл с portable JRE: на машине, где он работает,
Python и Java ставить не надо.
## Запуск
### Вариант 1. Бандл (собирается скриптом `build.ps1`)
Готового бандла в релизах нет — он собирается на машине с Python: `build.ps1` кладёт в
`dist\bsl-ls-mcp\` Python и jar BSL LS (скачивает сам), а portable JRE 21 добавляется
в `dist\bsl-ls-mcp\jre\` отдельно — скрипт в конце подскажет, откуда взять. Дальше папка
самодостаточна, на целевой машине:
```bat
:: 1. указать путь к исходникам 1С (или отредактировать BSL_WORKSPACE в run.cmd)
set BSL_WORKSPACE=C:\1c\src\cf
:: 2. проверка — должно напечатать [selftest] OK
run.cmd --selftest
:: 3. запуск демона (streamable-http на :8081/mcp)
run.cmd
```
Как Windows-служба (автозапуск, авто-рестарт) — из-под администратора:
```powershell
powershell -ExecutionPolicy Bypass -File install-service.ps1 -Workspace "C:\1c\src\cf"
```
Для проекта EDT: `-Workspace "C:\Projects\git\<репозиторий>\<Проект>\src"`. Набор диагностик
фиксируется конфигом BSL LS: `-Config "<путь>\.bsl-language-server.json"`.
Управление — штатными средствами Windows (`Restart-Service bsl-ls-mcp`), полный реиндекс —
MCP-инструментом `bsl_reindex`. Состояние индекса — `%ProgramData%\bsl-ls-mcp\status.json`.
### Вариант 2. С исходников (нужны Python 3.10+ и Java 21+)
jar BSL LS в репозиторий не входит: его нужно положить в `server\` (или указать путь
в `BSL_LS_JAR`).
```powershell
py -3 -m pip install -e .
$jar = "bsl-language-server-1.0.7-exec.jar"
Invoke-WebRequest "https://github.com/1c-syntax/bsl-language-server/releases/download/v1.0.7/$jar" -OutFile "server\$jar"
$env:BSL_WORKSPACE = "C:\1c\src\cf"
bsl-ls-mcp --transport streamable-http --port 8081 # → http://127.0.0.1:8081/mcp
```
## Подключение к MCP-клиенту
В `.mcp.json` клиента (агентского пайплайна):
```json
{ "bsl-ls": { "type": "streamable-http", "url": "http://127.0.0.1:8081/mcp" } }
```
Первый вызов навигации подождёт индекс (~1.5 мин), дальше — мгновенно. Диагностики
доступны сразу (пока индекс строится — через пакетный analyze, см. поле `источник`).
Правки `.bsl` на диске сервер получает сам перед каждым запросом — реиндекс нужен только
после изменений метаданных.
> **Безопасность.** Демон не аутентифицирует вызовы и по умолчанию слушает только
> `127.0.0.1`. Не выставляйте порт в сеть без обратного прокси с авторизацией
> (`BSL_MCP_HOST=0.0.0.0` заблокирован без `BSL_ALLOW_REMOTE=1`). `path`-режим
> `bsl_diagnostics(path)` принимает любой локальный путь (UNC запрещён); пути проверок правок
> задачи ограничены `BSL_WORKSPACE` и `BSL_ALLOWED_ROOTS`. Подробнее — [SECURITY.md](SECURITY.md).
## Как устроено имя объекта
Везде, где инструмент просит имя — это строка с точками, как в `ПолноеИмя()` 1С:
```
Тип.Модуль → операции над модулем (диагностики)
Тип.Модуль.Метод → навигация по функции/процедуре
Тип.Объект.Форма.ИмяФормы → модуль формы (для диагностик)
```
Примеры: `ОбщийМодуль.ОбщегоНазначения`, `Справочник.Контрагенты.Форма.ФормаЭлемента`,
`ОбщийМодуль.ОбщегоНазначения.ЗначениеРеквизитаОбъекта`.
**Код вне корпуса** (внешние обработки/отчёты) адресуется не именем, а параметром
`path` — произвольный каталог или `.bsl`-файл; индексированный корпус для этого не нужен
(см. `bsl_diagnostics` ниже).
## Методы
| Инструмент | Что делает | Вход | Кому полезно |
|---|---|---|---|
| **`bsl_diagnostics`** | Проверка кода: ошибки, стиль, устаревшие конструкции. Блокирующий гейт «нельзя сдавать с ошибками». Код корпуса — из тёплого индекса с контекстом конфигурации (1–2 c), пока индекс строится — пакетный analyze. | `module_full_name` (`Тип.Модуль`/форма) **или** `path` (любой локальный каталог/файл) **или** `text`; зона правок — `lines="от-до"` или `function="Метод"` | developer (перед сдачей), reviewer |
| **`bsl_callers`** | Кто **вызывает** функцию — по всему корпусу, включая вызовы по строковому имени (`ДлительныеОперации`, `ВыполнитьМетодКонфигурации`: поле `способ`). Анализ влияния «кого заденет правка». | `Тип.Модуль.Метод` | analyst, architect, reviewer |
| **`bsl_callees`** | Кого **вызывает** функция (исходящие вызовы). От чего зависит метод. | `Тип.Модуль.Метод` | analyst, architect |
| **`bsl_definition`** | Где **объявлен** метод (переход к определению). | `Тип.Модуль.Метод` | все |
| **`bsl_references`** | Все **места использования** метода (со строкой кода). | `Тип.Модуль.Метод` | analyst, architect |
| **`bsl_complexity`** | **Сложность** методов модуля: когнитивная + цикломатическая. Сигнал «стоит упростить». | `Тип.Модуль` **или** `path` (любой локальный файл/каталог) [+ метод] | reviewer |
| **`bsl_reindex`** | Полный **реиндекс** корпуса in-place (после массовых изменений конфигурации). | — | обслуживание |
| **`bsl_rules_check`** | Проверка **правок задачи** по правилам проекта: шаблоны из реестра + проверки кода (чтение/запись базы в цикле, форма транзакции, параметры, служебный интерфейс чужих модулей и др.). Только строки задачи. Без индекса, секунды. | `repo` (+`base`, `rev`) **или** `baseline`+`target`; `rules` — реестр | developer, reviewer, хук CI |
| **`bsl_task_methods`** | Какие методы задача **добавила** и какие **изменила**. | `repo` (+`base`, `rev`) **или** `baseline`+`target` | analyst, reviewer |
### Что возвращают (коротко)
- **`bsl_diagnostics`** → `{diagnostics, suppressed}`. По умолчанию `diagnostics` — полный
список только `error`+`warning` (error первыми); стилевой шум `info`/`hint` свёрнут в
`suppressed.by_code` (счётчики по кодам, чтобы не раздувать ответ). Детали свёрнутого —
вызов с `code="Typo"`. Поле `file` точно указывает модуль (менеджер/объект/форма), а для
кода вне корпуса — путь файла относительно переданного `path`.
Адрес — **ровно один** из двух:
```
bsl_diagnostics(module_full_name="ОбщийМодуль.МойМодуль") # модуль корпуса
bsl_diagnostics(path=r"C:\1c\work\<задача>\Реализация") # внешняя обработка (с описанием форм)
bsl_diagnostics(path=r"...\ObjectModule.bsl") # один файл
```
- **`bsl_callers` / `bsl_callees`** → список `{name, type, full_name, kind}` —
`full_name` можно сразу подать в другой инструмент.
- **`bsl_definition` / `bsl_references`** → список `{type, module, full_name, line, text}` —
`line` 1-based, `text` — сама строка кода.
- **`bsl_complexity`** → список `{full_name, cognitive, cyclomatic}`.
- **`bsl_rules_check`** → `{"находки": [{ид, уровень, файл, строка, текст, регламент}],
"исключены": [...], "пропущено": [{что, почему}]}`. Что не удалось выполнить (правило без
реализации, регулярка не компилируется), названо в `пропущено` — «чисто» при пропусках не
бывает.
- **`bsl_task_methods`** → `[{файл, модуль, метод, вид, экспорт, строки, статус}]`,
`статус` — «новый» или «изменён».
Имена в ответах — русские (как у 1С).
## Проверка правок задачи по правилам проекта
`bsl_rules_check` смотрит **только строки задачи**: изменённые и добавленные строки по
`git diff -U0 <base>`, новый файл — целиком. Вендорский код рядом задаче не вменяется.
Источник правок — git-репозиторий выгрузки или пара каталогов «эталон / копия» (внешние
обработки, без git). Индекс LSP не нужен.
**Правила — данные проекта, а не код инструмента.** Реестр правил (`JSON`) живёт у проекта и
передаётся путём (`rules` или `BSL_RULES`). В нём два вида правил:
- **шаблон** — регулярка + область строки (код без литералов, литерал запроса, комментарий…)
+ примеры `ловит`/`не_ловит`;
- **код** — ссылка на проверку инструмента по её ключу (`"реализация": "loop.db-read-via-call"`);
номер, уровень, текст и пункт регламента — проекта, их можно менять, не трогая инструмент.
Без реестра работают все проверки кода с нейтральными текстами (ид = ключ). Формат реестра,
каталог ключей и области шаблонов — в [README_full.md](README_full.md#проверка-правок-задачи).
Тот же сценарий — из командной строки, без демона (так его зовёт хук CI):
```powershell
bsl-ls-mcp rules-check --repo C:\1c\src\cf --base <коммит-до-задачи> --rules правила.json --json
bsl-ls-mcp task-methods --repo C:\1c\src\cf --base <коммит-до-задачи>
bsl-ls-mcp diagnostics --repo C:\1c\src\cf --base <коммит-до-задачи> --bsl-config .bsl-language-server.json --json
```
`diagnostics` — диагностики BSL LS (error → Fail, warning → Warn) только по строкам задачи, в том же
формате, что `rules-check`: гейт «ноль error» для хуков и CI без демона.
Код возврата `rules-check` и `diagnostics`: 0 — нарушений уровня Fail нет, 1 — есть, 2 — ошибка входа.
## Поведение
- **Первый вызов навигации** после старта ждёт индексацию (~1.5 мин на боевом корпусе),
дальше — доли секунды. **Диагностики индекс не ждут** — отрабатывают всегда за ~5–8 c.
- **Свежесть:** правки на диске видны без перезапуска (навигация — по `didChange`,
диагностики читают файл заново).
- **Имя не разрешилось** → понятная ошибка; **нет результатов** → пустой список.
Полная документация по параметрам, переменным окружения и устройству — в
[README_full.md](README_full.md).
TDQS
Scored across 9 tools
Most tools are clearly distinct (callees vs callers vs definition vs complexity vs diagnostics vs rules_check). However, bsl_callers ('who calls a function') and bsl_references ('where a method is used') have overlapping purpose, and the descriptions do little to delineate the boundary between them beyond callers mentioning string literals. An agent could plausibly pick either tool for the same question.
All tools use a consistent 'bsl_' prefix and snake_case (bsl_callees, bsl_definition, bsl_rules_check, bsl_task_methods). There is a minor mix of verb-style (bsl_reindex) and noun-style names, but overall the convention is predictable.
Nine tools is well within the ideal range and each maps to a distinct navigation, diagnostics, or review-lifecycle capability. Nothing feels redundant or padded for a language-server MCP.
The surface covers navigation (definition/references/callers/callees), diagnostics, complexity, reindexing, and task-oriented rules/method review — a strong coverage of the code-review domain. Minor gaps remain (no document-symbol/outline or type/hover lookup), which agents can work around but would occasionally want.