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. Готовый бандл (рекомендуется)
Папка `dist\bsl-ls-mcp\` самодостаточна (внутри Python и Java). На целевой машине:
```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\bf_edt\BF\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+)
```powershell
py -3 -m pip install -e .
$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`** | **Сложность** методов модуля: когнитивная + цикломатическая. Сигнал «стоит упростить». | `Тип.Модуль` [+ метод] | 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 <коммит-до-задачи>
```
Код возврата `rules-check`: 0 — нарушений уровня Fail нет, 1 — есть, 2 — ошибка входа.
## Поведение
- **Первый вызов навигации** после старта ждёт индексацию (~1.5 мин на боевом корпусе),
дальше — доли секунды. **Диагностики индекс не ждут** — отрабатывают всегда за ~5–8 c.
- **Свежесть:** правки на диске видны без перезапуска (навигация — по `didChange`,
диагностики читают файл заново).
- **Имя не разрешилось** → понятная ошибка; **нет результатов** → пустой список.
Полная документация по параметрам, переменным окружения и устройству — в
[README_full.md](README_full.md).
TDQS
Scored across 7 tools
Most tools target clearly distinct aspects: complexity, definition, callees, callers, diagnostics, and reindex. However, bsl_references ('where the method is used') and bsl_callers ('who calls the function') could be confused as overlapping in purpose, even though callers is more specific to incoming calls.
All tool names use a consistent bsl_ prefix followed by a single descriptive concept in lowercase snake_case (e.g., bsl_complexity, bsl_definition, bsl_callers). The pattern is predictable and uniform across the set.
Seven tools is well-scoped for a language server focused on navigation, call analysis, diagnostics, and indexing. Each tool earns its place without redundancy or excessive breadth.
The surface covers core navigation (definition, references), call hierarchy (callers/callees), complexity, diagnostics, and reindexing. Minor gaps exist, such as direct module content retrieval or symbol search, but these are not critical for the stated purpose.