Skip to main content
Glama

bsl-ls-mcp

tests License: MIT Python Platform maintenance

MCP-обёртка над BSL Language Server для статического анализа и навигации по коду 1С (BSL). Один интерфейс наружу — инструменты mcp__bsl-ls__* для агентов и любых MCP-клиентов.

Статус проекта. Инструмент рабочий и используется в бою, но развивается по остаточному принципу: делюсь как есть. Активной поддержки, разбора issue и приёма правок в срок не обещаю — реагирую по возможности и без гарантий. Форки и адаптация под свои задачи только приветствуются.

Подробности (архитектура, сборка, все настройки, внутренняя механика) — в 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 ставить не надо.

Related MCP server: code-index-mcp

Запуск

Вариант 1. Бандл (собирается скриптом build.ps1)

Готового бандла в релизах нет — он собирается на машине с Python: build.ps1 кладёт в dist\bsl-ls-mcp\ Python и jar BSL LS (скачивает сам), а portable JRE 21 добавляется в dist\bsl-ls-mcp\jre\ отдельно — скрипт в конце подскажет, откуда взять. Дальше папка самодостаточна, на целевой машине:

:: 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 -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).

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 клиента (агентского пайплайна):

{ "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.

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

Везде, где инструмент просит имя — это строка с точками, как в ПолноеИмя() 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.

Тот же сценарий — из командной строки, без демона (так его зовёт хук CI):

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.

Available Tools

9 tools
bsl_calleesB

Кого вызывает функция (outgoing calls). full_name: 'ОбщийМодуль.МойМодуль.ИмяФункции'.

Inputs: full_name (required). Returns: result

bsl_callersB

Кто вызывает функцию. full_name: 'ОбщийМодуль.МойМодуль.ИмяФункции'. [{name, type, full_name, kind, способ}]: способ "вызов" — граф LSP (Модуль.Метод(...)); "строка" — имя метода строковым литералом ("Модуль.Метод" для ДлительныеОперации, ВыполнитьМетодКонфигурации, в переменной…), такие записи несут "строки" (номера); граф их не видит. Литерал сравнивается целиком без учёта регистра; комментарии не в счёт.

Inputs: full_name (required). Returns: result

bsl_complexityA

Сложность методов модуля (когнитивная + цикломатическая). Метрика ревьюеру. РОВНО ОДИН адрес: module_full_name — 'ОбщийМодуль.МойМодуль' | 'Отчет.Х' (все модули объекта) | форма; ИЛИ path — любой локальный .bsl или каталог: внешняя обработка, расширение тестов, выгрузка ревизии MR (full_name — имя модуля 1С, где его можно определить, иначе путь от path). function (опц.) — только этот метод или перечень через запятую; ненайденный метод — ошибка «метод не найден».

Inputs: path, function, module_full_name. Returns: result

bsl_definitionB

Где объявлен метод. full_name: 'ОбщийМодуль.МойМодуль.ИмяФункции'.

Inputs: full_name (required). Returns: result

bsl_diagnosticsA

Диагностики кода. Укажите РОВНО ОДИН адрес: module_full_name — модуль корпуса: 'ОбщийМодуль.МойМодуль' | 'Справочник.X.Форма.Имя'; path — любой локальный каталог или .bsl-файл (внешние обработки/отчёты, расширения), напр. 'C:\1c\work<задача>\Реализация'; UNC запрещён; text — СТРОКА кода 1С (снипет): линт до записи в файл. Обёртка в процедуру НЕ нужна (блок операторов линтуется как есть), нужна лишь синтаксическая завершённость (закрытые Если/Цикл, не оборванные выражения). Проверки ПОФАЙЛОВЫЕ, без контекста конфигурации (тип модуля/ссылки на объекты не проверяются). Для снипета по умолчанию возвращаются ВСЕ замечания (не только error+warning).

По умолчанию для module/path отдаёт полным списком только error+warning, а info/hint сворачивает в сводку suppressed.by_code (счётчики по кодам) — чтобы не переполнять бюджет на крупных модулях/формах (для text порог по умолчанию 'hint' — всё). Детали: code='Typo' (все по коду, любой severity) или min_severity='hint' (всё подряд). Зона правок — lines='2660-2781' | '10-20,35' (один файл цели) ИЛИ function='Метод[,Метод2]': только диагностики, начинающиеся в ней, ВСЕ уровни и без сворачивания; "источник".фильтр называет диапазоны (для function — найденные границы методов, от директив &… до Конец…). Источник ("источник".движок): код корпуса (module_full_name и path внутри workspace) — тёплый LSP, когда индекс готов: он видит метаданные конфигурации (тип модуля, объекты, реквизиты форм) — без ложных UnusedLocalMethod/UnusedLocalVariable в формах, с ExecuteExternalCodeInCommonModule, MissingCommonModuleMethod, UsingThisForm. Пока индекс строится (первый вызов, ~1–2 мин) — пакетный analyze без контекста конфигурации, сервер прогревается в фоне; "примечание" это называет. Код вне workspace и text — analyze. UnknownMember ненадёжен в обоих источниках (поля выборок, реквизиты регистров EDT) — не гейт. Возвращает {"diagnostics":[...], "suppressed":{"total":N,"by_code":[...]}, "источник":{"движок":"lsp"|"analyze", "примечание"?}}.

Inputs: code, path, text, lines, +3 more.

bsl_referencesC

Где используется метод. full_name: 'ОбщийМодуль.МойМодуль.ИмяФункции'.

Inputs: full_name (required). Returns: result

bsl_reindexA

Полный реиндекс корпуса — после изменений метаданных (новые объекты, реквизиты). Правки .bsl на диске (рабочая копия, коммиты, переключение ветки) сервер получает сам перед каждым запросом навигации и диагностик — для них реиндекс не нужен.

Inputs: no named parameters.

bsl_rules_checkA

Проверка правок задачи по правилам проекта (шаблоны и проверки кода: циклы и чтение базы, форма транзакции, параметры, служебный интерфейс чужих модулей и др.). Источник правок — РОВНО ОДИН: repo (git-репозиторий исходников — выгрузки конфигуратора или проекта EDT; base — коммит до задачи, по умолчанию точка ответвления от develop, иначе HEAD; rev — ревизия вместо рабочей копии) ИЛИ пара baseline + target (каталоги). Проверяются только строки задачи; новый файл — целиком. rules — реестр правил проекта (JSON; по умолчанию BSL_RULES; без реестра — встроенный каталог проверок). only — подмножество ид правил; paths — только эти пути задачи. Возвращает {"находки":[{ид, уровень, файл, строка, текст, регламент}], "исключены":[...], "пропущено":[{что, почему}], "база":{ревизия, как} — для repo}. Индекс LSP не используется.

Inputs: rev, base, only, repo, +4 more.

bsl_task_methodsB

Новые и изменённые методы задачи: [{файл, модуль, метод, вид, экспорт, строки, статус}], статус — «новый» (объявление добавлено задачей) или «изменён» (правка внутри метода). Источник правок — как у bsl_rules_check: repo (+ base, rev) ИЛИ baseline + target.

Inputs: rev, base, repo, paths, +2 more. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 9 tools

    Disambiguation3/5

    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.

    Naming Consistency4/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      A
      maintenance
      MCP 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.
      33
      -
    • A
      license
      Not graded
      quality
      A
      maintenance
      Rust-native code index MCP server with first-class 1C:Enterprise (BSL) support. Static binary, no runtime — 25 MCP tools (18 universal + 7 BSL-specific), tree-sitter AST for 10 languages, federation across multiple repos.
      161
      MIT
    • F
      license
      Not graded
      quality
      B
      maintenance
      MCP 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.
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables LLM agents to explore and search a 1C:Enterprise configuration codebase, including metadata objects, module procedures, call graphs, and semantic similarity search.
      4
      MIT