Skip to main content
Glama
README.md
# bsl-ls-mcp

[![tests](https://github.com/Vladimirov-Maxim/bsl-ls-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/Vladimirov-Maxim/bsl-ls-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
![Python](https://img.shields.io/badge/python-3.10%2B-blue)
![Platform](https://img.shields.io/badge/platform-Windows-informational)
![maintenance](https://img.shields.io/badge/maintenance-as--is-yellow)

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С в формате CR-выгрузки (каталог `src/cf`).
- ~14 ГБ свободной RAM — для навигации (граф держится в памяти). Диагностикам индекс
  не нужен, им хватает ~2 ГБ на разовый вызов.
- Java 17+ или готовый бандл с 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"
```
Удобный пультик к службе (лампочка статуса + старт/стоп/переиндекс) — `bsl-ls-tray.exe`.

### Вариант 2. С исходников (нужны Python 3.10+ и Java 17+)

```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 мин), дальше — мгновенно. Диагностики
доступны сразу.

> **Безопасность.** Демон не аутентифицирует вызовы и по умолчанию слушает только
> `127.0.0.1`. Не выставляйте порт в сеть без обратного прокси с авторизацией
> (`BSL_MCP_HOST=0.0.0.0` заблокирован без `BSL_ALLOW_REMOTE=1`). `path`-режим
> ограничен `BSL_WORKSPACE` и `BSL_ALLOWED_ROOTS`. Подробнее — [SECURITY.md](SECURITY.md).

## Как устроено имя объекта

Везде, где инструмент просит имя — это строка с точками, как в `ПолноеИмя()` 1С:

```
Тип.Модуль                  → операции над модулем (диагностики)
Тип.Модуль.Метод            → навигация по функции/процедуре
Тип.Объект.Форма.ИмяФормы   → модуль формы (для диагностик)
```
Примеры: `ОбщийМодуль.ОбщегоНазначения`, `Справочник.Контрагенты.Форма.ФормаЭлемента`,
`ОбщийМодуль.ОбщегоНазначения.ЗначениеРеквизитаОбъекта`.

**Код вне корпуса** (внешние обработки/отчёты) адресуется не именем, а параметром
`path` — произвольный каталог или `.bsl`-файл; индексированный корпус для этого не нужен
(см. `bsl_diagnostics` ниже).

## Методы

| Инструмент | Что делает | Вход | Кому полезно |
|---|---|---|---|
| **`bsl_diagnostics`** | Проверка кода: ошибки, стиль, устаревшие конструкции. Блокирующий гейт «нельзя сдавать с ошибками». Работает без индекса, ~5–8 c. | `module_full_name` (`Тип.Модуль`/форма) **или** `path` (каталог/файл вне корпуса) | 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_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"...\Ext\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}`.

Имена в ответах — русские (как у 1С).

## Поведение

- **Первый вызов навигации** после старта ждёт индексацию (~1.5 мин на боевом корпусе),
  дальше — доли секунды. **Диагностики индекс не ждут** — отрабатывают всегда за ~5–8 c.
- **Свежесть:** правки на диске видны без перезапуска (навигация — по `didChange`,
  диагностики читают файл заново).
- **Имя не разрешилось** → понятная ошибка; **нет результатов** → пустой список.

Полная документация по параметрам, переменным окружения и устройству — в
[README_full.md](README_full.md).

TDQS

A3.7/5.0

Scored across 7 tools

Disambiguation5/5

Every tool targets a distinct language-server operation: incoming calls, outgoing calls, declaration lookup, usage lookup, diagnostics, complexity metrics, and index rebuilding. The inverse pairs callers/callees and definition/references are clearly separated by their descriptions, so an agent is unlikely to confuse them.

Naming Consistency4/5

All tools share the consistent bsl_ prefix and snake_case convention, and most are noun-style operations such as bsl_callers, bsl_definition, and bsl_diagnostics. The main deviation is bsl_reindex, which reads as an imperative action rather than a noun, but the overall pattern remains predictable.

Tool Count5/5

Seven tools is well-scoped for a BSL code-intelligence server: four navigation tools, two code-analysis tools, and one index-maintenance command. Each tool earns its place, and the set is neither too thin nor overloaded.

Completeness4/5

The toolset covers the main analysis workflow: callers/callees for call-graph navigation, definition/references for symbol lookup, diagnostics for linting, complexity for maintainability review, and reindex for keeping the index fresh after large changes. A direct symbol-search or module-outline tool is missing, but the complexity tool can enumerate module methods, so the gap is minor and workaroundable.

Maintenance

ActivityMaintained
ResponsivenessNo issues