Skip to main content
Glama

1C配置结构MCP服务器

tests license python

多个1C配置的元数据参考手册、平台语法参考和查询语言参考——面向编写BSL代码的代理。提供最小但足够的切片:将人类表述解析为精确的对象名称、在代码导出中搜索现成过程、其签名、受限的过程体窗口以及来自调用、元数据和表单的反向关联、按所需详细程度展示对象结构、其关联、平台方法的描述并考虑具体配置的版本以及查询语言结构。

不能替代对项目工作源码的grep:服务器只在已加载的配置导出文件中搜索过程,看不到未加载的修改。来源边界在docs/data-sources.md中固定。

状态——截至2026-08-21

阶段

状态

1C导出处理

✅ 20种元数据,8.3.5和8.3.23,XML和JSON

导出格式

✅ schema v1

加载器、模型、关联图、渲染

✅ 5个配置,20 522个对象,322千条边

平台帮助

✅ 三个版本的合并索引,25 691个元素,since/until边界

查询语言

✅ shquery_ru.hbk,127页,无版本的独立来源

搜索

✅ 97.1%帮助,94.7%查询语言,90.5%元数据——见「已测量」

寄存器虚拟表

✅ 现成的查询字段名(КоличествоОстаток)

旧平台替换表

✅ 不可用的内容不只是被禁止,而是被替换为方案

来源注册表、版本映射

✅

MCP服务器,10个工具

✅ streamable-http和stdio

Docker

✅ 单容器,357MB(按Docker CLI输出)

搜索索引缓存

✅ 12 MB,替代重复解析启动

测量台架

✅ python -m mcp1c.bench,P@k,MRR,差距,标记核对

测试

✅ .venv/bin/python -m pytest,1100

仪表盘

✅ 注册表、来源、查询运行、关联图、卡片、词典

授权

✅ API_TOKEN读权限,ADMIN_TOKEN写权限

接收配置导出为文件

✅ data/incoming/,来源筛选和记录

从导出文件生成代码索引

✅ 搜索、过程卡片和调用反向搜索

最终镜像大小已于2026-08-21验证:命令 docker image ls mcp1c:latest --format '{{.Size}}'输出357MB。 这是Docker CLI显示的尺寸。命令 docker image inspect mcp1c:latest --format '{{.Size}}'返回77950901字节 的内部字段; 这是另一个指标,而不是显示尺寸的第二次测量。

对配置没有限制。 任何配置都可以加载——标准配置(会计、薪酬、文档流转、零售)和行业配置:导出处理遍历元数据,而不是死记硬背。解析的是导出出来的内容。

重要的是配置运行所在的平台版本:它决定了get_syntax会显示哪些内容为可用,哪些内容因较新而被隐藏。已在8.3.5和8.3.23上验证——这是遇到过的边界;帮助从三个版本合并,8.3.5、8.3.23和8.3.27。同时导出处理必须在8.3.5上编译:下边界由它决定,而不是由服务器决定。

Related MCP server: 1C_MCP_SERVER_OWN

目录

  1. 启动 — Docker、仪表盘、 关联图、无Docker

  2. 连接代理 — MCP如何工作、 如果无法连接、令牌、客户端配置: Claude Code、Codex CLI、 Cursor、VS Code、Qwen Code、 stdio

  3. 工具 — 调用顺序、 来源、查询语言、 平台版本、 帮助合并、 替换

  4. 数据管理 — 来源、 配置导出为文件、 词典和搜索键、 CLI、 测量台架、 手动服务器、 数据来源

  5. 内部结构 — 模块、 测量、测试

  6. 安全 — 令牌、无令牌时开放的内容

  7. 文档

  8. 许可证 — Apache 2.0、与「1C」公司的关系


1. 启动

Docker(主要方式)

# 1. Положить исходные данные
mkdir -p data/bootstrap
cp ВыгрузкаКонфигурации.zip                     data/bootstrap/
cp /opt/1cv8/8.3.27.2130/shcntx_ru.hbk          data/bootstrap/

# 2. Поднять
docker compose up -d --build

# 3. Проверить
curl http://localhost:5001/health
{"status":"ok",
 "configurations_total":2,
 "syntax_loaded":true,
 "query_language_loaded":true,
 "configurations":["РозницаДляКазахстана","ОтраслеваяКонфигурация"],
 "syntax":["8.3.5.1570","8.3.23.1997","8.3.27"]}

平台帮助和查询语言是不同的来源和不同的字段: syntax_loaded只属于前者,syntax列出已加载帮助的版本。 配置名称和帮助版本只返回给通过读权限检查的请求;没有令牌时只保留status、 计数器和两个标志。

data/bootstrap/中的所有内容在启动时都会被索引:*.zip——配置导出, *.hbk——平台帮助。同一文件不会重复解析:按哈希校验。

按习惯放入bootstrap/的配置导出为文件并不合适——服务器根据归档组成来识别它(有代码,没有manifest.json/manifest.xml清单),不会尝试解析:那是千兆字节,每次启动都处理是不行的。启动消息列表中不会报错,而是显示其名称并提醒这些文件应放在哪里——data/incoming/,见下文 「配置导出为文件」一节。

./data目录挂载到容器中作为/data。服务器在其中保存 源文件、索引、缓存和registry.json;注册表中的路径是相对的,因此 该目录可以在开发机器和容器之间移动。

data/完全不在git中——它是卷,而不是仓库的一部分。通过复制目录来迁移。因此克隆后需要自己放入帮助文件:仓库不包含也不能包含它,这是「1C」公司的内容。

修改代码后需要重新创建容器,而不是重新启动:

docker compose up -d --build --force-recreate

restart会在旧镜像上启动旧容器,修改不会生效。

关于端口。 服务器对外暴露在5001,容器内部监听8000—— docker-compose.yml中的端口映射为5001:8000。该文件中的所有地址都是外部的,即5001。如果被其他服务占用——请修改映射的左侧部分,右侧不要动:EXPOSE和镜像的healthcheck都依赖它。

仪表盘

http://localhost:5001/——六个页面:

页面

内容

概览

已加载内容:对象、关联、平台版本、清单中的警告

来源

已加载内容列表、每个代码库的三个覆盖表、完整JSON日志的路径、带传输进度条的.zip和.hbk上传、删除、「传入导出」区块——data/incoming/中的文件、按按钮解析

查询

运行表述列表并给出评分和排序原因

关联

对象邻域图(图片形式)

卡片

对象组成或平台元素描述——与代理看到的内容相同

词典

带来源的规则;创建别名或同义词组

上传——看到什么和何时看到

上传分两个阶段进行,显示方式也不同。

文件传输——在「来源」页面上以进度条显示:百分比、大小、 速度和剩余时间估算。由浏览器计算,这不是随意的选择。 服务器看不到传输进度:await request.form()只有在 请求体完整到达后才返回控制权,任务在之后才创建。已在真实套接字上验证:40 MB传输了8.1秒,在此期间从第二个连接发起的32次/sources轮询没有看到任何任务。在localhost上没有区别,在远程服务器上这是数分钟的空屏。

同时500 MB的限制在发送前就检查:以前超大的文件会完整上传,然后才被拒绝。

解析——同一页面上的「上传」表格:「接收中」→ 「解析中」→「完成」或带原因的「错误」。工作进行时,页面 自动刷新(meta refresh,每2秒一次)。

进度条需要JS,表格不需要。关闭JS后表单像普通表单一样工作:文件发送、任务创建、状态在表格中可见——只是传输期间没有进度条。

关联——对象图

/graph绘制对象的邻域:按类型着色,按引用方向画箭头,悬停显示边的标签。点击节点围绕它构建图,拖拽移动,滚轮缩放。邻居上限在页面上选择(15…400),裁剪以数字表示——「显示30个,共102个」。

回答「如果动它会破坏什么」:被橙色文档包围的寄存器立即告诉你谁在动它。

深度始终是一步。 两步之后从常用目录中会取出上千个对象,三步之后是配置的三分之一;再远关联会经过通用机制,如附加属性,它们几乎把一切都连接起来。无法用关联数阈值来截断它们:这样的节点有34条关联,而有意义的Справочник.Пользователи有323条。因此由人来展开节点,而不是启发式——人能看到哪里不值得去。

代理没有这个工具是故意的。 图在两步之内就会膨胀到上千个对象,而用简单阈值无法剔除通用机制:一个有意义的节点可能比技术节点拥有更多连接。单独的工具只会与可测量的输出限制规则一起返回;目前精确的下一步由人在交互式图中选择。

失误无需离开浏览器即可修复:在请求页面上,每个短语都有一个“不对——创建别名”的链接,它会跳转到已填入该短语的词典。修改立即生效——索引不会重新构建,无需重启。

读取由 API_TOKEN 保护,写入由 ADMIN_TOKEN 保护。 只要 API_TOKEN 未设置,任何能访问到该地址的人都可以读取——包括配置结构和定制内容。对于 localhost 这是可以接受的,对于网络上的服务器则不行。

令牌分开是因为读取令牌存在于每个 MCP 客户端的配置中,并随之一同泄露;代理不应拥有删除来源的权限。管理员令牌也可以当作读取令牌使用——无需保留两个请求头。

// .mcp.json — как клиент передаёт токен
{"mcpServers": {"1c": {"type": "http", "url": "http://localhost:5001/mcp",
                       "headers": {"X-Api-Token": "..."}}}}

仅限 ASCII:HTTP 请求头使用 latin-1 编码,西里尔字母无法通过。/health 保持开放以供健康检查,但配置名称仅凭令牌返回。

词典的加载、删除和编辑需要 ADMIN_TOKEN——与 /admin/reload 使用的是同一个;没有它,这些端点就不存在,而不是“它们被关闭了”。令牌在表单中输入一次,进入浏览器的不是它,而是会话标识符。

通过 docker-compose.yml 旁边的 .env 设置——包含所有变量的模板位于 .env.example:

cp .env.example .env
python3 -c "import secrets; print(secrets.token_urlsafe(32))"   # значение
docker compose up -d --force-recreate

结果中的名称是指向卡片的链接:对于对象,卡片包含带类型的属性、表格部分和流水;对于平台元素,则包含签名、参数、可用性和出现版本。代理收到的也是同样的文本,带有 brief / fields / full 切换开关。属性没有自己的卡片——链接指向其所属对象。

“请求”页面回答了“服务器为什么给出这个结果”的问题:每个命中旁边都有原因——精确匹配、来自词典的别名、查询的所有词。从中可以看出如何修复失误——用同义词、别名还是权重。

解析帮助文档需要几秒钟:页面会在解析后响应,但这不会延迟 MCP 客户端——索引在单独的线程中进行。

不使用 Docker

从仓库副本——与运行测试和 CLI 的方式相同:

python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
PYTHONPATH=src .venv/bin/python -m mcp1c.server --host 0.0.0.0 --port 5001

或者用包安装——这样就不需要 PYTHONPATH,旁边会出现三个命令:

pip install .

mcp1c-server --host 0.0.0.0 --port 5001   # = python -m mcp1c.server
mcp1c reg-list --data data                # = python -m mcp1c.cli
mcp1c-bench --help                        # = python -m mcp1c.bench

模块化启动(python -m mcp1c.server)在这种情况下仍然可用:命令是相同的入口点,只是名称不同。所有参数都在“数据管理”一节中描述。


2. 连接代理

服务器通过官方 SDK 的标准传输实现 MCP 协议,因此适用于任何 MCP 客户端。不需要任何 HTTP 包装器。

传输方式

适用场景

地址

streamable-http

服务器在 Docker 中或在独立机器上

http://地址:5001/mcp

stdio

客户端自行在本地启动进程

—

两种受支持的传输方式均已通过官方 MCP 客户端验证:initialize 握手、tools/list、tools/call,协议版本 2025-11-25。

不支持的过时 HTTP+SSE 传输:--transport sse 在读取数据和启动服务器之前就会被拒绝为无效值。旧客户端需要 streamable-http 模式或通过 stdio 本地启动。

工作原理

在连接失败之前了解这一点很有用。地址只有一个——/mcp, 没有按工具区分的端点;调用哪个工具写在请求体中,而不是路径中。

接下来是两种不同的机制,不应混淆:

工具描述

数据

时机

连接时一次

每次调用

谁发起

客户端,自行,不经过模型

模型,根据决策

方法

POST initialize,然后 POST tools/list

POST tools/call

去向

模型的系统提示

对话正文

代价

一次性,整个会话期间常驻

每次调用

连接时,客户端发送 POST initialize——服务器以名称、版本和 instructions 文本作为响应,并在请求头中返回 mcp-session-id。然后 POST tools/list 一次性返回工具:名称、描述、参数 JSON 模式。所有这些在用户输入第一个词之前就被放入模型的上下文中。模型不会在需要时才去获取描述——它已经在那里了。

由此得出一个在编辑描述时很重要的推论:无论模型是否调用任何一个工具,它们都会在整个会话期间占据窗口空间。

无论加载了什么,工具始终是十个。 这个集合是契约,而不是变量:工具之间相互关联,在工作服务器上,配置、代码、平台帮助和查询语言的来源可以独立加载。tools/list 加上 instructions 的契约大小不依赖于注册表的状态。

由此得出一个必须提前知道的直接推论:如果来源未加载,你仍然要为其工具付费。 没有平台帮助时,search_syntax 和 get_syntax 会常驻在上下文中,花费 1,185 个令牌,回答“帮助未连接”;compare_configurations 在只有一个配置时——262 个令牌只为回答“至少需要两个”。解决方法是加载来源,而不是筛选工具:动态集合曾在 2026-08-19 尝试过并被取消,因为独立来源必须保持统一的会话契约。

