Bsl Context
БесплатноНе проверенMCP server that validates AI-generated 1C:Enterprise (BSL) code against the real platform API. Catches unknown enum values, wrong argument counts, and missing t
Описание
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.
README
Русский | English
Published on Infostart: bsl-context — проверка ИИ-кода 1С на соответствие API платформы
An MCP server providing 1C:Enterprise 8.3 platform context: types, methods, properties, constructors, system enumeration values — plus static validation of BSL expressions against a real platform index.
The data source is the platform's syntax assistant (shcntx_ru.hbk), parsed by a
custom reader (running 1C is not required).
Why
Language models and linters handle BSL syntax well but are "blind" to referential
correctness against the platform: whether a system enumeration value exists,
whether a platform type has a given method, whether a global function's argument
count fits its overloads. bsl-context covers exactly that layer — it checks code
against the actual API of a specific platform version.
Features
Reference tools — search and details for platform types, methods, properties, constructors, and enumeration values.
Module/fragment validation (validate_module) — accepts either a whole
module or an arbitrary fragment; via tree-sitter-bsl the server
extracts Процедура/Функция declarations from the submitted text and does
not treat their calls as typos of platform methods (for a fragment this set is
simply empty); it also validates compiler/extension directive names. Returns
findings with line, column, kind, and confidence:
| Finding kind | confidence | Meaning |
|---|---|---|
unknown_enum_value |
high | System enumeration value does not exist |
wrong_argument_count |
high | Global function argument count outside its overloads |
unknown_type_member |
low | Platform type has no such method/property |
unknown_new_type |
low | Новый TypeX constructor unknown to the platform |
unknown_global_method |
high / low | Unknown global call similar to a platform method (fuzzy: strong match → high, weak → low) |
undeclared_method |
high | Call is not declared in the submitted module and unknown to the platform (whole-module check only; suppressed in extension modules) |
unknown_directive |
high / low | Directive name (&НаСервере, &Перед, …) not in the whitelist |
shadowed_context_name |
high | Variable name is taken by a read-only context property: the assignment fails at runtime. The form-member rule needs module_path |
high-confidence findings have a false-positive rate near zero; low-confidence ones
depend on the accuracy of type inference and the completeness of the hbk.
Validation levels
Analysis depth is set via the level parameter (or default_validation_level in
the config), clamped to [1..=3]:
- 1 — references with an explicit type name in the source (
Новый TypeX,TypeY.ValueZ, global function argument counts). Low noise, safe default. - 2 — additionally, local type inference within a procedure:
X = Новый TypeX,X = TypeY.ValueZ, the// @type TypeXannotation. - 3 — additionally, return-type tracking: a variable's type from the return
type of a method/property, including chains like
Query.Execute().Select().
The higher the level, the more findings — and the more potential false positives.
What the validator cannot know
The validator sees the text of a SINGLE module plus the platform context. It
does not know the configuration's metadata, so it cannot verify that
application procedures declared in other modules exist. The undeclared_method
finding is suppressed when the name may come from outside:
- an ordinary (non-managed) form module calls its owner's object module export methods without a prefix;
- an extension module calls procedures of the module it extends (such a module
is recognized by the
&Перед,&После,&Вместо,&ИзменениеИКонтрольdirectives, and strict checking is disabled for it); - a global common module (
Глобальный = Истина) is called without a prefix from any module.
The first and third cases cannot be recognized from the module text alone —
false positives for undeclared_method are possible there. The strict
profile will not filter them out (the finding has high confidence); when
working with such modules it's better not to rely on this finding.
Likewise, the validator does not know the form's set of attributes. An attribute
shadows a context name (UT has forms with attributes named Метаданные,
БезопасноеХранилище), so inside a form module the shadowed_context_name
finding for global-context names is off by default. Pass the attribute list via
form_attributes and it works there too: attribute names are excluded, the rest
are checked.
Profiles
The profile parameter (or default_profile in the config):
full(default) — all findings,levelas passed. For a strong model that discards questionable findings itself.strict— only high-confidence findings and a forcedlevel=1. For weaker models, so a false positive does not cause a feedback loop.
Architecture
A Cargo workspace of five crates:
| Crate | Purpose |
|---|---|
hbk-reader |
Reads the binary shcntx_ru.hbk container |
hbk-parser |
Parses help HTML pages (types, methods, enumerations) |
platform-index |
Platform index: loading, storage, search |
bsl-validator |
BSL expression validator (tree-sitter) |
server |
HTTP MCP server (axum + rmcp), config, PID lock |
Requirements
- Rust (edition 2021), built with
cargo build --release. - The
shcntx_ru.hbkfile from an installed 1C:Enterprise platform (C:\Program Files\1cv8\<version>\bin\shcntx_ru.hbk). Not included in the repo.
Build
cargo build --release
The binary is target/release/bsl-context-rs (.exe on Windows).
Configuration
Copy configs/config.toml.example to
configs/config.toml and adjust it for your machine. Key fields:
host = "127.0.0.1" # bind, loopback by default
port = 8007 # MCP server port
platform_path = 'C:\Program Files\1cv8\8.3.27.1786' # platform version directory
default_validation_level = 1
Choosing the platform version when several are installed
If multiple platform versions are installed side by side, the server does not
pick a version automatically — the path is set explicitly via platform_path.
Inside that directory it looks for shcntx_ru.hbk at two paths:
<platform_path>/shcntx_ru.hbk and <platform_path>/bin/shcntx_ru.hbk.
This is deliberate: method signatures and the set of system enumerations differ
between platform versions, so code must be validated against the version it is
written for. If platform_path is unset, the server starts and /health
responds, but the MCP tools return 503 with a hint to set the path.
Network deployment
By default the server listens on loopback. With host = "0.0.0.0" you must add
the external address to allowed_hosts (rmcp's DNS-rebinding protection),
otherwise networked requests get 403 Forbidden: Host header is not allowed:
allowed_hosts = ["localhost", "127.0.0.1", "::1", "<server-ip>"]
External source of configuration names
The validator receives the text of a SINGLE module, so a call to a procedure declared in another file of the configuration looks like a typo to it. A symbol source fixes that: it answers three questions — "does the configuration declare such a method", "is it an exported method of a GLOBAL common module", and "which exported methods does the owner object module of an external data processor have".
Measured on the UT configuration (14905 modules): without a source — 1420 high-confidence
undeclared_method findings; with one — 44, of which exactly one is real.
Three ways to connect it, same result:
# 1. Own lightweight index. The server stays self-contained.
[symbol_source]
kind = "lite"
root = 'C:\RepoUT' # configuration dump directory
db_path = 'C:\tools\bsl-context\ut_lite.db' # database file; the directory is created for you
The database is built by the rebuild_symbol_index tool — call it after the first start
and after every change to the configuration. It takes no parameters: the paths come from
the config. While it runs, validation keeps using the previous database; if the build
fails, the previous database stays intact. The same can be done from the command line:
bsl-lite-index build --root <dump> --db <file.db> (the directory must already exist).
# 2. Reading the code-index database directly (same machine only).
[symbol_source]
kind = "code_index_db"
db_path = 'C:\RepoUT\.code-index\index.db'
# 3. Through a running code-index service — any machine, by address and port.
[symbol_source]
kind = "code_index_mcp"
url = "http://127.0.0.1:8011/mcp"
repo = "ut"
timeout_ms = 5000
With no section (or kind = "none") the validator behaves as before, knowing nothing
about the configuration.
How they differ. lite needs nothing external and answers from memory, but its database
must be rebuilt after the configuration changes. The code-index sources read from that
index instead — if a file watcher keeps it current, the names are always fresh. The
"global common module" flag is taken from the module's XML, which code-index stores verbatim.
They also differ in speed. Measured on a 261,548-function index: a direct SQLite lookup
takes 13 µs (142 ns once the names are held in memory), a networked code-index request
13.4 ms. The validator checks hundreds of calls per module, so prefer lite or
code_index_db; use code_index_mcp when the index lives on another machine.
Several configurations on one server
One server can serve several configurations at once, each with its own access method.
Instead of the single [symbol_source] section, list them:
[[symbol_sources]]
repo = "ut" # configuration alias — this is the tools' `repo` argument
kind = "lite"
root = 'C:\RepoUT'
db_path = 'C:\tools\bsl-context\ut_lite.db'
[[symbol_sources]]
repo = "bp"
kind = "code_index_db"
db_path = 'C:\RepoBP\.code-index\index.db'
[[symbol_sources]]
repo = "zup"
kind = "code_index_mcp"
url = "http://10.0.0.5:8011/mcp"
code_index_repo = "zup-prod" # optional: only when code-index names that repository differently
validate_module and rebuild_symbol_index then take a repo argument — that alias.
It is required whenever at least one configuration is configured, even a single one:
a call must be unambiguous. An unknown alias is refused with the list of available ones.
[symbol_source] and [[symbol_sources]] are mutually exclusive.
With no configuration set up at all the argument is not needed: code is checked against the platform reference only.
What happens when a symbol source is unavailable
A source that answers "no such method" to everything is worse than no source at all: the
validator turns that into a high-confidence undeclared_method finding on every single
procedure call. Hence:
- On connect, a
code_index_mcpsource askscode-indexfor the stats of its own repository. Ifcode-indexdoes not know it, the source is not created and the log gets an explicit error listing the available repositories. - A configuration is declared but its source failed to come up —
validate_modulefor that alias refuses and explains why (forlite: "index not built, callrebuild_symbol_index") instead of emitting findings that are certainly false. - A source dies mid-flight (network,
code-indexdown) — it is marked unhealthy, the empty answer is not cached, and validation for that configuration refuses until recovery.
Tool whitelist
If you only need part of the server's surface, list the tools you want in the
[tools] section. For example, module validation plus two lookup helpers:
[tools]
enabled = ["validate_module", "get_constructors", "get_enum_values"]
A missing section or an empty list means all eleven tools are available, as before.
Hidden tools are absent from tools/list and are rejected on a direct call.
An unknown name does not break startup: it produces a warning in the log and the
tool simply never appears.
Running
bsl-context-rs --config /path/to/config.toml
Healthcheck — GET http://127.0.0.1:8007/health (no MCP handshake required).
MCP tools
Transport — Streamable HTTP at http://127.0.0.1:8007/mcp (stateless).
| Tool | Purpose |
|---|---|
search |
Fuzzy search across types, global methods, properties |
info |
Details by exact name |
get_member |
A specific method/property of a type |
get_members |
All members of a type (methods + properties + enum values) |
get_constructors |
A type's constructors with signatures |
get_enum_values |
Values of a system enumeration |
validate_enum |
Validate an enumeration value |
validate_method_call |
Validate a global function's argument count |
validate_module |
Validate BSL code (whole module or fragment) against the platform |
rebuild_symbol_index |
Rebuild the own name index (kind = "lite"); paths come from the config |
reserved_names |
Context-occupied names from the platform help: global_readonly/form_readonly (assignment fails at runtime), global_writable/form_writable (no variable is created — the session or the form is silently changed) |
Connecting an MCP client
{
"mcpServers": {
"bsl-context": {
"type": "http",
"url": "http://127.0.0.1:8007/mcp"
}
}
}
Changelog
See CHANGELOG.md (in Russian).
License
MIT.
Установка Bsl Context
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/Regsorm/bsl-contextFAQ
Bsl Context MCP бесплатный?
Да, Bsl Context MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Bsl Context?
Нет, Bsl Context работает без API-ключей и переменных окружения.
Bsl Context — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Bsl Context в Claude Desktop, Claude Code или Cursor?
Открой Bsl Context на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Bsl Context with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