因此,描述写得紧凑,细节则转移到工具本身的输出中:只有在需要时才为它们付费。

GET /mcp——不是“错误的 POST”,而是同一地址上的第三种方法:它打开从服务器到客户端的消息流,并且需要已经获得的 mcp-session-id。DELETE /mcp 关闭会话。

如果客户端无法连接

日志中的响应代码(docker logs -f mcp1c)会指出原因:

代码

问题

406

客户端未发送 Accept: application/json, text/event-stream——两种类型都需要

400 Missing session ID

客户端未返回在 initialize 时获得的 mcp-session-id 请求头

400 在第一次 GET /mcp 时

客户端以 GET 开始握手——它使用的是旧的 HTTP+SSE 传输,而此地址上是 streamable-http

404 在 /sse 上

同样:旧传输已完全禁用

401

在设置了 API_TOKEN 时未传递 X-Api-Token

日志为空

客户端根本没有发送请求——问题出在它的配置中,请求未到达服务器

真实案例:Qwen Code 无法连接,因为其配置中有 url 键——在 Gemini CLI 系列中(Qwen 继承了该格式),它表示旧的 SSE 传输,客户端以 GET 开始,收到 400。使用 httpUrl——即 streamable-http——连接立即成功。

令牌:在客户端设置中添加什么

如果服务器设置了 API_TOKEN,每个客户端都必须通过请求头发送它。没有请求头,/mcp 会返回 401,代理根本看不到工具。

两个请求头中的任何一个都可以——服务器都接受:

X-Api-Token: <токен>
Authorization: Bearer <токен>

三件容易绊倒的事情:

  • 仅限 ASCII。 HTTP 请求头使用 latin-1 编码,西里尔字母令牌无法通过。生成方式: python3 -c "import secrets; print(secrets.token_urlsafe(32))"。

  • 客户端中放的是 API_TOKEN,而不是 ADMIN_TOKEN。 管理员令牌也会被接受,但客户端配置会进入 git 和备份:泄露的读取令牌只允许查看,泄露的管理员令牌则允许删除来源。

  • stdio 完全不需要令牌。 那里客户端自行启动进程,不涉及网络,无需检查。如果客户端不支持设置请求头——这是一个可行的变通方案。

在配置客户端之前,先验证服务器能看到令牌:

curl -s -o /dev/null -w '%{http_code}\n' -X POST \
  -H 'x-api-token: ВАШ_ТОКЕН' \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
  http://localhost:5001/mcp

200——令牌已被接受。401——令牌错误或请求头未送达。

如何不提交机密

.mcp.json 和类似文件通常位于仓库中。选项:

  1. 变量替换——如果客户端支持(Claude Code 支持): "X-Api-Token": "${MCP1C_API_TOKEN}",变量本身放在 ~/.zshrc 中。 进入 git 的是变量名,而不是值。

  2. 将文件移出 git 管理: git rm --cached .mcp.json && echo ".mcp.json" >> .gitignore。

  3. 将设置放在项目的用户级客户端配置中,而不是项目中—— 这样仓库就完全不相关了。

Claude Code

项目根目录下的 .mcp.json 文件:

{
  "mcpServers": {
    "1c": {
      "type": "http",
      "url": "http://localhost:5001/mcp",
      "headers": { "X-Api-Token": "${MCP1C_API_TOKEN}" }
    }
  }
}

只有在服务器设置了 API_TOKEN 时才需要 headers 块。值取自环境变量,以便文件可以放在仓库中:

echo 'export MCP1C_API_TOKEN=ваш_токен' >> ~/.zshrc && source ~/.zshrc

或者用命令:

claude mcp add --transport http 1c http://localhost:5001/mcp \
  --header "X-Api-Token: $MCP1C_API_TOKEN"

Codex CLI

~/.codex/config.toml 或项目中的 .codex/config.toml:

[mcp_servers.mcp1c]
url = "http://localhost:5001/mcp"

# Только если задан API_TOKEN. Имя ключа для заголовков у Codex менялось между
# версиями — сверьтесь со своей (`codex --help`, раздел MCP). Не подхватилось —
# используйте stdio, там токен не нужен вовсе.
[mcp_servers.mcp1c.http_headers]
X-Api-Token = "ваш_токен"

Cursor

.cursor/mcp.json:

{
  "mcpServers": {
    "1c": {
      "type": "streamable-http",
      "url": "http://localhost:5001/mcp",
      "headers": { "X-Api-Token": "ваш_токен" }
    }
  }
}

VS Code (Copilot)

.vscode/mcp.json——这里的键名为 servers:

{
  "servers": {
    "1c": {
      "type": "http",
      "url": "http://localhost:5001/mcp",
      "headers": { "X-Api-Token": "ваш_токен" }
    }
  }
}

Qwen Code

格式来自 Gemini CLI,键选择传输方式——这是唯一的细微差别:

{
  "mcpServers": {
    "1c": {
      "httpUrl": "http://localhost:5001/mcp",
      "headers": { "X-Api-Token": "ваш_токен" }
    }
  }
}

httpUrl——streamable-http,我们的情况。此格式中的 url 表示旧的 SSE 传输:客户端将以 GET /mcp 开始握手,收到 400 Missing session ID 并无法连接。

其他客户端

Windsurf、Antigravity、Cline、Roo Code、控制台代理——记录格式相同:传输类型、URL,以及如果设置了 API_TOKEN,还有请求头块。区别仅在于文件名和顶层键(mcpServers 或 servers)——请查阅具体客户端的文档。

客户端不支持设置请求头——这不是死胡同:通过 stdio 连接,那里不需要令牌,因为没有网络。

通过 stdio 本地启动

当客户端必须自行启动服务器时。这里不需要令牌:进程由客户端启动,通信通过进程管道进行,而不是通过网络——没有什么可检查的,也没有需要防御的对象。

{
  "mcpServers": {
    "1c": {
      "command": "python3",
      "args": ["-m", "mcp1c.server", "--transport", "stdio", "--data", "/путь/к/data"],
      "env": { "PYTHONPATH": "/путь/к/проекту/src" }
    }
  }
}

3. 工具

集合是固定的,并且有意保持精简:每个工具都持续存在于代理的上下文中。新工具只为单独的用户任务而出现,而不是为每个内部索引而出现。

Инструмент

Назначение

list_configurations

已加载内容,每种配置下有哪些提供程序可用

search_objects(query, config, kind, limit)

人类表述 → 精确对象名称

search_procedures(query, config, extension, scope, limit)

精确名称或词语 → 配置代码或单个扩展中的过程

get_procedure(address, config, extension, start_line, lines)

模块目录或签名、编译上下文及过程体窗口

get_callers(address, config, extension, limit)

已确认的调用位置、元数据绑定及表单处理程序

get_object(full_name, config, detail)

对象组成;detail:brief / fields / full

get_related(full_name, config)

变动、引用、依赖 — 仅限直接关系

compare_configurations(full_name, configs)

同一对象在两种配置中的对比

search_syntax(query, config, kind, limit)

按平台帮助及查询语言搜索

get_syntax(name, config, detail)

签名、参数、可用性、版本、旧平台替代项

当加载了多个配置时,config 为必填项:服务器有意不静默代填——否则代理会按错误的代码库编写代码,而无人知晓。

list_configurations 显示主配置及每个扩展的代码索引实际状态:就绪、正在构建(含阶段和进度)、出错或代码未加载。对于就绪的扩展,输出四种注解的重叠数、受影响的模块数及自有过程数,以及用于访问其代码的现成参数 extension。就绪语料库若变体未知或损坏,则称为**“受限就绪”**状态。所有三个外壳获得同一代次的精确聚合数据,但按各自任务展示。list_configurations 和 reg-list 保留详细诊断:类别、稳定顺序下的前 20 个问题及剩余精确数量;对于不可寻址的候选对象,仅输出序号,不显示物理名称和本地路径。/sources 不以地址流形式展示,而是显示三个可核对表格,含数量、百分比和明确分母:模块与过程、表单结构、表单模块。

每个语料库的完整列表原子地存储在一个最新文件中:data/logs/code-<sha256 source_id>.json。主配置和每个扩展各有不同的日志;重新加载仅替换自己的文件,删除源则删除其日志。损坏的、代次不符的或与当前索引内容不一致的日志不显示为最新,并从就绪索引重新构建。表单结构单独显示完全读取、部分读取和未读取的数量。 schema v1 的契约和不变量如下所述。警告位于不完整回答之上,并直接说明:零计数不能证明不存在隐藏数据。

代码覆盖日志 — schema v1

一个文件属于一个可独立删除的源 <Конфигурация>:modules 或 <Конфигурация>:ext:<Расширение>。源名称不包含在路径中:文件按完整 sha256 source_id 命名。

{
  "schema_version": 1,
  "kind": "module_coverage",
  "source": {
    "id": "Отраслевая конфигурация:modules",
    "kind": "modules",
    "sha256": "...",
    "loaded_at": "2026-08-24T12:00:00+00:00",
    "selection_version": 4,
    "locator_generation": 3,
    "code_version": "1.0.0"
  },
  "identity": {
    "source_id": "Отраслевая конфигурация:modules",
    "source_sha256": "...",
    "generation": 3
  },
  "coverage": {
    "modules": {
      "total": 2,
      "source_available": 1,
      "empty": 0,
      "partial": 0,
      "unreadable": 0,
      "conflict": 0,
      "compiled_without_source": 1
    },
    "procedures": {"total": 1, "full": 1, "partial": 0},
    "form_structures": {
      "total": 1, "full": 0, "partial": 1, "unavailable": 0
    },
    "form_modules": {
      "total": 1, "read": 1, "empty": 0, "missing": 0, "unreadable": 0
    },
    "limitations": {
      "categories": {"compiled_without_source": 1, "unknown_marker": 1},
      "occurrences_total": 2,
      "problem_rows_total": 2,
      "unknown_markers": 1,
      "known_markers_incomplete": 0,
      "unsupported_addresses": 0,
      "broken_containers": 0,
      "unreadable_bodies": 0,
      "budget_exceeded": 0,
      "body_conflicts": 0,
      "compiled_without_source": 1
    }
  },
  "problems": [
    {
      "category": "unknown_marker",
      "address": "ОбщаяФорма.Пример",
      "ordinal": 0,
      "reason": "маркер form не поддержан",
      "marker": 99
    },
    {
      "category": "compiled_without_source",
      "address": "ОбщийМодуль.Пример",
      "ordinal": 0,
      "reason": "скомпилированный модуль без исходника",
      "marker": null
    }
  ]
}

类别 modules、procedures、form_structures 和 form_modules 之和必须等于各自的 total;两个表单表格共用一个分母;problem_rows_total 等于完整 problems 的长度。若无法证明规范地址,则 address 为 null,此时 ordinal 为确定性的候选编号。marker 存储已读取的 form 结构标记,若问题与之无关则为 null。identity 将日志与 sha256 及定位符目录代次关联。

文件中不包含绝对路径、原始异常、traceback、令牌、BSL 代码体和原始 form 记录。目录打开时不跟随符号链接,临时文件在其中创建并原子替换最终文件。写入失败不取消语料库的就绪状态。

get_object 根据 detail 添加代码相关信息:brief 不访问代码提供程序,fields 给出一行计数器,full 列出对象的模块和所有表单(不含其内容)。表单凭任何证据均可见:独立的 XML 描述符、Form.xml、Form.bin、扁平 .Form 或单个表单模块。 若索引正在构建、以错误结束或未加载,对象元数据仍会连同代码的真实状态一起返回。get_related 标记其过程确实被任何已加载扩展覆盖的相关对象;扩展自身的过程不产生此类标记。在 fields 和 full 下,对象卡片无总限制地列出与其表单相关的原因,因此未读取的表单不会变成虚假的“无表单”。过程与关系工具同样将警告置于部分结果之上;代次变更时连同计数器和问题一起重复整个回答。

search_procedures 合并两个层级。名称精确匹配可找到任何过程,包括非导出过程;按词语、变格和头部注释搜索仅对导出过程有效。每个层级的 limit 单独设置,必须是 1 到 50 的整数。回答中包含地址 Модуль::Имя、磁盘上的签名、导出性、行号、已确认调用位置数以及同名位置的单独计数器(其目标无法解析)。扩展注解的布尔索引被中性命名:它不将 &После 或 &Перед 视为对原始过程的完全覆盖。 签名和过程体不保存在内存中。 层级 .bsl、扁平 .txt 以及源容器 Form.bin/.Form 的 module 记录经过同一个词法分析器;搜索及后续卡片使用同一代次的定位符,而非从地址恢复路径。

无 scope 时搜索为全局。显式 scope="Документ.ЧекККМ" 提升对象的所有模块,而 scope="ОбщийМодуль.ОбщегоНазначения" 或其他精确地址则提升单个模块;其余结果保持在其下方。作用域不从 query 猜测。extension 选择恰好一个已加载扩展;无扩展时仅按主配置搜索。

get_procedure 接受搜索中的精确地址。不带 :: 的模块地址返回不含过程体的目录;Модуль::Имя 返回签名、编译上下文和过程体。start_line 从 0 开始,lines 必须是 1 到 200 的整数;长回答包含下一个窗口的现成调用,不跳过行。对于所选扩展,&После、&Перед 和 &Вместо 显示其过程体;&ИзменениеИКонтроль 显示主配置的过程体及仅逐字的 #Вставка/#Удаление 块。工具在过程体上方警告其他已加载扩展,但不将其代码混入回答。签名和过程体为单个回答从磁盘读取,不保留在内存中。 同一定位符可跨越缓存和重启:若源在读取期间被替换,整个回答按新代次重复,两个代次的部分不会混合。

get_callers 仅接受精确地址 Модуль::Имя。首先按模块分组已确认的调用位置并命名属主过程,然后显示元数据图中的事件订阅和计划任务,之后显示 Form.xml 中的表单元素和事件。limit 必须是 1 到 50 的整数;截断后保留位置和模块的精确数量。描述符或容器记录本身不能证明不存在处理程序:在位置语义未证明时,工具报告部分覆盖。Form.xml 状态单独存储,因此即使相邻容器有缺陷,完好的 XML 绑定仍可用。 同名过程且模块未解析的调用单独输出,不归属于所请求的地址。若两个过程位于同一物理行,则不猜测属主。工具不读取模块文本。空回答提醒:通过 Выполнить、ОписаниеОповещения 和 ПодключитьОбработчикОжидания 的字符串调用不被索引。

提供程序不知道的内容

  • 按词语搜索仅针对导出过程。非导出过程可通过精确名称或已知模块的目录找到。

  • 动态调用(名称以字符串形式传给 Выполнить、ОписаниеОповещения 或 ПодключитьОбработчикОжидания)不被索引。

  • 已编译的通用模块没有可用源码:可见地址本身,但其中的过程、调用、签名和过程体不可见。

  • 在容器结构 Form.bin/.Form(包括扁平导出)中,目前仅证明了括号语法和根标记 19、20、23、25、26、27,但未证明位置字段的用途。因此此类表单被视为部分读取,其中的属性、元素和事件无法猜测。 完整组成和绑定仍仅可从 Form.xml 获取;XML 描述符单独提供 UUID、名称、同义词和表单类型。

  • 未解析到精确模块的同名调用不归属于所请求的过程,而是单独显示。

一个名称可同时存在于两个域中:СтрНайти 既在平台中(自 8.3.6 起),也在查询语言中。此时 get_syntax 列出同名项并附上各自的现成地址,可用输出中的字符串重复调用:

get_syntax("СтрНайти")                    → Одноимённых элементов: 2
                                            - `Глобальный контекст.СтрНайти` — Метод, с 8.3.6
                                            - `Запрос.СтрНайти` — Функция запроса
get_syntax("Запрос.СтрНайти")             → карточка функции языка запросов

限定符 Запрос. 是必需的,因为查询语言元素没有属主:无法像平台元素那样通过 Объект.Член 来称呼它。

调用顺序 — 以及违反顺序会失去什么

list_configurations
├─ search_objects → get_object → get_related
├─ search_procedures → get_procedure → get_callers
└─ search_syntax → get_syntax

在代码链中,每一步都添加前一步没有的信息。没有 search_procedures,需要预先知道精确地址,并失去按用途和作用域搜索的能力。没有 get_procedure,不显示签名、编译上下文、过程体及扩展的精确语义。没有 get_callers,无法验证编辑的直接后果:已确认的调用位置、元数据绑定和表单事件。

get_object 步骤不可跳过。 搜索仅返回名称和计数器;代码所依赖的一切都存在于对象卡片中:

  • 注册表的类型和周期性。 СрезПоследних 仅存在于周期性的信息注册表中,而非周期性的 566 个中的 603 个;

  • 虚拟表字段的现成名称。 在查询中,资源 Количество 称为 КоличествоОстаток、КоличествоОборот、КоличествоПриход — 配置器中这些名称在任何地方都不可见,由平台生成;

  • 子conto 上限、对应关系、图表资源 — 没有它们,СубконтоДт1 之类的字段无从命名;

  • 无限长度字符串。 直接在类型中标记:Строка (неогр. — только через ПОДСТРОКА) 对比 Строка(200)。此类字段不能直接放入查询 — 平台既不允许比较、分组,也不允许排序。在真实配置中,此类字段占字符串字段的 23% 到 38%,因此在出现它们的卡片上(20 522 个中的 2 474 个),在字段列表之前打印带配方的说明。

紧随 search_objects 之后编写的查询看起来正确,却因“字段未找到”而失败。仅从 get_object 才能获得的信息示例:

## Таблицы запроса
- `РегистрНакопления.ТоварыНаСкладах.Остатки`
  измерения: Склад, Номенклатура, Характеристика
  ресурсы: КоличествоОстаток, РезервОстаток

第二个同样的例子 — 它由 2026-08-18 的真实失误发现。代理按无长度限制的字符串分组了查询;我们给出的数据是正确的,但差异只能通过括号中数字的缺失来读取:

> **Строки неограниченной длины** помечены `(неогр.)`. Платформа не даёт их
> сравнивать, группировать и упорядочивать и не пускает в РАЗЛИЧНЫЕ,
> ОБЪЕДИНИТЬ и агрегатные КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ. Ограничивайте
> длину — одинаково в списке выборки и в группировке:
>
>     ПОДСТРОКА(КодСкидки, 1, 100) КАК КодСкидки
>
> Длину подбирайте по смыслу поля: 100 — не универсальное число.

## Реквизиты

- `КодСкидки` — Строка (неогр. — только через ПОДСТРОКА) // Код скидки
- `КодМаркировки` — Строка(200) // Код маркировки

配方既写在保留条款中,也写在字段行本身,这并非冗余。 第一版把保留条款印在卡片的最后一段。活体代理 2026-08-18 调用了 get_object,参数为 detail=fields,完整地拿到了它——但 仍然按这样的字段进行了分组。保留条款位于字段行之后 721 个 token 处,而决策是在复制名称的地方做出的。同样的教训已经写在 工具描述上:规则在其被阅读的地方生效,而不是在其被更仔细放置的地方。

每一条禁令都经过验证:聚合类——引用帮助文档,其余五条—— 在活体数据库上运行并记录错误文本。帮助文档只在六个聚合函数中的三个 知道该限制,对分组、排序、РАЗЛИЧНЫЕ、ОБЪЕДИНИТЬ 和比较只字不提——也就是说, 一个诚实阅读了它的代理不可能得知此事。按来源的拆分——见 docs/data-sources.md,「卡片中的保留条款」一节。

在旧配置上调用平台函数之前——先调用 get_syntax。 不可用的内容会被标记,替换配方如果已记录,也放在那里。

来源相互独立

共有五个,每个单独接入:

来源

文件

提供内容

没有它

配置元数据

СтруктураКонфигурации_*.zip

对象、属性、关联、移动

search_objects 和 get_object 不响应

配置代码

配置导出到文件的归档

主配置的过程、签名、函数体、编译上下文、调用位置、表单事件

没有配置代码,search_procedures、get_procedure 和 get_callers 会指出缺失的来源

扩展代码

扩展导出到文件的归档

所选扩展的自有和修改过程、其函数体和调用位置

没有扩展代码,主配置可用,但 search_procedures、get_procedure 和 get_callers 看不到该扩展的代码和覆盖

平台帮助

shcntx_ru.hbk

方法、属性、签名、可用性、版本

search_syntax 提示「来源未接入」

查询语言

shquery_ru.hbk

ВЫБРАТЬ、ЛЕВОЕ СОЕДИНЕНИЕ、ИТОГИ ПО、РАЗНОСТЬДАТ

查询语言构造无法找到

已加载内容

可用的功能

所有必要来源

全部

仅配置

元数据;语法提示「来源未接入」

仅帮助

语法不按版本过滤,config 不需要

无

list_configurations 说明应加载什么

查询语言——独立来源

shquery_ru.hbk 来自同一平台安装目录。127 页: 52 个函数、67 个关键字、8 篇文章。作为普通来源加载并 进入与平台帮助相同的搜索索引——无需用单独工具搜索,search_syntax 两者都能找到。

文件本身没有版本——已在全部 129 页上验证:零处 提及「8.3.x」和「从版本开始」。但查询语言会变化:8.3.20 版本新增了 25 个函数,其中包括 СтрНайти、Лев、Прав、ВРег、НРег、 СтрЗаменить、Окр、Цел 以及全部三角函数。

版本无处可取:平台帮助完全不描述查询语言函数 (ПОДСТРОКА——在 25 511 个元素中零匹配)。因此版本由 策展表 query_versions.py 指定——依据 1С 的列表「从 8.3.20 版本起添加到查询语言的函数」。其余 27 个函数 不标注版本:它们一直存在。

接下来是常规过滤:8.3.5 上的配置看不到这些函数, 8.3.23 上可以看到。

该表用数据验证——通过比较两个不同平台的帮助文档。旧版中没有 而新版中有的,就是两者之间出现的,且必须标注版本:

python3 tools/lab/compare_query_help.py <старая.hbk> <новая.hbk>

2026-08-19 运行,8.3.5.1570 对比当前版本:新增 29 个,覆盖 29 个,误报 0 个。误报是最糟糕的错误:一个在旧帮助中已存在 但被标注了版本的元素,会从存在它的配置中隐藏起来。

每个服务器一个实例:重复加载会替换之前的实例。

页面表格会显示,但不会被搜索。 在此帮助文档中,表格单元格 用 <TD> 内的段落标记,如果不单独解析,卡片会把 表格打印成一列值:「Товар / Количество / Номер / Сантехника / 104 / …」 连续二十多行。现在表格用单独字段解析——127 页中 31 页上有 51 个表格——并在文本中打印在各自位置: 带有两个示例的页面在每个示例下方显示各自的结果。 表格内容不会进入搜索索引。

此帮助文档中的表格有两种不同性质,解析方式也不同:

内容

数量

在卡片中的显示

数据表——示例查询的结果

31 页上 51 个

markdown 表格

手绘语法图——构造的语法

17 页上 21 个

按分支层级缩进的阶梯式

按标记区分,而非 CSS 类:class=SimplyTable 并非标注在所有表格上——7 个真正的表格没有它。特征——几何形状:数据表的 所有行宽度相同,语法图的宽度参差不齐,且有由单个竖线组成的单元格(这是画出来的线,不是值)。

损坏的标记会被点名。 带有未闭合 <TABLE> 的页面 解析时不含表格,但不会丢失,其名称会进入来源 警告:作为加载输出(mcp1c.cli reg-add)中的一行,以及 仪表板「来源」页面上的单独一行。不能默默给出比平时更贫乏的卡片:这与帮助中根本没有该内容 无法区分。

一半名称与平台名称相同(127 个中 57 个)——ГОД、МЕСЯЦ、 ПРЕДСТАВЛЕНИЕ 两边都有。为了不让关于查询的问题引向平台 方法,「在查询中」「在查询文本中」「在样本中」等措辞会给 查询语言元素一个温和的提升。温和是有意为之:在明确区分时 平台元素仍保持第一——「如何在查询中设置参数」 也可能是指 Запрос.УстановитьПараметр。

如果加载了多个配置,config 参数为必填。 默认不代入任何内容:静默选择会导致 代理按他人配置编写代码,而无人察觉。

答案取决于平台版本

同一个调用,两个配置:

get_syntax("СтрШаблон", config="Розница")     → 8.3.23
# Метод: Глобальный контекст.СтрШаблон
с версии платформы 8.3.6
Доступность: ТонкийКлиент, ВебКлиент, Сервер, ТолстыйКлиент, …

get_syntax("СтрШаблон", config="Отраслевая")  → 8.3.5
# `Глобальный контекст.СтрШаблон` недоступен в этой конфигурации
Элемент существует, но появился в 8.3.6, а конфигурация работает на 8.3.5.1570.
Использовать нельзя — код не скомпилируется.

对于平台 8.3.5,从输出中移除了 6 539 个元素,对于 8.3.23——874 个。不是 通过警告,而是通过过滤:代理会跳过警告,但不会跳过输出中缺失的方法。

可用性字段(服务器 / 瘦客户端 / Web 客户端 / 移动端)必须 阅读:从客户端上下文调用服务器方法无法编译。

多个版本的帮助合并为一个索引

一份新帮助配旧配置会撒谎。已在 8.3.5 上测量: 服务器会宣布 199 个元素不存在,117 个会以错误的 签名返回(8.3.5 上的 ЗаписьXML.ОткрытьФайл 接受两个参数,8.3.27 中—— 三个),410 个——以错误的可用性返回。这些都是编译错误,而非不精确。

因此不同版本的帮助并排放置,合并为一个带有 since 和 until 边界的索引,答案按特定配置的版本组装。帮助的数量需要与已加载配置的平台数量相同——两个极端版本不能替代中间版本。

成本已测量且很小:合并三个版本产生 25 691 个键,而单个版本为 24 777 个, 即不到百分之一。每版本独立容器也可行, 并保留为应急路径,但作为主要方案在数字上落败——每个版本 300–450 МБ 和 独立地址。

服务器自行指出缺少哪些帮助、哪些多余——在 list_configurations 的输出中。

用替换代替禁止

说「函数不存在」——只是答案的一半。另一半——用什么替换它, 而这无法从帮助中推导:过时标记只出现在 2.5 万个 页面中的 15 页上。

因此有替换表(replacements.py),目前 6 条记录——8.3.6 中出现的 字符串函数。get_syntax 不是禁止,而是给出配方:

get_syntax("СтрРазделить", config="Отраслевая")   → 8.3.5
# `СтрРазделить` недоступна: появилась в 8.3.6

Замена: РазложитьСтрокуВМассивПодстрок(<Строка>, <Разделитель>)
Оговорка: разделитель у `СтрРазделить` — набор символов, каждый из которых
самостоятельный разделитель; у замены это одна строка целиком.

保留条款为必填。 替换几乎从不等价,默默 塞入一个相似函数——比什么都不提示更糟。

该表根据实际案例补充,而非盲目:为无人询问的函数 编造绕过方案没有意义。


4. 数据管理

添加来源

# в Docker
docker compose exec mcp1c python -m mcp1c.cli reg-add /data/bootstrap/Выгрузка.zip --data /data
docker compose exec mcp1c python -m mcp1c.cli reg-add /data/bootstrap/shcntx_ru.hbk --data /data

# без Docker
PYTHONPATH=src python3 -m mcp1c.cli reg-add Выгрузка.zip

更简单:将文件放入 data/bootstrap/——下次启动时会自动拾取。

配置导出到文件

第二种来源——不是元数据(СтруктураКонфигурации_*.zip),而是配置本身 导出到文件:模块代码和表单。服务器构建并缓存 过程、调用和表单的内部索引;search_procedures 按 现成集合搜索。缓存未命中时,索引在后台构建:不依赖代码的工具 继续响应,而代码工具显示阶段 X/4 和 当前阶段实际处理的 N/M 个元素。现成集合整体发布, 不会出现来自不同版本的中间状态。 后台构建不会覆盖 registry.json,只要 startup 还在 恢复后续来源。如果 startup 异常中断, 磁盘上之前的完整快照保持完整;部分恢复的 来源列表不会覆盖保存到其上。

四个缓存消耗文件保存安全定位器、覆盖聚合 以及前 20 个脱敏问题及其余问题的精确数量。模块函数体、 过程签名和原始表单记录不会进入其中。在 warm 启动时 检查来源的 sha256、筛选版本、定位器代次、每个索引的内部不变量 及其与单个目录的一致性。因此 结构或语义损坏的集合被视为整体未命中,而非部分旧答案的来源。损坏或只读缓存不会 使来源崩溃:服务器在内存中执行 cold 重建并发布完整 诊断,即使新缓存无法写入。发布的 cold 和 warm 答案在所有计数器和原因类别上一致。 每个表单的局部原因与受限列表分开存储:因此 get_object 在重启后显示所选对象的所有表单问题, 而不会把通用 /sources 变成无限答案。Reader 不读取超过 256 МиБ 的缓存文件, 也不解压超过 512 МиБ 的 payload;超过任一 限制——就是普通的 cache miss,直到 marshal.loads,而不是尝试耗尽内存。

最终版 selection v4 的实机验收已于 2026-08-21 在四个脱敏代码源(三个主要导出和一个扩展)上完成:

PYTHONPATH=src .venv/bin/python \
  tools/lab/measure_modules_acceptance.py --data data --timeout 120

脚本只打印一个不含名称和路径的 JSON。热启动耗时 3,676 秒,startup_problems_total = 0,进程峰值 856.2 MiB。目录证明了 8,650 个层级 .bsl、828 个来自 Form.bin 的模块、1,523 个扁平 .txt、1,079 个来自 .Form 的模块,以及 7 个无源码的已编译模块。共发现 6,150 个表单:3,331 个完整、1,330 个部分、1,489 个未读取。精确的限制类别:descriptor_only=671、invalid_syntax=1598、known_marker_semantics_incomplete=659、form_structure_missing=561、compiled_without_source=7;此语料库中没有未知标记、预算超限、损坏容器和冲突。这里的零是这些特定来源的测量结果,而不是对任何未来格式提供支持的承诺。

此前 2026-08-21 在三个代码源冷缓存上的后台响应性测量:在 72.12 秒内对每个路径完成了 73 次秒级调用,无失败。该计时器在 /health 就绪后开始,而下方 125 秒的容器测量是从容器启动到所有代码源 ready 为止。/health 响应中位数为 5.76 毫秒,最差 171.01 毫秒;真实 search_objects 分别为 8.11 和 172.49 毫秒。容器达到 healthy,全部 12 个缓存文件已发布。如需复现,请将 data/ 的副本(不含 index/cache/*.modules-*)挂载到单独容器中并运行:

.venv/bin/python tools/lab/measure_background_responsiveness.py \
  http://127.0.0.1:5002 /путь/к/копии/data

最终镜像的内存在 2026-08-21 selection v4 之后重新测量:四个代码源和 16 个模块索引缓存文件。仅删除消耗性缓存后的冷启动耗时 111.216 秒,同一容器在全部 16 个文件的 dev、ino、大小和 mtime_ns 均未变化的情况下的热重启为 11.495 秒。

状态

memory.peak cgroup

memory.current 在 ready 后

RSS PID 1

HWM PID 1

docker stats

冷重建

1 404 649 472 B(1 339.6 MiB)

1 400 582 144 B(1 335.7 MiB)

762 180 KiB(744.3 MiB)

764 228 KiB(746.3 MiB)

728.3 MiB

热启动

612 851 712 B(584.5 MiB)

599 142 400 B(571.4 MiB)

570 180 KiB(556.8 MiB)

570 180 KiB(556.8 MiB)

533.2 MiB

两次容器均达到 healthy;restart_count = 0,oom_killed = false。在两次最终运行中,traceback、exception、critical 和 error 每个术语的行数恰好为 0 行。cgroup 值包含内核页缓存,因此它们自然不同于进程 RSS 和 docker stats 读数。这是该特定语料库大小的参考,而不是设置 mem_limit 的依据。

脚本只打印一个仅含聚合数据的 JSON:时长、来源和缓存数量、cgroup 和 PID 1 字段、docker stats、健康状态、重启次数、OOM 和日志术语计数器。来源名称、本地路径和日志行不打印。在 cold 模式下,它构建最终镜像,预先停止容器,并删除仅由当前来源的工作名称函数计算出的精确 modules-toc、modules-calls、modules-forms 和 modules-search 文件。index/cache 目录和这些目标本身不能是符号链接;多余或混合的名称集不算就绪。停止后,目录以 O_NOFOLLOW 打开,其 dev/ino 与最初验证的目录核对。目标通过 dir_fd 列出和验证,仅通过同一描述符删除精确的基名:将父目录替换为符号链接不会引向外部,而硬链接只会丢失内部链接。然后脚本执行 --force-recreate。测量器本身不删除或替换来源、解压后的代码或 registry.json。运行中的服务器在启动和后台构建期间正常原子地更新 registry.json 状态;测量在代标记中考虑这些写入。就绪不仅要求 healthy,还要求 sha256、loaded_at 和来源本身的绑定不变,所有者配置的 sha256 相同,状态为 ready,且每个来源恰好有四个缓存。正常重启时,配置元数据会重新解析并获得新的运行时 loaded_at;测量器只允许这一转换,然后要求新代的两个相同快照。读取内存、docker stats 和日志后,最终检查先读注册表,再读缓存,再读注册表;两个标记必须与就绪代匹配。标记还包括 registry.json 本身的 dev、ino、大小和 mtime_ns,因此即使写入相同字节也算新代。warm 模式在停止前记住每个精确缓存文件的 dev、ino、大小和 mtime_ns。在 docker stop 之后、docker start 之前,它立即以 O_NOFOLLOW 重新打开目录,通过持有的 dir_fd 核对目录的 dev/ino 和整个文件快照;就绪时和最终检查中也要求相同快照。重建、覆盖或损坏文件会使整个结果无效。--timeout 和 --poll-interval 是有限的正秒数;单一的 timeout 余量限制每个 Docker 命令。

.venv/bin/python tools/lab/measure_container_memory.py --mode cold --data data \
  --timeout 300 --poll-interval 0.5
.venv/bin/python tools/lab/measure_container_memory.py --mode warm --data data \
  --timeout 300 --poll-interval 0.5

扩展导出也放在同一位置 data/incoming/,并用同一个按钮解析。 服务器自行根据归档内的 Configuration.xml 判断导出类型——人仍然只选择扩展所附加的配置,而不是单独的按钮或“这是扩展”字段。扩展作为独立来源 <配置名>:ext:<扩展名>(类型 extension)建立,而不是 <配置名>:modules:扩展名取自其自身导出的 Name 标签,而非由人编造。代码放入自己的目录 data/extensions/<配置名>/<扩展名>/——与 data/modules/<配置名>/ 相邻,但不在其内部,因此第二次导出不会覆盖第一次。一个配置可以有任意数量的扩展——配置模块仍然恰好一个导出,和以前一样。

扩展的身份是其导出内的 Name 标签,而不是文件名或整个内容。 人可以随意重命名归档:两个文件名不同但 Name 相同的文件会重新解析为同一个来源——第二次解析只是更新代码和 origin(最后解析的文件名),键和目录不变。同一规则的另一方面:如果两个不同扩展的 Name 在清除路径不允许的字符后相同(例如 Прайс/Розница 和 Прайс:Розница 产生相同的目录名),它们也会合并为一个来源——第二次解析会覆盖第一个的代码。对于普通名称(不含字母、数字、连字符、下划线、点和空格以外的字符),清除不会改变任何内容,也不会发生这种冲突。

识别是双方的正向规则,检查顺序很重要。 偏向配置的错误更危险:意味着进入模块分支并完全删除已解析的配置代码。因此首先查看扩展的强特征(ObjectBelonging、ConfigurationExtensionPurpose)——只要看到一个,无论 CompatibilityMode 如何都不会进入模块分支:接下来只在“扩展”(四个条件全部满足:两个强特征、非空 NamePrefix、无 CompatibilityMode)和拒绝之间决定。只有当完全没有扩展的强特征时,才由 CompatibilityMode 决定:非空——配置,空或无标签——拒绝。其他一切也是拒绝并附说明,不触碰磁盘上的任何内容:Configuration.xml 未找到(不仅在归档根目录中搜索,还在唯一的顶层目录中搜索——这样归档由 zip -r 归档.zip 文件夹 命令创建,macOS Finder 归档的辅助 __MACOSX/ 和 .DS_Store 不会干扰)、无法读取(CRC 损坏、记录截断)、无法解析为 XML、不携带可识别的结构,或声明的文件大小不合理地过大。

放在哪里。 放在 data/incoming/ 中,而不是通过“来源”页面的上传表单——那里没有此字段。目录由服务器在启动时创建,因此从第一次运行起就存在。然后在“来源”页面(仅限以 ADMIN_TOKEN 登录者)出现“传入导出”块,带有“解析”按钮。

只扫描目录本身,不扫描嵌套子目录。 放在 data/incoming/Розница/ 中的归档服务器不会看到——也不会对此说任何话,因为没有什么可显示的。

文件复制期间没有按钮。 1.5 GB 的 cp 需要几分钟,而文件从第一秒起就在目录中可见:修改时间不到五秒前的归档,其状态显示为“文件仍在复制”,sha256 完全不计算(反正会过期),解析此类文件会被拒绝并附说明。请等待复制结束并刷新页面。

重复解析会整体覆盖目录——但仅在成功后。 更新后的导出按钮标记为“重新解析”:data/modules/<配置名>/(或扩展目录)的旧内容被新内容整体替换,否则新导出中不存在的文件(已删除的对象、重命名的模块)会永远留在那里,两次导出会混合。解压同时进行到旁边的临时目录,不影响之前的解析:如果 extract 中途失败(模块 CRC 损坏、空间不足、权限)或提取了零个文件,则根本不会写入工作目录——注册表和磁盘不会不一致。替换不是原地删除旧的,而是换位(“将旧的重命名到一边 → 将新的重命名到其位置 → 删除搁置的”):如果新的无法移到旧的位置,服务器尝试将旧的恢复到原来的位置。如果这也失败(两个重命名的失败性质通常相同——权限、同一个 bind-mount),解析明确拒绝并在文本中说明两个路径:旧解析物理上在哪里,新的空或部分解压的在哪里,以便可以手动恢复目录;服务器不会对不存在的目录默默显示“已解析”。中断过程中留下的残片(.tmp-*)会在下次解析同一配置或扩展前清除——保存的旧解析副本(.old-*),如果到了那一步,本身不会被删除:由人决定。重新解析不改变目录权限——新目录获得旧目录的权限(如果目录尚不存在则为常规权限),而不是创建临时目录时使用的受限权限。

同一来源的并发解析按顺序执行:新请求立即取消前一代,但等待其临时目录工作完成。因此一个解析不能删除另一个活动的 .tmp-*,工作目录和缓存只由最后一代获得。被取消的请求以明确错误结束;等待的过期请求根本不开始解压。不同配置和不同来源键的扩展互不阻塞。

«Отбор устарел» — состояние на случай, когда меняется не файл, а правило. Каждый разобранный источник помнит версию правила отбора (внутренняя SELECTION_VERSION: что берём из архива и куда кладём). Если код на диске разобран старой версией правила, источник показывается как «отбор устарел», а не «разобрано» — хотя архив на incoming/ тот же самый файл, с тем же sha256. Кнопка подписана «переразобрать», как у обновлённой выгрузки: код на диске перетирается заново, уже по нынешнему правилу. Прежний разбор сам по себе не переписывается — правку правила отбора человек видит только после нажатия кнопки. Источник, разобранный до появления этого поля (запись без selection_version в старом registry.json), тоже считается устаревшим: версия у него неизвестна, а не «наверняка свежая» — иначе человек никогда не увидел бы «переразобрать» для кода, который никогда не проходил через нынешнее правило. Текущая версия 4 сохраняет XML-дескрипторы форм и иерархические Ext/Form.bin; источник версии 3 поэтому обязательно показывается устаревшим и получает эти файлы только после явного переразбора. Версия отбора входит в штамп кэша: старый кэш не принимается даже для того же неизменившегося ZIP. Перед заменой каталога сервер пишет короткий журнал рокировки; после аварийной остановки следующий запуск по registry.json либо завершает новое поколение, либо возвращает прежний каталог.

Мусор архиватора Finder на macOS в код не попадает. Архив, собранный командой «Сжать объекты», несёт служебный __MACOSX/ с копиями ресурсных вилок каждого файла (._Имя, тот же суффикс, что у оригинала) — отбор их пропускает, как и любое имя, начинающееся на ._, где бы оно ни лежало.

Обёртка архива не воспроизводится в пути на диске. Архив, упакованный командой zip -r архив.zip папка или через Finder («Сжать объекты») — вся выгрузка лежит внутри одного каталога верхнего уровня, — при раскладке на диск этот уровень не повторяется: код ложится как data/modules/<ИмяКонфигурации>/Catalogs/…, а не data/modules/<ИмяКонфигурации>/папка/Catalogs/…. Правило распознавания обёртки общее с поиском Configuration.xml внутри неё (то же самое место абзацем выше, «Распознавание»): служебный __MACOSX/ и корневой .DS_Store в счёт не идут, а несколько каталогов верхнего уровня обёрткой не считаются — угадывать, какой из них «тот самый», сервер не станет. Санитизация путей (отказ членам, ведущим наружу корня) применяется уже после снятия обёртки, а не вместо неё.

Удаление источника уносит и код. Кнопка «удалить» у источника <ИмяКонфигурации>:modules сносит data/modules/<ИмяКонфигурации>/, а у источника расширения <ИмяКонфигурации>:ext:<ИмяРасширения> — только его собственный каталог data/extensions/<ИмяКонфигурации>/<ИмяРасширения>/: модули конфигурации и другие расширения той же конфигурации не задеваются. Иначе сотни мегабайт остались бы занятыми невидимо: в разделе «Исходные файлы» они не показываются, там только data/sources/.

Архив, в котором не нашлось ни модулей, ни форм, отклоняется. Выгрузка структуры метаданных — тоже .zip, и без этой проверки она заводила бы источник на ноль файлов с состоянием «разобрано». Её подают формой «Загрузить» на этой же странице.

Почему не через браузер. Архив весит гигабайт с лишним — у типовой конфигурации розничных продаж 2.3.10.5 это 1 380 МБ. Форма загрузки на «Источниках» построена под метаданные в единицы мегабайт и на таком файле не работает сразу по трём причинам: предел загрузки 500 МБ; тройное копирование с пиком около 4 ГБ — буфер приёма тела запроса, временная копия во mkdtemp() и копия на сам том; и сама передача больше гигабайта по HTTP без возможности продолжить после обрыва. Файл на томе все три ограничения обходит: копируется обычным cp, а сервер читает архив членом за членом, не разворачивая его целиком ни разу.

Что остаётся на диске. Не весь архив — только модули (.bsl у иерархической выгрузки, .txt и канонические скомпилированные CommonModules/<Имя>.Module или CommonModule.<Имя>.Module у плоской) и формы: XML-дескриптор, Form.xml и Form.bin у иерархической, контейнер .Form целиком у плоской. Form.bin и .Form сохраняются без изменений как источник для провайдера кода; производный .bsl при приёме не создаётся. Текстовые макеты *.Template.txt не принимаются за модули. Контейнер сохраняется как есть, вместе с двоичной записью формы: код обычной формы лежит внутри него записью module, и разбирать контейнер на приёме означало бы тащить сюда разбор формата 1С.

После распаковки физическое дерево перечисляется один раз в неизменяемый каталог канонических адресов и безопасных локаторов. Оглавление, вызовы, формы и поиск получают один и тот же снимок: обычные .bsl/.txt читаются как файлы, код Form.bin/.Form — как запись module исходного контейнера, скомпилированный .Module остаётся адресом без придуманного тела. Одинаковые тексты одного адреса после общей нормализации дедуплицируются; разные не получают молчаливого приоритета и исключаются как конфликт.

Код конфигурации ложится в data/modules/<ИмяКонфигурации>/, код расширения — в свой каталог data/extensions/<ИмяКонфигурации>/<ИмяРасширения>/; актуальные журналы покрытия — в data/logs/. Все три вида защищены правилами **/modules/, **/extensions/ и **/logs/ в .gitignore. Замер python3 tools/lab/measure_intake.py <архив>..., прогон 2026-08-19:

Что

Архив

Развёрнуто

Отбираем

типовая конфигурация розничных продаж 2.3.10.5

1 380 МБ

2 063 МБ, 33 188 файлов

351,4 МБ, 11 072 файла

расширение к ней

1 МБ

8 МБ, 453 файла

6,9 МБ, 155 файлов

Живой прогон самого приёма на тех же файлах — не оценка по каталогу zip, а реальный вызов intake.planned_size, intake.enough_space и intake.extract, замер python3 tools/lab/measure_intake_run.py <каталог для распаковки> <архив>..., прогон 2026-08-19: оценка требуемого места на архиве в 1,4 ГБ — 0,15 с (читается только центральный каталог zip, тело не трогается вовсе), распаковка — 3,1 с, пик RSS процесса — 111 МБ. Файлов и байт, которые вернул extract(), и того, что фактически легло на диск, — поровну, скрипт сверяет это сам.

Исходник сервер не удаляет. Каталог data/incoming/ серверу удалять запрещено — файл остаётся на месте и после успешного разбора; повторный разбор того же архива его не трогает, сверка идёт по sha256 с кэшем на странице (считать хеш гигабайта при каждом обновлении списка нельзя).

Источник заводится под ключом <ИмяКонфигурации>:modules, а не именем конфигурации: тот же ключ, что у метаданных, при загрузке вытеснил бы их из реестра. Какая конфигурация — хозяйка выгрузки, решает человек. Если в реестре загружена ровно одна, выбор не нужен: поля рядом с кнопкой на странице нет, разбор берёт единственную сам. Если загружено две и больше, рядом с кнопкой появляется выпадающий список загруженных имён — какую выбрали, к той код и привязывается. Имя из формы сверяется со списком загруженных: неизвестное отклоняется до начала разбора, с объяснением. Автоматическая привязка по манифесту выгрузки (без участия человека) пока не сделана. Платформа источника модулей берётся у конфигурации, к которой он привязан, — сама выгрузка в файлы точной сборки платформы не содержит, только режим совместимости, а это другое число. У расширения выбор конфигурации работает так же (см. выше «Выгрузка расширения кладётся туда же»); вид выгрузки — модули или расширение — сервер различает сам по Configuration.xml, отдельного поля или кнопки для этого на странице нет.

Нехватка места — отказ до начала. После выбора конфигурации и вида источника реестр сверяет свободное место на томе до распаковки. Требуется объём безопасно отобранных файлов плюс резерв индекса: 15% с округлением вверх, но не меньше 25 МБ. Формула одинакова для первой загрузки и переразбора: занятый старым корнем объём уже исключён из значения свободного места, повторно прибавлять его нельзя. Не хватает — разбор не начинается, а причина с обеими цифрами в мегабайтах остаётся на странице «Источники» и переживает перезапуск. Прямой вызов реестра проходит ту же проверку; при ошибке или заполнении тома прежний разбор остаётся на месте.

Скомпилированный *.Module виден в сводке и в перечне модулей как ОбщийМодуль.<Имя>, но процедур и тела у него нет: search_procedures, get_procedure и get_callers говорят об этом прямо и не выдают пустой индекс за доказательство отсутствия процедуры.

Кнопка «разобрать» требует ADMIN_TOKEN — как любая другая запись: без токена этого маршрута не существует, а не «он закрыт».

Применить изменения без перезапуска

Работающий сервер держит реестр в памяти, поэтому после reg-add его нужно подтолкнуть. Либо перезапуск (docker compose restart mcp1c, около 2 секунд), либо админ-ручка:

# включается переменной ADMIN_TOKEN; без неё маршрут отключён
ADMIN_TOKEN=секрет docker compose up -d
curl -X POST -H "x-admin-token: секрет" http://localhost:5001/admin/reload

Словарь: как говорят против того, как названо

Главная сложность поиска — разрыв между словами человека и именами в конфигурации. «Заказ клиента» — а объект называется ЗаказПокупателя. Словарь лежит в data/dictionary.json, правится без пересборки образа.

Два механизма, и они разные.

Синонимы слов — общие для всех конфигураций:

python3 -m mcp1c.cli dict-synonyms клиент покупатель заказчик

Псевдонимы объектов — прямое указание «когда я говорю так, я имею в виду вот эти объекты», вес выше любого текстового совпадения. Два десятка типовых фраз («файлы», «товары», «клиенты», «сотрудники», «задачи») встроены и работают сразу; если объекта в конфигурации нет, псевдоним не применяется. Свои добавляются с привязкой к конфигурации:

python3 -m mcp1c.cli dict-alias "справочник физлиц" \
    Справочник.ФизическиеЛица Справочник.Пользователи \
    --config РозницаДляКазахстана
«справочник физлиц»
    Справочник.ФизическиеЛица     псевдоним из словаря
    Справочник.Пользователи       псевдоним из словаря

Существование объектов проверяется при добавлении — псевдоним на опечатку бесполезен. Посмотреть содержимое: dict-show, удалить: dict-alias «фраза» --remove.

Изменения применяются перезапуском контейнера или POST /admin/reload — пересобирать образ не нужно. Перезагрузка выполняется вне event loop, поэтому /health и MCP-запросы продолжают обслуживаться во время восстановления.

Поисковые ключи языка запросов — третий механизм, и правится он только в коде (search_keys.py) с обычной проверкой изменений. Разрыв тут другой природы: человек не называет конструкцию чужим словом, а описывает задачу. «Количество дней между двумя датами» против РАЗНОСТЬДАТ, «убрать повторы» против РАЗЛИЧНЫЕ — общих слов ноль, и синоним не поможет, заменять нечего.

Поэтому к 116 страницам из 127 приписаны формулировки, которыми их спрашивают, и попадают в поисковый индекс отдельным полем. В рантайме не весят ничего. Результат на живом наборе: 57,9% → 94,7% первым местом, без регресса на 61 тысяче автоматических запросов.

Ключи сочинены нами, а не выгружены, и отсюда три ограничения:

  • живут отдельным слоем в git, а не приписываются разобранному элементу;

  • в ответ агенту не попадают — ответ по-прежнему собирается только из справки, ключи работают исключительно на попадание в нужную статью;

  • привязаны к страницам по идентификатору, и если справка даст другой набор страниц, расхождение называется при загрузке, а не проявляется молча просевшим поиском.

Правило целиком — в docs/data-sources.md, раздел «Сгенерированные слои поверх источников».

Посмотреть, что загружено

docker compose exec mcp1c python -m mcp1c.cli reg-list --data /data
РозницаДляКазахстана  2.3.10.5  платформа 8.3.23.1997
  объектов 5637, связей 44034, загружено 2026-08-18T12:22:16+00:00
  метаданные : да
  синтаксис  : справка 8.3.27, новее конфигурации, скрыто 874
  модули     : не загружен
  язык запросов: подключён, 127 страниц

Конфигураций может не быть вовсе — сервер при этом работает, если загружена хоть одна справка: отвечают search_syntax и get_syntax, config указывать не нужно. reg-list в этом случае перечисляет подключённое и возвращает 0:

Конфигурации не загружены. Подключено:
  язык запросов, 127 страниц
Работают search_syntax и get_syntax, без фильтра по версии.

在完全空的注册表上——显示“未加载任何内容。”并返回代码 1。任何需要配置的命令,都会在那里说明具体缺少什么,以及每项由什么提供。reg-list 不等待冷构建:对于主配置和每个扩展,它显示与 /sources 和 list_configurations 相同的原子状态——就绪的计数器、阶段和进度、错误或代码缺失。

无需代理调试——mcp1c.cli

CLI 访问与 MCP 工具相同的注册表和相同的函数。如果它回答正确——问题出在客户端配置,而不是服务器。

命令分为三组。按注册表——与代理看到的内容相同:

PYTHONPATH=src python3 -m mcp1c.cli reg-list  [--data data]
PYTHONPATH=src python3 -m mcp1c.cli reg-add   Выгрузка.zip     [--data data]
PYTHONPATH=src python3 -m mcp1c.cli reg-add   shcntx_ru.hbk    [--data data]
PYTHONPATH=src python3 -m mcp1c.cli reg-search "чек ккм"  --config РозницаДляКазахстана
PYTHONPATH=src python3 -m mcp1c.cli reg-search "разделить строку" --syntax --limit 5
PYTHONPATH=src python3 -m mcp1c.cli reg-search-procedures "провести документ" \
    --config Пример --scope Документ.Чек --limit 10
PYTHONPATH=src python3 -m mcp1c.cli reg-get-procedure \
    'Документ.Чек.МодульОбъекта::ОбработкаПроведения' \
    --config Пример --start-line 0 --lines 200
PYTHONPATH=src python3 -m mcp1c.cli reg-get-callers \
    'Документ.Чек.МодульОбъекта::ОбработкаПроведения' \
    --config Пример --limit 20

不带 --syntax 的 reg-search 按元数据搜索,带该参数则按帮助和查询语言搜索。三个代码命令镜像同名的 MCP 工具并打印相同的响应:reg-search-procedures QUERY 接受 --config、--extension、--scope、--limit(默认 10);reg-get-procedure ADDRESS 接受 --config、--extension、--start-line(0)和 --lines(200);reg-get-callers ADDRESS 接受 --config、--extension 和 --limit(20)。所有三个命令的 --data 默认等于 data。在冷的一次性启动时,这些命令等待后台构建不超过 90 秒,以便进程不会在结果和四个缓存文件写入之前终止 daemon 线程。如果时间不够,命令返回显式错误;服务器不使用此等待,并继续显示进度。

直接按文件,不经注册表——在数据进入服务器之前查看导出:

PYTHONPATH=src python3 -m mcp1c.cli info    Выгрузка.zip
PYTHONPATH=src python3 -m mcp1c.cli stats   Выгрузка.zip
PYTHONPATH=src python3 -m mcp1c.cli show    Выгрузка.zip Документ.ЧекККМ --detail full
PYTHONPATH=src python3 -m mcp1c.cli related Выгрузка.zip Документ.ЧекККМ --depth 2
PYTHONPATH=src python3 -m mcp1c.cli find    Выгрузка.zip реализация --limit 10

路径是 ZIP 或解压后的目录,格式根据清单确定。

搜索词典——同义词是通用的,别名绑定到配置:

PYTHONPATH=src python3 -m mcp1c.cli dict-show                       # правила и их происхождение
PYTHONPATH=src python3 -m mcp1c.cli dict-show --all --config Розница...
PYTHONPATH=src python3 -m mcp1c.cli dict-synonyms чек ккм касса     # группа взаимозаменяемых слов
PYTHONPATH=src python3 -m mcp1c.cli dict-synonyms чек ккм --remove
PYTHONPATH=src python3 -m mcp1c.cli dict-alias "справочник физлиц" Справочник.ФизическиеЛица
PYTHONPATH=src python3 -m mcp1c.cli dict-alias "справочник физлиц" --remove

dict-show 显示每个规则的来源——这是分析“为什么搜索表现如此”的起点。

搜索质量测量——mcp1c.bench

单独的测试台,因为没有数字的“变好了”只是意见。

PYTHONPATH=src .venv/bin/python -m mcp1c.bench \
    --data data --config РозницаДляКазахстана \
    --auto --sets query-language,roznica-metadata,modules-procedures \
    --check-notes

键

作用

--data 路径

服务器数据目录,默认 data

--sets 名称,名称

来自 tests/queries/*.json 的手动 schema v1 集合,不带扩展名

--auto

按帮助自动生成的集合:精确名称和同名

--config

配置;如果加载了多个则必填

--extension

用于过程集合的单独扩展代码语料库;不带该键则测量基础代码

--limit

结果深度,默认 10

--save 路径

保存运行结果以供比较;按约定为 data/bench/ГГГГ-ММ-ДД.json

--baseline 路径

与之前的运行比较——逐一点名谁换了位置

--check-notes

将集合中的备注与查询所占的位置进行核对

每个手动 JSON 包含 schema_version: 1、显式的 domain——syntax、metadata 或 procedures——以及 cases 数组。文件名不选择索引。在 procedure 集合中,expected 存储不带模块名称的 BSL bare 名称;测试台不区分大小写地将名称展开为所选语料库的所有精确地址。这样可以发布可复现的表述,而不暴露具体实现的结构。可选的 expected_miss: true 和基于零的 expected_rank 在 --check-notes 时机器核对已固定的 baseline;这不是 pytest 的质量阈值。旧的根 JSON 数组和没有版本的旧 baseline 被显式拒绝:需要重新创建。--save 首先原子地替换报告文件,然后才打印结果:写入错误不会在磁盘或 stdout 上留下部分报告。

打印 P@1/P@3/P@5/P@10、MRR、“外部域排第一”的比例以及第一个结果与第二个结果之间的中位差距。故意没有 assert 阈值:查询集合不是测试,百分比会因词典的每次修改而破坏。代码 1 表示备注不一致;代码 2 表示整个测量在打印和保存之前因无效集合、歧义选择或索引未就绪而被取消。如果在过程集合期间代码发生变化,整个集合将按一个索引代从头重新运行。

两次运行的比较如下所示(恶化排在最前):

=== сравнение с прошлым прогоном ===
  - «как прибавить месяц к дате в запросе»: 1 -> промах
  - «как отсортировать результат запроса»: 1 -> 5
  + «в чем разница между внутренним и левым соединением»: 5 -> 4

集合不包含在镜像中(tests/ 在 .dockerignore 中)——从工作副本运行,而不是从容器中运行。

手动启动服务器——mcp1c.server

PYTHONPATH=src python3 -m mcp1c.server --data data          # streamable-http на :8000/mcp
PYTHONPATH=src python3 -m mcp1c.server --transport stdio    # локальному клиенту
PYTHONPATH=src python3 -m mcp1c.server --host 0.0.0.0 --port 5001

--transport 没有其他值。过时的 HTTP+SSE 已完全禁用:--transport sse 标志在读取数据和启动服务器之前就被拒绝。

原始数据来源

配置结构——通过 exporter-1c/ 中的处理生成。四种模块变体适用于普通和受管表单、XML 和 JSON;XML 变体兼容 8.3.5。两个处理已编译好,可直接打开:ВыгрузкаСтруктурыКонфигурации_ОбычнаяФорма_XML.epf(8.3.5 及以上)和 ВыгрузкаСтруктурыКонфигурации_УправляемаяФорма_XML_JSON.epf(8.3.6 及以上,格式在表单上选择)。

平台帮助——来自 1C 安装目录的 shcntx_ru.hbk 文件:

/opt/1cv8/<версия>/shcntx_ru.hbk
C:\Program Files\1cv8\<версия>\bin\shcntx_ru.hbk

名称必须完全匹配。 同一目录中有数百个 .hbk 文件——38 种不同的帮助,每种有二十多种语言。与所需文件相似的:

文件

这是什么

为什么不适用

shcntx_root.hbk

同一帮助,语言无关部分

25 508 个元素,但没有任何描述:只有页面树和英文标识符,没有出现版本

shlang_ru.hbk

内置语言描述

根本不是 1C 容器

shquery_ru.hbk

查询语言

同上

config_ru.hbk

配置器帮助

是容器,但内部没有语法助手页面

1cv8_ru.hbk

用户手册

不是容器

按大小无法区分:shcntx_root.hbk 为 33 MB,而所需文件为 39 MB。后缀 _ru 是语言,_root 是不含文本的公共部分。

文件不对——服务器解释具体原因,并保留原有帮助不动。

只需一份来自最新可用平台的帮助即可:每个元素都带有出现版本,对于旧配置,多余内容会被过滤掉。如果路径中没有版本,则从数据本身推导。

旧平台的帮助也接受——它们的标记方式不同(章节用 div 而不是 p),这已考虑在内。如果为旧部署搭建独立服务器,这会很有用:8.3.5 的帮助提供 18 936 个元素,不包含 СтрНайти、СтрРазделить、ЗаписьJSON——8.3.5 中本来就没有这些。但这种帮助不报告自身版本:其中没有“从版本开始”的标记,因为当时一切都是当前的。因此版本取自文件名或目录名——将其命名为 8.3.5.1570.hbk 或放在 data/hbk/8.3.5.1570/ 中,否则与配置的匹配将无法工作。


5. 工作原理

src/mcp1c/
  v8container.py     контейнер 1С — общий для .hbk, .cf, .epf
  syntax_parser.py   разбор справки платформы
  syntax_model.py    модель элемента справки, виды, границы версий
  syntax_merge.py    слияние справок разных версий в один индекс
  query_parser.py    разбор справки по языку запросов (shquery_ru.hbk)
  replacements.py    чем заменить функцию, которой нет в старой платформе
  virtual_tables.py  таблицы запроса регистров и имена их полей
  loader.py          чтение выгрузок, XML и JSON в одну модель
  model.py           модель конфигурации
  graph.py           граф связей
  graph_view.py      окрестность объекта для картинки на дашборде
  search.py          лексический поиск
  search_keys.py     формулировки, которыми спрашивают язык запросов
  synonyms.py        встроенный словарь: как говорят против того, как названо
  dictionary.py      локальный словарь поверх встроенного
  index_cache.py     кэш поисковых индексов, расходный
  modules_index.py   оглавление, вызовы и формы для get_callers
  store.py           чтение и запись разобранных справок
  render.py          markdown-карточки объектов и элементов
  intake.py          отбор и распаковка выгрузки в файлы, санитизация имён
  incoming.py        состояние data/incoming: кэш sha256, причина отказа
  registry.py        реестр источников, сопоставление версий
  tools.py           десять инструментов, без зависимости от MCP
  server.py          протокольный слой (единственная внешняя зависимость)
  dashboard.py       веб-интерфейс: реестр, запросы, словарь
  cli.py             отладочный CLI
  bench.py           стенд замеров качества поиска

一个模型,两种格式。 XML 和 JSON 是同一 schema 的不同序列化;加载器将两者转换为相同的字典。已验证:两种导出产生相同的 30 个键的集合。

图由加载器构建,而不是 1C。 边从属性类型、文档流转、输入依据、所有者、订阅处理器和计划任务方法中推导。规则可以在不重新导出的情况下修改。

弱边。 像 ЗначениеДоступа 这样的属性枚举了数百种类型,几乎把所有东西都关联起来。这些关联被标记为弱关联,默认隐藏——否则有用的信息会被淹没。

详细程度。 Документ.ЧекККМ 的完整描述(50 个属性、17 个表格部分)会完全消耗上下文。brief 是几行,fields 是组成,full 是带关联的。

无外部数据库。 生产索引保持在一个进程中:紧凑的代码数组无需单独的网络跳转即可响应,搜索耗时 0.18–1.5 毫秒。Elasticsearch、向量存储和图数据库在此数据量下不值得单独的进程和维护。向量搜索还需要编码器模型(镜像增加 185–620 MB)和仅编码查询就需要 16–32 毫秒。

在真实数据上测量——2026-08-18

工作服务器上加载的内容:

配置

平台

对象数

边数

哈萨克斯坦会计

8.3.27.1936

3 492

84 426

文档流转 КОРП

8.3.27.1936

4 596

50 554

薪酬与人事管理

8.3.27.1936

5 181

100 136

哈萨克斯坦零售

8.3.23.1997

5 637

58 345

行业配置

8.3.5.1570

1 616

29 288

总计

20 522

322 749

集合是随机的——这是手头现有的。重要的不是配置本身,而是平台的多样性:8.3.5、8.3.23 和 8.3.27 在同一个注册表中,每个配置按自己的平台响应。

加上平台帮助——三个版本(8.3.5、8.3.23、8.3.27)的合并索引,25 691 个元素,以及查询语言——127 页作为独立来源。

最终镜像带 12 个模块索引缓存文件的暖启动——在 2026-08-21 测量的工作语料库上为 19 秒。冷启动时,源码被解析,索引被构建并存入 data/index/cache/,解析后的帮助存入 data/index/syntax/。之后从那里加载。

缓存是派生的、可消耗的:绑定到 Python 版本、包代码指纹和源哈希。任何一项不匹配——索引将重新构建。目录可以随时删除,它会自行恢复。如果缓存卷是只读的,无法删除过时文件不会中断源从注册中移除。

registry.json 中的记录顺序不重要:代码只在其配置之后恢复。如果配置记录不存在、在运行期间被删除或替换,旧的模块或扩展记录不会在没有所有者的情况下发布。

搜索索引的 posting 位于 numpy 数组中;临时字典填充在冻结后立即释放。服务器的总 RSS 不能通过将隔离层相加获得:冷峰值和容器预热状态在提升所有源之后分别测量。

模块文本——代码工具已连接

配置导出到文件的接收已实现——上文“配置导出到文件”部分:代码和表单写入磁盘,源在注册表中登记,四个内部索引被构建并缓存。search_procedures 按词搜索精确名称和导出过程,get_procedure 返回模块目录或带主体窗口的卡片,get_callers 合并已确认的调用位置、元数据绑定和表单处理器,无需读取主体。

截至 2026-08-21 主配置的当前生产快照:137 116 个过程、619 029 个调用位置、3 194 个表单、89 528 个表单元素和 24 202 行事件绑定行。

可在自己的导出上复现,无需打印其名称或路径:

MODULES_ROOT=/путь/к/выгрузке
.venv/bin/python tools/lab/measure_modules_cache.py "$MODULES_ROOT"

测量器打印 JSON-聚合,键为 procedures、calls、forms、elements 和 event_rows。最后一个计数器是 <Event> 的原始行,在公开绑定中分组和去重之前。

原型的历史快照于 2026-08-20 在脱敏的分层导出上采集到文件中:7 878 个模块、137 115 个过程、260 MB 文本。下面保存的正是它的数字,而不是当前的聚合。

层

磁盘上

内存中

137 115 个过程的目录

14,9 MB

62 MB

619 030 个已解析和未解析的调用点

12,0 MB

51 MB

按 49 181 个导出过程搜索

4,27 MB

173 MB

表单:3 194 个文件,69 769 个元素

5,8 MB

44 MB

模块文本和签名

260 MB

0

搜索延迟为 1,2–1,5 毫秒。四个索引的完整冷构建并写入缓存约需 50 秒。

文件导出有两种不同的版本,第二种单独测量过——行业配置 10.5.1.3 在 8.3.5 上:扁平布局,模块为 .txt,普通表单的代码在二进制容器 .Form 内。2 603 个模块、33 555 个过程,解析 1,1 秒,按全部 94 MB 搜索中位数为 0,2 毫秒。该格式不包含表单结构,部分通用模块以编译形式提供——其中根本没有源代码。这些模块可通过地址 ОбщийМодуль.<Имя> 看到,但无法读取其中的过程和调用。因此,汇总、搜索、普通模块目录、反向搜索和重叠信息会在结果上方提示:聚合仅按可用源代码给出,可能不完整。

测量脚本位于 tools/lab/;上面的每个数字都可以用它复现:

.venv/bin/python tools/lab/measure_modules_cache.py <каталог выгрузки в файлы>
.venv/bin/python tools/lab/measure_modules.py <каталог выгрузки в файлы>
.venv/bin/python tools/lab/measure_resident.py <каталог> <файл индекса> собрать
.venv/bin/python tools/lab/measure_search.py <файл индекса> экспортные
.venv/bin/python tools/lab/measure_forms.py <каталог>
.venv/bin/python tools/lab/measure_flat.py <каталог плоской выгрузки>
.venv/bin/python tools/lab/measure_container_memory.py --mode cold --data data \
  --timeout 300 --poll-interval 0.5
.venv/bin/python tools/lab/measure_container_memory.py --mode warm --data data \
  --timeout 300 --poll-interval 0.5

搜索质量

由测试台采集,一条命令即可复现:

PYTHONPATH=src .venv/bin/python -m mcp1c.bench \
    --data data --config РозницаДляКазахстана \
    --auto --sets query-language,roznica-metadata,modules-procedures \
    --check-notes

数据集

查询数

P@1

P@3

P@5

P@10

MRR

差距

查询语言

21

85,7%

85,7%

90,5%

90,5%

0,869

35,0%

零售元数据

21

81,0%

90,5%

90,5%

95,2%

0,862

93,2%

模块过程

3

0%

0%

0%

33,3%

0,047619

0%

帮助精确名称

50 926

97,1%

98,3%

98,7%

98,9%

0,978

91,7%

同名

10 544

98,7%

99,8%

99,9%

100%

0,992

93,9%

整张表于 2026-08-21 用上面的精确命令在只读模式下采集,未使用 --save;命令以代码 0 结束。三个手工数据集由真实表述和失误组成,后两个由数据本身构建。过程的排名为 [失误, 失误, 7]。这是改进的基线,而不是验收门槛。

过程行可单独更快地复现:

PYTHONPATH=src .venv/bin/python -m mcp1c.bench \
    --data data --config РозницаДляКазахстана \
    --sets modules-procedures

「差距」——第一个结果与第二个结果拉开多少,取中位数。回答「是稳中还是侥幸」的问题:查询语言 35% 对帮助 91,7% 意味着这些胜利的稳固程度弱三倍,排序调整可以在不移动 P@1 一个百分点的情况下翻转它们。

搜索延迟为每查询 0,18–1,4 毫秒,取决于数据集。

查询集不包含在镜像中(tests/ 在 .dockerignore 中):应从工作副本测量,而不是从容器中。

测试

.venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytest          # 1100 тестов (прогон 2026-08-21)

不依赖 data/ 的内容:仓库中没有专有导出,所有需要的内容都在 tests/conftest.py 中合成构建。

搜索质量不通过测试检查——它由测试台测量(mcp1c.bench,见「已测量」)。百分比阈值会因每次词典修改而破坏,因此测试台打印数字,由人做决定。pytest 检查可观察行为:「索引未重新构建」、「结果一致」、「启动未崩溃」。


6. 安全

两个令牌,都由环境变量设置。只要令牌未设置,相应的访问就对所有能触及该地址的人开放。

变量

保护什么

未设置时

API_TOKEN

读取:MCP 工具和仪表板页面

配置结构对所有人开放

ADMIN_TOKEN

写入:上传和删除源、解析传入导出(/sources/incoming/parse)、编辑词典、/admin/reload

这些路由被禁用,返回 404

「开放」和「禁用」之间的区别是有意为之。无令牌读取可以工作——在自

Available Tools

11 tools
compare_configurationsA

Сравнить один и тот же объект в двух конфигурациях: чем различаются имена реквизитов. Типы и содержимое табличных частей не сравниваются. Дочитайте все страницы по готовому вызову продолжения.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoЧисло различий на странице суммарно для обеих сторон, от 1 до 100.
cursorNoНепрозрачный курсор из продолжения. Привязан к паре, объекту и содержимому сравнения.
configsNoРовно два разных имени из `list_configurations`. Не заданы — автоматический выбор только при ровно двух загруженных конфигурациях; иначе выберите пару явно.
full_nameYesПолное имя объекта, которое ищется в обеих конфигурациях.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. It discloses the comparison limitation (only attribute names, not tabular-section types/contents) and warns that all pages must be read through the continuation call. This is meaningful behavioral context, though it does not address permissions or side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded: main purpose, comparison scope, and pagination instruction in three tight sentences. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the fully documented schema and existing output schema, the description covers the important behavioral details: what is compared, what is ignored, and pagination. It could slightly improve by referencing list_configurations for pair selection, but the schema already handles that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented. The description adds no additional parameter-level meaning beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: compare the same object across two configurations by attribute names. It also distinctly scopes what is compared and explicitly excludes tabular-section types and contents, making it clearly distinguishable from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context is given for when to use the tool: comparing one object's attribute names in two configurations. It does not explicitly name alternatives or when-not conditions, but the scope caveat and sibling list make the intended usage reasonably obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_callersA

Кто вызывает точную процедуру: подтверждённые места в коде с процедурой-владельцем, привязки подписок и регламентных заданий из метаданных, элементы и события формы. Одноимённые вызовы без разрешённого модуля показываются отдельно и не приписываются запрошенному адресу. Тела модулей не читаются.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoСколько мест вызова показать: целое число от 1 до 50. Оставшееся число подтверждённых мест и модулей указывается отдельно; одноимённые места без разрешённой цели тоже не выводятся без границы.
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.
addressYesТочный адрес процедуры `Модуль::Имя`, полученный из `search_procedures` или оглавления `get_procedure`.
extensionNoИмя одного загруженного расширения. Не задано — места в коде ищутся только в основной конфигурации; чужой код не подмешивается.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden, and it delivers. It discloses that only confirmed locations are returned, that unresolved same-name calls are shown separately, and that module bodies are not read. These are meaningful behavioral details beyond a generic 'returns callers' statement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact: three dense sentences that front-load the main purpose, then add scope caveats and a limitation. Every sentence earns its place, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and all parameters have rich schema descriptions, the definition is complete. The tool description covers scope, edge-case handling for unresolved same-name calls, and the fact that module bodies are not read, which is enough for an agent to use it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well documented in the schema. The tool description does not add extra parameter semantics, but it does not need to; the schema already explains address, limit, config, and extension. A baseline of 3 is appropriate here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Кто вызывает точную процедуру' — who calls the exact procedure. It then enumerates exact kinds of call sites (code locations, subscription/scheduled-job bindings, form items/events), making it clearly distinct from siblings like search_procedures or get_procedure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the intended use clear: given an exact procedure address, identify its confirmed callers. It also communicates an important scope rule by stating that unresolved same-name calls are not attributed to the requested address. It does not explicitly name alternatives or exclusion conditions, but the context is unambiguous enough for an agent to select it correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_objectA

Структура объекта конфигурации: реквизиты с типами, табличные части, движения, предопределённые. detail: brief | fields | full. Обязательный шаг перед написанием кода или запроса. Только здесь видно то, от чего код зависит и чего нет в поиске: вид и периодичность регистра (СрезПоследних есть лишь у периодического регистра сведений, а непериодических большинство), корреспонденция, предел субконто, и — для регистров — раздел «Таблицы запроса» с уже подставленными именами полей: ресурс Количество в запросе называется КоличествоОстаток или КоличествоОборот, и в конфигураторе таких имён не видно. Большие HTTP-сервисы и подсистемы дочитываются тем же get_object по готовому вызову с непрозрачным cursor; после смены поколения чтение нужно начать заново.

ParametersJSON Schema
NameRequiredDescriptionDefault
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.
cursorNoНепрозрачный cursor из ответа get_object для продолжения HTTP-сервиса или подсистемы. Передавайте без изменений с теми же full_name, config и detail.
detailNoУровень детализации: `brief` — пара строк со счётчиками, `fields` — состав для написания кода, `full` — со свойствами и связями. Полное описание крупного документа занимает много контекста, поэтому `full` только когда связи действительно нужны.fields
full_nameYesПолное имя объекта: `Документ.ЧекККМ`, `Справочник.Номенклатура`. Получается из `search_objects`.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It reveals the cursor-based continuation mechanism for large HTTP services and subsystems, warns that reading must restart after a generation change, and explains that the 'full' detail level consumes a lot of context. These are valuable behavioral traits beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long and dense, but the core purpose is front-loaded and the examples (e.g., 'СрезПоследних', 'КоличествоОстаток') justify the tool's necessity. Some redundancy exists with the schema's parameter descriptions, but overall each sentence contributes useful context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, when to use it, parameter semantics, detail-level trade-offs, and the cursor/generation-change behavior. An output schema exists, so return values are covered elsewhere. The description is sufficiently complete for an agent to invoke and interpret this complex tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful guidance: it explains the detail levels in context, warns about the context cost of 'full', and clarifies cursor usage with same full_name, config, and detail. This exceeds simple schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns the configuration object structure: attributes with types, tabular sections, movements, and predefined data. It goes beyond a generic 'get object' by explaining what is included and why it is unique compared to search results. This differentiates it from sibling tools like search_objects and search_procedures.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says this is a mandatory step before writing code or a query, and notes that only here can one see details not available in search. It gives a clear usage context but does not explicitly name alternatives or state when not to use it. Still, the guidance is concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_procedureA

Оглавление модуля либо карточка одной процедуры из загруженной выгрузки кода. Адрес модуля без :: возвращает только оглавление без тела; Модуль::Имя возвращает сигнатуру, контекст компиляции и окно тела до 200 строк с готовым вызовом продолжения. Выбранное расширение читается отдельно от основной конфигурации; смысл его аннотации показывается явно.

ParametersJSON Schema
NameRequiredDescriptionDefault
linesNoРазмер окна тела: целое число от 1 до 200. Если тело длиннее, ответ содержит готовый вызов следующего окна без пропусков.
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.
addressYesТочный адрес модуля (`ОбщийМодуль.ОбщегоНазначения`) или процедуры (`ОбщийМодуль.ОбщегоНазначения::Проверить`).
extensionNoИмя одного загруженного расширения. Не задано — читается код основной конфигурации; чужие расширения в тело не подмешиваются.
start_lineNoНомер первой строки окна тела, начиная с 0. Значение берётся из готового вызова продолжения в предыдущем ответе.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does meaningful work: it discloses that a bare address returns no body, that the body window is capped at 200 lines, that a ready continuation call is included, and that a selected extension is read separately from the main configuration. It does not cover error/not-found behavior, but the core execution traits are clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, each earning its place: the general purpose, the two address-mode behaviors, and the extension-isolation behavior. Key information is front-loaded and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter tool with no annotations and an output schema, the description is complete enough: it covers address semantics, body windowing, continuation pagination, and extension handling. Config disambiguation is already documented in the schema, and the output schema covers return structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema for `address` by explaining the `::` distinction that controls whether the body is returned, and for `extension` by noting it is read separately with explicit annotation meaning. The remaining parameters are already well documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource and distinct behaviors: it returns either a module's table of contents or a single procedure card from the loaded code export. It also explains the two address modes (`Module` vs `Module::Name`) and lists included elements (signature, compilation context, up-to-200-line body window), so an agent can distinguish it from sibling tools like search_procedures or get_syntax.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use a bare module address for a table of contents without the body, and use `Модуль::Имя` for a full procedure card with body window and continuation call. It does not explicitly name alternative tools or exclusion conditions, but the intended invocation patterns are unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_syntaxA

Полное описание элемента платформы 1С (сигнатура, параметры, тип возврата, доступность, версия появления, предупреждение об устаревании с рекомендуемой заменой, пример). Для объекта detail=full также открывает список связанных методов, свойств и страниц «См. также» с точными адресами для следующего вызова; после 50 ссылок продолжайте через detail=links и links_offset. Вызывать перед использованием функции на старой конфигурации: недоступное в её версии помечается, и там же лежит рецепт замены, если он записан (СтрРазделить появилась в 8.3.6 — на 8.3.5 нужен обход). Поле «Доступность» — тоже ошибка компиляции: серверный метод из клиентского контекста не соберётся. Режим совместимости проверяется отдельно: по одной версии платформы успешную компиляцию в старом режиме утверждать нельзя.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesИмя элемента платформы: `СтрНайти`, `ЗаписьJSON.ЗаписатьНачалоОбъекта`, `ValueTable.Columns`. Для членов объектов надёжнее указывать `Объект.Член`.
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.
detailNoУровень карточки синтаксиса: `brief`, `fields` (по умолчанию), `full` (описание и первые 50 связей) или `links` (только связи, по 50 на страницу). Для следующей страницы `links` передайте `links_offset` из ответа. Связи показываются только по справке точного релиза конфигурации; без конфигурации доступность не проверена.fields
links_offsetNoСмещение страницы связей для `detail=links`, от нуля. В остальных режимах оставьте 0.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses that `full` opens the related-methods/properties list capped at 50 links with continuation via `links_offset`, that the config must be specified when more than one is loaded, and that availability is a compile-error concept (server method from client context will not build). It even warns that compatibility mode must be verified separately, which is non-obvious behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the core capability leads, followed by paging and the availability/compatibility caveats. The final two sentences on availability and compatibility are valuable but slightly tangential to the call itself, keeping it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return format need not be explained; the description still covers paging behavior, the config-selection requirement, and the compatibility caveat, which is what an agent needs. It is complete enough for a complex lookup tool, though the interplay between config and link availability could be slightly tighter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3, but the description adds real meaning beyond the schema: how the detail tiers differ, that links paginate at 50, that `links_offset` is only meaningful for `detail=links`, and that links are shown only for the exact release help of the configuration. This goes past restating field docs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb (retrieve the full description) and an exhaustively enumerated resource: signature, parameters, return type, availability, version-of-appearance, deprecation with replacement, and an example. This clearly distinguishes it from the search-oriented siblings like search_syntax and search_procedures.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete when-to-use rule: call it before using a function on an old configuration, since unavailable members are flagged and a replacement recipe is stored there. It also explains the paging path (detail=links, links_offset). It does not explicitly name a sibling alternative (e.g. search_syntax for lookup), so it falls short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_configurationsA

Какие конфигурации 1С загружены, на какой платформе и что по ним доступно. Вызывать первым: если конфигураций больше одной, параметр config обязателен во всех остальных инструментах, а имя для него берётся отсюда.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the behavioral burden. It discloses that the tool is a read-oriented listing, reveals the returned concepts (configurations, platform, availability), and explains an important behavioral consequence: the config name should be sourced from this tool. It does not explicitly state read-only or side-effect-free behavior, but the query-like phrasing makes the intent clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The core purpose is front-loaded, followed immediately by the most important usage rule. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with an output schema present, the description provides the essential context an agent needs: what the tool lists, why it exists, and how its output feeds into other tools. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description correctly mentions `config` as a parameter for other tools, not this one, and adds no unnecessary parameter detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool reports: which 1C configurations are loaded, on which platform, and what is available for them. It also distinguishes itself from siblings by framing itself as the entry point that supplies the `config` value other tools need.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage guidance: call this tool first, and if more than one configuration exists, all other tools require the `config` parameter whose value comes from this result. This directly tells an agent when and why to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_extensionsA

Показать расширения, фактически действовавшие в снятом сеансе 1С, не применённые расширения и порядок элементов в ответе API платформы. Вызывать после list_configurations, когда задача зависит от активности расширений. Без отдельного runtime-снимка возвращает unknown; позиция API не выдаётся за доказанный порядок исполнения модулей.

ParametersJSON Schema
NameRequiredDescriptionDefault
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that without a separate runtime snapshot it returns 'unknown', and that API position order is not presented as proven module execution order. These caveats are valuable and go beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with purpose, followed by usage and caveats. Every sentence serves a distinct informative role, with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description does not need to explain return values. It covers purpose, usage context, prerequisite, and important behavioral caveats. It adequately equips an agent to determine when and how to call the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the `config` parameter is already well-described (name as returned by `list_configurations`, mandatory when multiple configurations). The tool's description adds no additional parameter detail beyond what the schema provides, so a baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: showing extensions that were actually active in a captured 1C session, unapplied extensions, and the order of elements in the platform API response. It references the prerequisite `list_configurations` and differentiates itself by focusing on extension activity within a specific session context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance to call after `list_configurations` when the task depends on extension activity. Gives a clear context and prerequisite, though it doesn't list when-not to use alternatives. No direct sibling for extensions exists, so the contextual direction is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_objectsA

Найти объект конфигурации по описанию или части имени. Запрос можно писать по-человечески: «расходная накладная», «цены номенклатуры». Отдаёт только имена и счётчики — состава полей здесь нет. Прежде чем писать код или запрос по найденному объекту, вызовите get_object: вид и периодичность регистра, готовые имена полей виртуальных таблиц (КоличествоОстаток, СубконтоДт1) приходят только оттуда. Запрос, написанный сразу после поиска, выглядит правильным и падает на «поле не найдено».

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoОграничить вид: Документ, Справочник, РегистрСведений, РегистрНакопления, Перечисление, ОбщийМодуль и т. п.
limitNoСколько результатов вернуть. По умолчанию 10, максимум 50 (большее молча урезается). Поднимать выше 10 стоит только когда нужного не оказалось в первой десятке: правильный ответ почти всегда в первой пятёрке, а длинная выдача тратит контекст.
queryYesФормулировка по-человечески («расходная накладная») или часть имени объекта.
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It clearly states the limited output shape (names and counters only) and the failure mode when field information is missing. It does not mention auth or rate limits, but for a search tool the output limitation is the most important behavioral trait.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each earning its place: purpose, natural-language input, output scope, and the required follow-up with failure warning. There is no filler, and the most actionable guidance is clear and memorable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with a complete schema and an output schema, the description covers purpose, output limitations, and the follow-up needed to write correct code. It could mention alternatives like search_procedures, but the tool relationships are otherwise well handled by naming get_object explicitly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents query, kind, limit, and config. The description adds examples and a limit heuristic but no genuinely new parameter semantics; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource: find configuration objects by natural-language description or partial name, and explicitly notes it returns only names and counters. This distinguishes it from get_object, which must be called afterward for field metadata.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Directly instructs the agent to call get_object after searching before writing code or queries, and warns that queries written immediately after search will fail with 'поле не найдено'. Also gives actionable guidance on keeping limit at 10 unless the needed result is absent from the first ten.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_proceduresA

Найти процедуру или функцию в загруженном коде конфигурации либо одного выбранного расширения. Точное имя находит и неэкспортные процедуры; поиск по словам — только экспортные. Расширенная фраза о 12 типовых событиях разрешается в точное имя, но без scope не выбирает случайную реализацию. Для обычного поиска scope задаёт приоритет модулей, для распознанного события — ограничивает его реализации. Из query область не угадывается. Сигнатуры читаются из выгрузки в файлы только для показанных результатов.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoСколько результатов вернуть отдельно на каждом уровне поиска: по точному имени и по словам. Целое число от 1 до 50; значение вне диапазона отклоняется, чтобы не скрывать ошибку вызова.
queryYesТочное имя процедуры (`ПриЗаписи`) или слова из имени и комментария-шапки (`проверить остатки`), в том числе фраза о поддержанном типовом событии (`что выполняется при записи объекта`). Объект поиска из этого текста не угадывается — для него есть `scope`.
scopeNoНеобязательный явный scope: объект (`Документ.ЧекККМ`) или точный адрес (`ОбщийМодуль.ОбщегоНазначения`). В обычном поиске его модули поднимаются, а распознанное типовое событие разрешается только внутри scope. Из query область не выводится.
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.
extensionNoИмя одного загруженного расширения. Не задано — поиск идёт только по коду основной конфигурации, без примеси расширений.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly. It discloses that event phrases resolve without picking an arbitrary implementation, that scope changes priority or constraint semantics, that query does not imply scope, and that signatures are read from file dumps only for displayed results. These are non-obvious behavioral details beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the core purpose, and each sentence adds meaningful detail. However, it is somewhat dense and partially repeats scope/query semantics already documented in the input schema, so it is not maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the presence of an output schema, and full parameter coverage in the schema, the description covers all necessary operational aspects: search modes, event recognition behavior, scope semantics, config/extension context, and result-dependent signature reading. An agent has enough information to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The narrative description mostly restates scope semantics already present in the input schema and adds no new parameter-level detail beyond it. The schema itself is doing the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb and resource: 'Найти процедуру или функцию' in loaded configuration code or one selected extension. It further differentiates exact-name search from word-based search and notes exported versus non-exported coverage, making the tool's purpose immediately recognizable among siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides practical usage context: exact names find non-exported procedures, word search finds only exported ones, scope behaves differently for ordinary search versus recognized events, and config is tied to the loaded configuration. It does not explicitly name sibling alternatives or state when not to use this tool, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_syntaxA

Найти метод, свойство или объект платформы 1С. Для вызываемого действия задайте kind=method: иначе в выдаче могут оказаться свойства и сходные по названию механизмы. Даёт только строку списка. Сигнатура, параметры, доступность по контекстам, версия появления, порог устаревания и рекомендуемая замена — в get_syntax по найденному имени. При режиме совместимости компиляция метода остаётся непроверенной и помечается unknown.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoОграничить вид: method, property, event, object, query_table, query_field.
limitNoСколько результатов вернуть. По умолчанию 10, максимум 50 (большее молча урезается). Поднимать выше 10 стоит только когда нужного не оказалось в первой десятке: правильный ответ почти всегда в первой пятёрке, а длинная выдача тратит контекст.
queryYesЧто ищем: «разделить строку», «ЗаписьJSON», «StrFind» по платформе. Русские и английские имена равнозначны.
configNoИмя конфигурации 1С, как его вернул `list_configurations` (например «ОтраслеваяКонфигурация»). Обязателен, если загружено больше одной конфигурации: по умолчанию ничего не подставляется, иначе ответ может относиться к чужой конфигурации.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does real work: it discloses that output is only a list row (not detail), and that under compatibility mode method compilation is left unverified and marked unknown. It does not discuss permissions, ordering, or rate behavior, but the output-scope and edge-case disclosure is above average.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four front-loaded sentences with no filler: purpose, kind caveat, output scope, and where the detail lives. The most decision-relevant constraint (kind=method) is placed early, and the redirection to get_syntax closes the loop.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and 100% parameter coverage, the description need not explain returns or params, and it correctly focuses on the search-vs-detail boundary and the compatibility-mode caveat. It is essentially complete for this tool's complexity, with only minor gaps around result ordering.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, and the description adds genuine meaning beyond the bare enum list by explaining why kind=method matters for callable actions and that Russian/English names are equivalent. It enriches the semantics of kind rather than merely restating it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (find a 1C platform method/property/object) and immediately scopes the return to a list row only, explicitly contrasting with get_syntax which carries the full detail. An agent can separate this from siblings like get_syntax and search_objects without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete routing advice: set kind=method for callable actions to avoid properties and similarly named mechanisms, and directs the agent to get_syntax for signature/params/deprecation. It stops short of stating when to prefer the sibling search_objects or search_procedures, so it is clear context without full exclusion coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 1 tool updatev4.2.0
    • Removedget_module_source_file
  2. 2 tool updatesv4.1.0
    • Addedget_module_source_file
    • Changedget_syntax2 fields changed
      • changedInput schema / properties / detail / description
        Previous value: -"Уровень детализации: `brief` — пара строк со счётчиками, `fields` — состав для написания кода, `full` — со свойствами и связями. Полное описание крупного документа занимает много контекста, поэтому `full` только когда связи действительно нужны."New value: +"Уровень карточки синтаксиса: `brief`, `fields` (по умолчанию), `full` (описание и первые 50 связей) или `links` (только связи, по 50 на страницу). Для следующей страницы `links` передайте `links_offset` из ответа. Связи показываются только по справке точного релиза конфигурации; без конфигурации доступность не проверена."
      • addedInput schema / properties / links_offset
        Added value: +{
        +  "default": 0,
        +  "description": "Смещение страницы связей для `detail=links`, от нуля. В остальных режимах оставьте 0.",
        +  "title": "Links Offset",
        +  "type": "integer"
        +}
  3. 1 tool updatev3.3.0
    • Changedget_object1 field changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Непрозрачный cursor из ответа get_object для продолжения HTTP-сервиса или подсистемы. Передавайте без изменений с теми же full_name, config и detail.",
        +  "title": "Cursor"
        +}
  4. 1 tool updatev3.0.0
    • Changedcompare_configurations3 fields changed
      • changedInput schema / properties / configs / description
        Previous value: -"Имена конфигураций из `list_configurations`. Не заданы — берутся все загруженные."New value: +"Ровно два разных имени из `list_configurations`. Не заданы — автоматический выбор только при ровно двух загруженных конфигурациях; иначе выберите пару явно."
      • addedInput schema / properties / cursor
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maxLength": 2048,
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Непрозрачный курсор из продолжения. Привязан к паре, объекту и содержимому сравнения.",
        +  "title": "Cursor"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 40,
        +  "description": "Число различий на странице суммарно для обеих сторон, от 1 до 100.",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "title": "Limit",
        +  "type": "integer"
        +}
  5. 11 tool updatesv2.0.0
    • First observedcompare_configurations
    • First observedget_callers
    • First observedget_object
    • First observedget_procedure
    • First observedget_related
    • First observedget_syntax
    • First observedlist_configurations
    • First observedlist_extensions
    • First observedsearch_objects
    • First observedsearch_procedures
    • First observedsearch_syntax

TDQS

A4.4/5.0

Scored across 11 tools

Disambiguation5/5

The set follows a clean search_X (find) vs get_X (detail) pattern that the descriptions explicitly reinforce (e.g. search_objects returns names/counters only, get_object returns field structure). Each tool targets a distinct resource or action, with even subtle cases like get_object vs get_related and search_syntax vs search_procedures clearly differentiated.

Naming Consistency5/5

Every tool uses a consistent snake_case verb_noun convention (list_configurations, search_procedures, get_object, compare_configurations). No mixing of styles or vague standalone verbs.

Tool Count5/5

11 tools is well-scoped for a rich configuration-analysis domain, covering listings, search/detail pairs for objects, procedures, and platform syntax plus relation/caller/comparison utilities. Each tool earns its place with no redundant entries.

Completeness4/5

The surface covers the full read-only analysis lifecycle: discovery, structure, relations, callers, cross-config comparison, and platform syntax lookup. Minor gaps remain—procedure bodies are capped at ~200 lines and multi-hop dependency chains require manual repeated calls—but these are workable.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Provides a RAG-based search system for 1C:Enterprise platform documentation using hybrid BM25 and semantic search across multiple versions. It enables developers to retrieve API signatures, methods, and usage examples directly within IDEs or through a REST API.
    23
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for 1C:Enterprise that provides precise syntax reference cards (call signatures, parameters, return types, examples) by element name and lists object members. It helps AI agents answer 1C development questions using the official Russian help book.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides AI assistants in Cursor with local access to 1C platform documentation and XML configuration exports, enabling metadata lookup, BSL code search, and platform help queries without manual file copying.
    MIT