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,000개 엣지

플랫폼 도움말

✅ 세 버전 병합 인덱스, 25,691개 요소, since/until 경계

쿼리 언어

✅ shquery_ru.hbk, 127페이지, 버전 없는 별도 소스

검색

✅ 97.1% 도움말, 94.7% 쿼리 언어, 90.5% 메타데이터 — '측정됨' 참조

레지스터 가상 테이블

✅ 준비된 쿼리 필드 이름 (КоличествоОстаток)

구형 플랫폼 대체 테이블

✅ 사용 불가 항목은 단순히 금지되는 것이 아니라 레시피로 대체됨

소스 레지스트리, 버전 매핑

✅

MCP 서버, 10개 도구

✅ streamable-http 및 stdio

Docker

✅ 단일 컨테이너, Docker CLI 출력 기준 357MB

검색 인덱스 캐시

✅ 12MB, 재파싱 대신 로드됨

측정 스탠드

✅ 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/ — 6개 페이지:

페이지

내용

개요

로드된 것: 객체, 연결, 플랫폼 버전, 매니페스트의 경고

소스

로드된 목록, 각 코드 코퍼스의 세 가지 커버리지 테이블, 전체 JSON 로그 경로, 전송 진행률 표시줄이 있는 .zip 및 .hbk 업로드, 삭제, '수신 내보내기' 블록 — data/incoming/의 파일, 버튼으로 파싱

쿼리

순위 평가 및 이유가 포함된 표현 목록 실행

연결

객체 주변 그래프를 이미지로

카드

객체 구성 또는 플랫폼 요소 설명 — 에이전트가 보는 것과 동일

사전

출처가 있는 규칙; 별칭 또는 동의어 그룹 생성

업로드 — 무엇이 언제 보이는가

업로드는 두 단계로 진행되며 각각 다르게 표시됩니다.

파일 전송 — '소스' 페이지의 진행률 표시줄: 백분율, 용량, 속도 및 남은 시간 추정. 브라우저가 계산하며 이는 임의가 아닙니다. 서버는 전송 진행 상황을 볼 수 없습니다: await request.form()은 본문이 완전히 도착한 후에만 제어를 반환하며 작업은 그 이후에 생성됩니다. 실제 소켓에서 확인됨: 40MB가 8.1초 걸렸고, 그 동안 두 번째 연결에서 /sources를 32회 폴링했지만 어떤 작업도 보지 못했습니다. localhost에서는 차이가 없지만 원격 서버에서는 빈 화면으로 몇 분이 걸립니다.

또한 500MB 제한은 전송 전에 확인됩니다: 이전에는 초과 파일이 완전히 업로드된 후에야 거부되었습니다.

파싱 — 같은 페이지의 '업로드' 테이블: '수신 중' → '파싱 중' → '완료' 또는 이유가 있는 '오류'. 작업이 진행되는 동안 페이지는 자체적으로 새로고침됩니다(meta refresh, 2초마다).

진행률 표시줄은 JS가 필요하고 테이블은 그렇지 않습니다. JS가 꺼진 상태에서도 양식은 일반 양식처럼 작동합니다: 파일이 전송되고, 작업이 생성되며, 상태는 테이블에 표시됩니다 — 전송 중 표시줄만 없습니다.

연결 — 객체 그래프

/graph는 객체 주변을 그립니다: 유형별 색상, 참조 방향별 화살표, 호버 시 엣지 레이블. 노드 클릭은 그 주변에 그래프를 구축하고, 드래그는 이동하며, 휠은 확대/축소합니다. 이웃 제한은 페이지에서 선택됩니다(15…400), 잘림은 숫자로 표시됩니다 — '102개 중 30개 표시'.

'건드리면 무엇이 깨질까'에 답합니다: 주황색 문서로 둘러싸인 레지스터는 누가 이를 움직이는지 즉시 알려줍니다.

깊이는 항상 한 단계입니다. 두 단계에서는 자주 사용되는 참조서에서 천 개의 객체가 나오고, 세 단계에서는 구성의 1/3이 나옵니다. 그 이상은 추가 속성과 같은 공통 메커니즘을 통해 연결되며, 이는 거의 모든 것을 모든 것과 연결합니다. 연결 수 임계값으로 이를 잘라낼 수 없습니다: 해당 노드는 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는 healthcheck를 위해 열려 있지만, 구성 이름은 토큰이 있을 때만 반환한다.

사전 로드, 삭제 및 편집에는 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 헤더를 반환하지 않음

첫 GET /mcp에서 400

클라이언트가 GET으로 핸드셰이크를 시작함 — 구식 HTTP+SSE 전송을 사용하며, 이 주소는 streamable-http임

/sse에서 404

동일함: 구식 전송이 완전히 비활성화됨

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}" }
    }
  }
}

headers 블록은 서버에 API_TOKEN이 설정된 경우에만 필요하다. 값은 환경 변수에서 가져와 파일을 저장소에 유지할 수 있다:

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 불변식은 아래에 설명되어 있습니다. 경고는 불완전한 응답 위에 있으며 직접적으로 말합니다: 0 카운터는 숨겨진 데이터가 없음을 증명하지 않습니다.

코드 커버리지 로그 — 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 사이의 정수여야 합니다. 응답에는 주소 Модуль::Имя, 디스크의 시그니처, 내보내기 여부, 줄, 확인된 호출 위치 수 및 해결할 수 없는 동일 이름 위치의 별도 카운터가 포함됩니다. 확장 어노테이션의 부울 인덱스는 중립적으로 호출됩니다: &После 또는 &Перед를 원본 프로시저의 완전한 오버랩으로 제공하지 않습니다. 시그니처와 본문은 RAM에 저장되지 않습니다. 계층적 .bsl, 플랫 .txt 및 원본 컨테이너 Form.bin/.Form의 module 레코드는 동일한 렉서를 통과합니다; 검색 및 후속 카드는 주소에서 경로를 복원하지 않고 한 세대의 로케이터를 사용합니다.

scope 없이 검색은 전역입니다. 명시적 scope="Документ.ЧекККМ"은 객체의 모든 모듈을 올리고, scope="ОбщийМодуль.ОбщегоНазначения" 또는 다른 정확한 주소는 하나의 모듈을 올립니다; 나머지 결과는 아래에 유지됩니다. 범위는 query에서 추측되지 않습니다. extension은 정확히 하나의 로드된 확장을 선택합니다; 없으면 검색은 기본 구성에서만 수행됩니다.

get_procedure는 검색의 정확한 주소를 받습니다. :: 없는 모듈 주소는 본문 없는 목차를 반환합니다; Модуль::Имя는 시그니처, 컴파일 컨텍스트 및 본문을 반환합니다. start_line은 0에서 시작하며, lines는 1에서 200 사이의 정수여야 합니다; 긴 응답에는 줄 건너뜀 없이 다음 창에 대한 준비된 호출이 포함됩니다. 선택된 확장의 경우 &После, &Перед 및 &Вместо는 해당 본문을 표시합니다; &ИзменениеИКонтроль은 기본 구성의 본문과 #Вставка/#Удаление의 축어적 블록만 표시합니다. 도구는 다른 로드된 확장에 대해 본문 위에 경고하지만 해당 코드를 응답에 혼합하지 않습니다. 시그니처와 본문은 단일 응답을 위해 디스크에서 읽히며 RAM에 남지 않습니다. 동일한 로케이터는 캐시와 재시작을 견딥니다: 읽는 동안 소스가 교체되면 전체 응답이 새 세대에 따라 반복되며 두 세대의 부분이 혼합되지 않습니다.

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 단계는 건너뛸 수 없습니다. 검색은 이름과 카운터만 반환합니다; 코드가 의존하는 모든 것은 객체 카드에 있습니다:

  • 레지스터의 유형 및 주기성. СрезПоследних는 주기적 정보 레지스터에만 있으며, 비주기적 레지스터는 603개 중 566개입니다;

  • 가상 테이블 필드의 준비된 이름. 쿼리에서 리소스 Количество는 КоличествоОстаток, КоличествоОборот, КоличествоПриход라고 합니다 — 구성자에서는 이러한 이름이 어디에도 보이지 않으며 플랫폼이 생성합니다;

  • 하위콘토 한도, 대응, 그래프 리소스 — 이들 없이는 СубконтоДт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토큰 뒤에 있었고, 결정은 이름을 복사하는 곳에서 내려진다. 같은 교훈은 이미 도구 설명에 기록되어 있었다: 규칙은 그것을 읽는 곳에서 작동하지, 더 깔끔하게 놓아두는 곳에서 작동하는 것이 아니다.

각 금지는 검증되었다: 집계 함수는 도움말의 인용문으로, 나머지 다섯 개는 오류 텍스트를 기록한 실제 데이터베이스 실행으로 검증했다. 도움말은 여섯 개의 집계 함수 중 세 개에서만 제한을 알고 있으며, 그룹화, 정렬, РАЗЛИЧНЫЕ, ОБЪЕДИНИТЬ 및 비교에 대해서는 침묵한다 — 즉, 도움말을 성실히 읽은 에이전트는 이에 대해 알 수 없었다. 출처별 분류는 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» 및 «버전부터» 언급이 0건. 그러나 쿼리 언어는 변한다: 릴리스 8.3.20이 함수 25개를 추가했으며, 그중 СтрНайти, Лев, Прав, ВРег, НРег, СтрЗаменить, Окр, Цел 및 모든 삼각함수가 있다.

버전을 가져올 곳이 없다: 플랫폼 도움말은 쿼리 언어 함수를 전혀 설명하지 않는다 (ПОДСТРОКА — 25 511개 요소에서 0건 일치). 따라서 버전은 큐레이션된 테이블 query_versions.py가 지정한다 — 1C의 «릴리스 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개 테이블 — 텍스트의 제자리에 인쇄된다: 두 개의 예제가 있는 페이지는 각 결과를 해당 예제 아래에 표시한다. 테이블 내용은 검색 인덱스에 들어가지 않는다.

이 도움말의 테이블은 두 가지 다른 성격이며, 다르게 파싱된다:

무엇

수량

카드에서의 모습

데이터 테이블 — 예제 쿼리 결과

127페이지 중 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개가 제거되었다. 경고가 아닌 필터링으로: 경고는 에이전트가 놓칠 수 있지만, 결과에 없는 메서드는 놓칠 수 없다.

가용성 필드(서버 / 씬 클라이언트 / 웹 클라이언트 / 모바일)는 반드시 읽어야 한다: 클라이언트 컨텍스트에서 서버 메서드를 호출하면 컴파일되지 않는다.

여러 버전의 도움말이 하나의 인덱스로 병합된다

이전 구성에 대한 하나의 최신 도움말은 거짓말을 한다. 8.3.5에서 측정: 서버가 199개 요소를 존재하지 않는 것으로 선언하고, 117개를 잘못된 시그니처로 제공하며(ЗаписьXML.ОткрытьФайл은 8.3.5에서 매개변수 2개, 8.3.27에서 3개), 410개를 잘못된 가용성으로 제공한다. 이 모든 것은 컴파일 오류이지 부정확함이 아니다.

따라서 다른 버전의 도움말은 나란히 놓이고 since 및 until 경계와 함께 하나의 인덱스로 병합되며, 응답은 특정 구성의 버전에 맞춰 조립된다. 도움말은 로드된 구성의 플랫폼 수만큼 필요하다 — 두 개의 극단적인 중간 버전은 대체하지 못한다.

비용은 측정되었고 작다: 세 버전의 병합은 하나의 24 777개 대비 25 691개 키를 제공하며, 즉 1퍼센트 미만이다. 버전별 별도 컨테이너도 작동하며 비상 경로로 남아 있지만, 기본 경로로서는 숫자상 패배한다 — 버전당 300–450МБ와 자체 주소가 필요하다.

서버는 어떤 도움말이 부족하고 어떤 것이 불필요한지 스스로 말한다 — list_configurations 결과에서.

금지 대신 교체

«함수가 없다»고 말하는 것은 답의 절반이다. 나머지 절반은 무엇으로 교체할지이며, 도움말에서 도출되지 않는다: 폐기 표시는 25천 페이지 중 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개 요소를 표시한다. 준비된 세트는 다른 버전의 중간 상태 없이 전체가 게시된다. startup이 다음 소스를 아직 복원하는 동안 백그라운드 빌드는 registry.json을 덮어쓰지 않는다. startup이 비정상적으로 중단된 경우 디스크의 이전 전체 스냅샷은 그대로 남는다; 부분적으로 복원된 소스 목록은 그 위에 저장되지 않는다.

네 개의 캐시 소모 파일은 안전한 로케이터, 커버리지 집계 및 나머지의 정확한 수와 함께 처음 20개의 비식별화된 문제를 저장한다. 모듈 본문, 프로시저 시그니처 및 원시 양식 기록은 여기에 들어가지 않는다. warm-시작 시 소스의 sha256, 선택 버전, 로케이터 세대, 각 인덱스의 내부 불변식 및 단일 디렉터리와의 일관성이 확인된다. 따라서 구조적 또는 의미적으로 손상된 세트는 부분적으로 오래된 응답의 소스가 아니라 전체 미스로 간주된다. 손상되었거나 읽기 전용 캐시는 소스를 무너뜨리지 않는다: 서버는 메모리에서 cold-재빌드를 수행하고 새 캐시를 쓸 수 없더라도 전체 진단을 게시한다. 게시된 cold- 및 warm-응답은 모든 카운터와 원인 범주에서 일치한다. 각 양식의 로컬 원인은 제한된 목록과 별도로 저장된다: 덕분에 get_object는 재시작 후 선택한 객체의 모든 양식 문제를 표시하면서 일반 /sources를 무제한 응답으로 만들지 않는다. Reader는 256МиБ보다 큰 캐시 파일을 읽지 않으며 512МиБ보다 큰 payload를 압축 해제하지 않는다; 어느 한계의 초과는 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였습니다. 카탈로그는 계층적 .bsl 8,650개, Form.bin의 모듈 828개, 평면 .txt 1,523개, .Form의 모듈 1,079개, 소스 없이 컴파일된 모듈 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; 이 코퍼스에는 알 수 없는 마커, 예산 초과, 손상된 컨테이너, 충돌이 없습니다. 여기서 0은 바로 이 소스들에 대한 측정 결과이지, 향후 어떤 형식의 지원을 약속하는 것이 아닙니다.

2026-08-21 콜드 캐시에서 세 개의 코드 소스에 대한 이전 백그라운드 응답성 측정: 72.12초 동안 각 경로에 대해 73회의 초 단위 호출이 이루어졌고, 거부는 없었습니다. 이 타이머는 /health 준비 후에 시작되는 반면, 아래의 컨테이너 측정 125초는 컨테이너 시작부터 모든 코드 소스의 ready까지입니다. /health는 중앙값 5.76ms, 최악 171.01ms로 응답했습니다; 실제 search_objects는 각각 8.11ms와 172.49ms였습니다. 컨테이너는 healthy에 도달했고, 캐시 파일 12개가 모두 게시되었습니다. 반복하려면 별도 컨테이너에 index/cache/*.modules-*가 없는 data/ 복사본을 마운트하고 다음을 실행하십시오:

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

최종 이미지의 메모리는 selection v4 이후 2026-08-21에 다시 측정되었습니다: 코드 소스 4개와 모듈 인덱스 캐시 파일 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 전에 유지된 dir_fd를 통해 디렉터리를 O_NOFOLLOW로 다시 열고 해당 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.5GB의 cp는 몇 분이 걸리며 파일은 첫 1초부터 디렉터리에 보입니다: 5초 미만 전에 변경된 아카이브의 상태는 "파일이 아직 복사 중" 표시로 보여지고, sha256은 전혀 계산되지 않으며(어차피 오래될 것이므로), 해당 파일의 파싱은 설명과 함께 거부됩니다. 복사가 끝날 때까지 기다렸다가 페이지를 새로고침하십시오.

재파싱은 디렉터리를 완전히 덮어씁니다 — 그러나 성공 후에만. 업데이트된 추출물의 버튼은 "재파싱"으로 표시됩니다: data/modules/<구성명>/(또는 확장 디렉터리)의 이전 내용은 새 내용으로 완전히 교체됩니다. 그렇지 않으면 새 추출물에 없는 파일(삭제된 객체, 이름이 바뀐 모듈)이 영원히 남아 두 추출물이 섞이게 됩니다. 압축 해제는 옆의 임시 디렉터리에서 진행되며 이전 파싱에 영향을 주지 않습니다: extract가 중간에 실패하면(모듈의 손상된 CRC, 공간 부족, 권한) 또는 파일 0개를 선택하면 작업 디렉터리에 쓰기 전에 전혀 진행되지 않습니다 — 레지스트리와 디스크가 어긋나지 않습니다. 교체는 제자리에서 기존 것을 철거하는 것이 아니라 맞바꾸기입니다("이전 것을 옆으로 이름 변경 → 새 것을 그 자리로 이름 변경 → 남겨둔 것 철거"): 새 것이 이전 것의 자리로 이동하지 못하면 서버는 이전 것을 원래 위치로 되돌리려 시도합니다. 이것도 실패하면(두 이름 변경의 실패 원인은 일반적으로 동일 — 권한, 동일한 bind-mount), 파싱은 명시적으로 거부하고 텍스트에 두 경로를 모두 언급합니다: 이전 파싱이 물리적으로 어디에 있고 새 것이 비어 있거나 부분적으로 압축 해제된 곳이 어디인지 — 수동으로 디렉터리를 복원할 수 있도록; 서버는 존재하지 않는 디렉터리에 대해 조용히 "파싱됨"을 표시하지 않습니다. 중간에 중단된 프로세스의 잔재(.tmp-*)는 동일한 구성 또는 확장의 다음 파싱 전에 제거됩니다 — 저장된 이전 파싱 복사본(.old-*)은 그런 상황이 발생한 경우 자체적으로 삭제되지 않습니다: 이에 대한 결정은 사람의 몫입니다. 재파싱은 디렉터리 권한을 변경하지 않습니다 — 새 디렉터리는 이전 디렉터리의 권한(또는 디렉터리가 아직 없었던 경우 일반 권한)을 받으며, 임시 디렉터리가 생성되는 축소된 권한이 아닙니다.

동일한 소스의 동시 파싱은 순차적으로 수행됩니다: 새 요청은 이전 세대를 즉시 취소하지만 임시 디렉터리 작업이 완료될 때까지 기다립니다. 따라서 하나의 파싱이 다른 활성 .tmp-*를 삭제할 수 없으며, 작업 디렉터리와 캐시는 마지막 세대만 받습니다. 취소된 요청은 명시적 오류로 종료됩니다; 대기 중인 오래된 요청은 압축 해제를 시작하지 않습니다. 다른 키의 소스를 가진 다른 구성과 확장은 서로를 지연시키지 않습니다.

「선택 규칙이 구식임」— 파일이 아니라 규칙이 바뀌는 경우를 위한 상태. 처리된 각 소스는 선택 규칙의 버전을 기억합니다(내부 SELECTION_VERSION: 아카이브에서 무엇을 가져와서 어디에 둘지). 디스크의 코드가 이전 버전의 규칙으로 처리된 경우, 소스는 incoming/의 아카이브가 동일한 파일이고 동일한 sha256을 가진 경우에도 "처리됨"이 아닌 "선택 규칙이 구식임"으로 표시됩니다. 버튼은 업데이트된 내보내기와 마찬가지로 "다시 처리"로 표시됩니다: 디스크의 코드는 현재 규칙에 따라 다시 덮어씁니다. 이전 처리 결과 자체는 다시 쓰이지 않습니다 — 선택 규칙의 수정은 사람이 버튼을 누른 후에만 볼 수 있습니다. 이 필드가 생기기 전에 처리된 소스(이전 registry.json의 selection_version 없는 레코드)도 구식으로 간주됩니다: 버전이 "확실히 최신"이 아니라 알 수 없기 때문입니다 — 그렇지 않으면 사람은 현재 규칙을 통과한 적이 없는 코드에 대해 "다시 처리"를 결코 볼 수 없을 것입니다. 현재 버전 4는 양식의 XML 디스크립터와 계층적 Ext/Form.bin을 저장합니다. 따라서 버전 3의 소스는 반드시 구식으로 표시되고 명시적으로 다시 처리한 후에만 이러한 파일을 받습니다. 선택 버전은 캐시 스탬프에 포함됩니다: 변경되지 않은 동일한 ZIP에도 이전 캐시는 허용되지 않습니다. 디렉터리를 교체하기 전에 서버는 짧은 롤링 로그를 작성합니다. 비정상 종료 후 다음 시작은 registry.json에 따라 새 세대를 완료하거나 이전 디렉터리를 복원합니다.

macOS Finder 아카이버의 쓰레기는 코드에 들어가지 않습니다. "객체 압축" 명령으로 수집된 아카이브는 각 파일의 리소스 포크 복사본(._이름, 원본과 같은 접미사)이 있는 서비스용 __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이며, 이 검사가 없으면 "처리됨" 상태의 파일 0개 소스를 만들었을 것입니다. 이는 같은 페이지의 "업로드" 양식으로 제공됩니다.

왜 브라우저를 통하지 않는가. 아카이브는 1GB 이상입니다 — 일반적인 소매 판매 구성 2.3.10.5의 경우 1,380MB입니다. "소스"의 업로드 양식은 수 메가바이트 단위의 메타데이터를 위해 만들어졌으며 이러한 파일에서는 세 가지 이유로 즉시 작동하지 않습니다: 업로드 한도 500MB; 최대 약 4GB의 삼중 복사 — 요청 본문 수신 버퍼, mkdtemp()의 임시 복사본, 볼륨 자체로의 복사본; 그리고 중단 후 재개할 수 없는 1GB 이상의 HTTP 전송. 볼륨의 파일은 세 가지 제한을 모두 우회합니다: 일반 cp로 복사되고 서버는 아카이브를 멤버별로 읽으며 전체를 한 번도 풀지 않습니다.

디스크에 남는 것. 전체 아카이브가 아니라 모듈만(계층적 내보내기의 .bsl, 평면 내보내기의 .txt 및 정식 컴파일된 CommonModules/<이름>.Module 또는 CommonModule.<이름>.Module)과 양식: 계층적의 XML 디스크립터, Form.xml 및 Form.bin, 평면의 .Form 컨테이너 전체. Form.bin과 .Form은 코드 공급자의 소스로 변경 없이 저장됩니다. 파생 .bsl은 수신 시 생성되지 않습니다. 텍스트 레이아웃 *.Template.txt는 모듈로 간주되지 않습니다. 컨테이너는 양식의 이진 레코드와 함께 그대로 저장됩니다: 일반 양식의 코드는 그 안에 module 레코드로 있으며, 수신 시 컨테이너를 파싱하는 것은 1C 형식 파싱을 여기로 가져오는 것을 의미합니다.

압축 해제 후 물리적 트리는 정식 주소와 안전한 로케이터의 불변 디렉터리로 한 번 열거됩니다. 목차, 호출, 양식 및 검색은 동일한 스냅샷을 받습니다: 일반 .bsl/.txt는 파일로 읽히고, Form.bin/.Form의 코드는 원본 컨테이너의 module 레코드로 읽히며, 컴파일된 .Module은 만들어진 본문 없이 주소로 남습니다. 공통 정규화 후 동일한 주소의 동일한 텍스트는 중복 제거됩니다. 다른 텍스트는 조용한 우선순위를 받지 않고 충돌로 제외됩니다.

구성 코드는 data/modules/<구성 이름>/에 배치되고, 확장 코드는 자신의 디렉터리 data/extensions/<구성 이름>/<확장 이름>/에 배치됩니다. 실제 커버리지 로그는 data/logs/에 있습니다. 세 가지 유형 모두 .gitignore의 **/modules/, **/extensions/ 및 **/logs/ 규칙으로 보호됩니다. 측정 python3 tools/lab/measure_intake.py <아카이브>..., 2026-08-19 실행:

항목

아카이브

압축 해제

선택

일반적인 소매 판매 구성 2.3.10.5

1,380MB

2,063MB, 33,188개 파일

351.4MB, 11,072개 파일

그에 대한 확장

1MB

8MB, 453개 파일

6.9MB, 155개 파일

동일한 파일에 대한 수신 자체의 실제 실행 — zip 디렉터리 추정이 아니라 intake.planned_size, intake.enough_space 및 intake.extract의 실제 호출, 측정 python3 tools/lab/measure_intake_run.py <압축 해제 디렉터리> <아카이브>..., 2026-08-19 실행: 1.4GB 아카이브의 필요 공간 추정 — 0.15초(zip 중앙 디렉터리만 읽고 본문은 전혀 건드리지 않음), 압축 해제 — 3.1초, 프로세스 RSS 피크 — 111MB. extract()가 반환한 파일과 바이트 수와 실제로 디스크에 배치된 것은 동일하며, 스크립트가 이를 직접 확인합니다.

서버는 원본을 삭제하지 않습니다. data/incoming/ 디렉터리는 서버가 삭제할 수 없습니다 — 파일은 성공적인 처리 후에도 그 자리에 남습니다. 동일한 아카이브의 재처리는 이를 건드리지 않으며, 검증은 페이지의 캐시와 sha256으로 수행됩니다(목록을 새로 고칠 때마다 1GB의 해시를 계산할 수 없습니다).

소스는 구성 이름이 아닌 키 <구성 이름>:modules로 생성됩니다: 메타데이터와 동일한 키는 업로드 시 레지스트리에서 이를 밀어냈을 것입니다. 어떤 구성이 내보내기의 소유자인지는 사람이 결정합니다. 레지스트리에 정확히 하나가 로드된 경우 선택이 필요 없습니다: 페이지의 버튼 옆에 필드가 없고 처리가 유일한 것을 자동으로 가져옵니다. 두 개 이상 로드된 경우 버튼 옆에 로드된 이름의 드롭다운 목록이 나타납니다 — 선택한 것에 코드가 바인딩됩니다. 양식의 이름은 로드된 목록과 대조됩니다: 알 수 없는 이름은 처리 시작 전에 설명과 함께 거부됩니다. 내보내기 매니페스트에 의한 자동 바인딩(사람의 참여 없이)은 아직 구현되지 않았습니다. 모듈 소스의 플랫폼은 바인딩된 구성에서 가져옵니다 — 내보내기 자체에는 정확한 플랫폼 빌드의 파일이 포함되지 않고 호환성 모드만 있으며 이는 다른 숫자입니다. 확장의 구성 선택도 동일하게 작동합니다(위의 "확장 내보내기는 같은 곳에 배치됨" 참조). 내보내기 유형 — 모듈 또는 확장 — 서버는 Configuration.xml로 스스로 구분하며, 이를 위한 별도의 필드나 버튼은 페이지에 없습니다.

공간 부족 — 시작 전 거부. 구성 및 소스 유형 선택 후 레지스트리는 압축 해제 전에 볼륨의 여유 공간을 확인합니다. 안전하게 선택된 파일의 용량에 인덱스 예비를 더한 값이 필요합니다: 15% 올림, 단 25MB 이상. 공식은 첫 업로드와 재처리에 동일합니다: 이전 루트가 차지한 용량은 이미 여유 공간 값에서 제외되었으므로 다시 더할 수 없습니다. 부족하면 처리가 시작되지 않으며 두 숫자가 메가바이트 단위로 포함된 이유가 "소스" 페이지에 남아 재시작 후에도 유지됩니다. 레지스트리의 직접 호출도 동일한 검사를 통과합니다. 오류 또는 볼륨 가득 참 시 이전 처리가 그 자리에 남습니다.

컴파일된 *.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 клиент покупатель заказчик

객체 별칭 — "내가 이렇게 말하면 이 객체들을 의미한다"는 직접적인 지정으로, 모든 텍스트 일치보다 가중치가 높습니다. 20여 개의 일반적인 문구("파일", "상품", "고객", "직원", "작업")가 내장되어 즉시 작동합니다. 구성에 객체가 없으면 별칭이 적용되지 않습니다. 자체 별칭은 구성에 바인딩하여 추가됩니다:

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

객체 존재는 추가 시 확인됩니다 — 오타에 대한 별칭은 쓸모없습니다. 내용 보기: dict-show, 삭제: dict-alias «문구» --remove.

변경 사항은 컨테이너 재시작 또는 POST /admin/reload로 적용됩니다 — 이미지를 재빌드할 필요가 없습니다. 재로드는 event loop 밖에서 수행되므로 복원 중에도 /health 및 MCP 요청이 계속 서비스됩니다.

쿼리 언어 검색 키 — 세 번째 메커니즘으로, 일반적인 변경 검토와 함께 코드(search_keys.py)에서만 편집할 수 있습니다. 여기서의 간극은 다른 성격입니다: 사람이 구성을 남의 단어로 부르는 것이 아니라 작업을 설명합니다. "두 날짜 사이의 일 수" 대 РАЗНОСТЬДАТ, "중복 제거" 대 РАЗЛИЧНЫЕ — 공통 단어가 전혀 없고 동의어도 도움이 되지 않으며, 대체할 것이 없습니다.

따라서 127페이지 중 116페이지에 사람들이 묻는 방식의 표현이 첨부되어 별도의 필드로 검색 인덱스에 들어갑니다. 런타임에는 아무것도 차지하지 않습니다. 실제 데이터셋의 결과: 57.9% → 94.7% 첫 번째 결과, 61,000개의 자동 쿼리에서 회귀 없음.

키는 내보낸 것이 아니라 우리가 만든 것이며, 여기서 세 가지 제한이 따릅니다:

  • 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

reg-search는 --syntax 없이 메타데이터로 검색하고, --syntax와 함께 사용하면 도움말 및 쿼리 언어로 검색합니다. 세 가지 코드 명령은 동일한 이름의 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입니다. 콜드 일회성 실행 시 이 명령들은 프로세스가 결과 및 네 개의 캐시 파일 기록 전에 daemon 스레드를 종료하지 않도록 백그라운드 빌드를 최대 90초까지 기다립니다. 시간이 부족하면 명령은 명시적 오류를 반환합니다; 서버는 이 대기를 사용하지 않고 계속 진행률을 표시합니다.

레지스트리 없이 파일에서 직접 — 서버로 전송되기 전에 내보내기를 확인하려면:

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 및 zero-based expected_rank는 --check-notes 시 고정된 baseline을 기계적으로 검증합니다; 이는 pytest 품질 임계값이 아닙니다. 이전 루트 JSON 배열 및 버전 없는 이전 baseline은 명시적으로 거부됩니다: 다시 생성해야 합니다. --save는 먼저 보고서 파일을 원자적으로 교체한 다음에만 결과를 출력합니다: 쓰기 오류는 디스크나 stdout에 부분 보고서를 남기지 않습니다.

P@1/P@3/P@5/P@10, MRR, "다른 도메인이 첫 번째" 비율 및 첫 번째 결과와 두 번째 결과의 중앙값 차이를 출력합니다. assert 임계값은 의도적으로 없습니다: 쿼리 세트는 테스트가 아니며 사전 수정마다 백분율이 깨질 것입니다. 코드 1은 메모 불일치를 의미합니다; 코드 2는 잘못된 세트, 모호한 선택 또는 준비되지 않은 인덱스로 인해 전체 측정이 출력 및 저장 전에 취소되었음을 의미합니다. procedure 세트 중 코드 변경 시 전체 세트는 하나의 인덱스 세대에 대해 처음부터 다시 실행됩니다.

두 실행 비교는 다음과 같습니다 (악화가 먼저):

=== сравнение с прошлым прогоном ===
  - «как прибавить месяц к дате в запросе»: 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 파일이 있습니다 — 각각 20여 개 언어로 된 38개의 서로 다른 도움말. 원하는 것과 유사한 것들:

파일

무엇인가

왜 부적합한가

shcntx_root.hbk

동일한 도움말, 언어 독립 부분

25 508개 요소, 하지만 설명이 전혀 없음: 페이지 트리와 영어 식별자만, 등장 버전 없음

shlang_ru.hbk

내장 언어 설명

1C 컨테이너가 전혀 아님

shquery_ru.hbk

쿼리 언어

동일

config_ru.hbk

구성자 도움말

컨테이너이지만 내부에 구문 도우미 페이지 없음

1cv8_ru.hbk

사용자 가이드

컨테이너 아님

크기로는 구분할 수 없습니다: shcntx_root.hbk는 33MB, 원하는 것은 39MB. _ru 접미사는 언어, _root는 텍스트 없는 공통 부분.

파일이 틀리면 서버가 정확히 이유를 설명하고 기존 도움말을 그대로 둡니다.

사용 가능한 가장 최신 플랫폼의 도움말 하나면 충분합니다: 각 요소는 등장 버전을 담고 있으며, 이전 구성의 경우 초과분은 필터링됩니다. 경로에 버전이 없으면 데이터 자체에서 유추됩니다.

이전 플랫폼의 도움말도 허용됩니다 — 마크업이 다르며(p 대신 div 섹션), 이는 고려되었습니다. 이전 구현용 별도 서버를 구축할 때 유용합니다: 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은 동일한 스키마의 서로 다른 직렬화입니다; 로더는 둘 다 동일한 사전으로 변환합니다. 검증됨: 두 내보내기 모두 동일한 30개 키 세트를 제공합니다.

그래프는 1C가 아닌 로더가 구축합니다. 간선은 속성 유형, 문서 이동, 입력 기준, 소유자, 구독 처리기 및 예약 작업 메서드에서 파생됩니다. 규칙은 재내보내기 없이 변경할 수 있습니다.

약한 간선. ЗначениеДоступа 같은 속성은 수백 개의 유형을 나열하고 거의 모든 것을 모든 것과 연결합니다. 이러한 연결은 약한 것으로 표시되고 기본적으로 숨겨집니다 — 그렇지 않으면 유용한 것들이 그 안에 묻힙니다.

세부 수준. Документ.ЧекККМ의 전체 설명(50개 속성, 17개 테이블 파트)은 컨텍스트를 완전히 소모합니다. brief — 두 줄, fields — 구성, full — 연결 포함.

외부 데이터베이스 없음. 운영 인덱스는 단일 프로세스에 유지됩니다: 컴팩트 코드 배열은 별도 네트워크 왕복 없이 응답하며 검색은 0.18–1.5ms가 걸립니다. Elasticsearch, 벡터 저장소 및 그래프 DB는 이 규모에서 별도 프로세스와 유지보수를 정당화하지 않습니다. 벡터 검색은 추가로 인코더 모델(+이미지에 185–620MB)과 쿼리 인코딩에만 16–32ms가 필요합니다.

실제 데이터로 측정 — 2026-08-18

작업 서버에 로드된 것:

구성

플랫폼

객체

간선

카자흐스탄 회계

8.3.27.1936

3 492

84 426

문서관리 KORP

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의 레코드 순서는 중요하지 않습니다: 코드는 자체 구성 다음에만 복원됩니다. 해당 레코드가 없거나, 삭제되었거나, 실행 중에 교체된 경우 이전 모듈 또는 확장 레코드는 소유자 없이 게시되지 않습니다.

검색 인덱스 포스팅은 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"

측정기는 procedures, calls, forms, elements, event_rows 키를 가진 JSON 집계를 출력합니다. 마지막 카운터는 공개 바인딩에서 그룹화 및 중복 제거 전의 원시 <Event> 행입니다.

프로토타입의 기록 스냅샷은 2026-08-20에 비식별화된 계층형 내보내기를 파일로 받아 촬영되었습니다: 모듈 7,878개, 프로시저 137,115개, 텍스트 260MB. 아래에는 현재 집계가 아닌 당시의 수치가 보존되어 있습니다.

계층

디스크에서

메모리에서

프로시저 137,115개의 목차

14.9MB

62MB

해석된/미해석된 호출 지점 619,030개

12.0MB

51MB

내보낸 프로시저 49,181개 검색

4.27MB

173MB

폼: 파일 3,194개, 요소 69,769개

5.8MB

44MB

모듈 텍스트 및 시그니처

260MB

0

검색 지연 시간은 1.2~1.5ms입니다. 캐시 기록을 포함한 4개 인덱스의 전체 콜드 빌드는 약 50초입니다.

파일로의 내보내기는 서로 다른 두 가지가 있으며, 두 번째는 별도로 측정되었습니다 — 8.3.5의 업계 구성 10.5.1.3: 플랫 레이아웃, .txt의 모듈, 이진 .Form 컨테이너 내부의 일반 폼 코드. 모듈 2,603개, 프로시저 33,555개, 파싱 1.1초, 전체 94MB 검색 시 중앙값 0.2ms. 이 형식에는 폼 구조가 포함되어 있지 않으며, 일부 공통 모듈은 컴파일된 상태로 제공됩니다 — 소스가 전혀 없습니다. 이러한 모듈은 ОбщийМодуль.<Имя> 주소에서 볼 수 있지만 내부의 프로시저와 호출은 읽을 수 없습니다. 따라서 요약, 검색, 일반 모듈 목차, 역방향 검색, 중복 정보는 결과 위에 집계가 사용 가능한 소스에 대해서만 제공되며 불완전할 수 있음을 경고합니다.

측정 스크립트는 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에 위의 정확한 명령으로 read-only 모드에서 --save 없이 촬영되었습니다; 명령은 코드 0으로 종료되었습니다. 세 개의 수동 세트는 실제 표현과 실패 사례에서 수집되었고, 마지막 두 개는 데이터 자체에서 구성됩니다. 프로시저의 순위는 [실패, 실패, 7]입니다. 이는 개선을 위한 기준선이지 수용 기준이 아닙니다.

프로시저 행은 별도로 더 빠르게 재현됩니다:

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

'격차' — 첫 번째 결과가 두 번째 결과에서 얼마나 떨어져 있는지, 중앙값으로. '확실히 맞았는지 우연인지'라는 질문에 답합니다: 쿼리 언어의 35% 대 도움말의 91.7%는 이러한 승리가 3배 더 약하게 유지되며 순위 조정이 P@1의 1%도 움직이지 않고 뒤집을 수 있음을 의미합니다.

검색 지연 시간은 세트에 따라 쿼리당 0.18~1.4ms입니다.

쿼리 세트는 이미지에 포함되지 않습니다 (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 응답

'열림'과 '비활성화됨'의 차이는 의도적입니다. 토큰 없는 읽기는 작동합니다 — 자신의 머신에서는 편리하고 위험하지 않습니다. 토큰 없는 쓰기는 전혀 작동하지 않습니다: 사전 편집 한 번 실패하면 공유 서버에 연결된 모든 사람의 검색이 조용히 깨집니다.

토큰은 헤더로 전달됩니다 — X-Api-Token 또는 Authorization: Bearer <토큰>. 관리 토큰은 읽기에도 유효합니다: 그렇지 않으면 소유자가 클라이언트에 두 개의 헤더를 유지해야 하기 때문입니다.

토큰은 라틴 문자여야 합니다. HTTP 헤더는 latin-1로 인코딩되며 키릴 문자 토큰은 물리적으로 서버에 도달하지 않습니다: 브라우저의 로그인 양식을 통해서는 작동하지만 클라이언트 헤더를 통해서는 작동하지 않습니다.

검사에서 제외되는 두 경로: /health(컨테이너 healthcheck가 사용하며 읽기 권한 이상의 정보를 제공하지 않음) 및 /login — 그렇지 않으면 로그인 양식이 발급하는 바로 그 인증 뒤에 갇히게 됩니다.

토큰과 관련 없는 두 가지 추가 규칙:

  • MCP 엔드포인트는 구성 구조를 전체적으로 반환합니다. 자신의 머신 밖으로 가져갈 때는 API_TOKEN을 설정하세요. 네트워크 액세스만으로는 충분하지 않습니다.

  • data/ 디렉토리는 전체가 .gitignore에 있습니다 — 내보내기가 있는 .hbk와 파싱된 인덱스 모두. 도움말 인덱스는 1C 회사의 동일한 콘텐츠를 압축만 푼 것입니다. 한 번 거기에 들어가 20개의 커밋 동안 남아 있었습니다. 기록은 git filter-repo로 다시 작성되었고 규칙은 확장자가 아닌 디렉토리 기준으로 재구성되었습니다: 확인해야 할 것은 '이것이 .hbk인가?'가 아니라 '이것이 data/에 있는가?'입니다.


7. 문서

파일

내용

CHANGELOG.md

1C에 대해 수행된 작업과 확인된 사항

docs/schema-v1.md

내보내기 형식 계약

docs/data-sources.md

어떤 소스에서 무엇을 가져오는지

docs/query-language-design.md

쿼리 언어 소스의 구조

docs/dashboard-design.md

대시보드 구조

docs/modules-intake-design.md

구성 내보내기를 파일로 수신 — 문제 정의

docs/modules-provider-design.md

코드 공급자의 인덱스 및 도구

exporter-1c/README.md

1C용 내보내기 처리

CONTRIBUTING.md

프로젝트 수정 방법: 언어, 커밋, 검사

SECURITY.md

취약점 신고 방법

6개의 자족적 계약 문서가 게시됩니다: 내보내기 형식, 소스 경계, 쿼리 언어 및 대시보드 구조, 코드 내보내기 수신 및 코드 공급자. 공개 파일의 각 링크는 저장소에도 포함된 자료로 연결되어야 합니다.

외부 DB, 벡터, 그래프 DB, SSE 전송 및 지연 로딩은 현재 코퍼스의 측정으로 기각되었습니다. 이전 비용을 반증하거나 새로운 실제 시나리오를 보여주는 새로운 측정이 있어야만 다시 검토할 수 있습니다.


8. 라이선스

Apache License 2.0. NOTICE도 별도로 읽어야 합니다 — 라이선스 자체가 말하지 않는 두 가지가 있습니다:

  • 프로젝트는 독립적으로 개발되었으며 ООО «1С»와 제휴하지 않습니다; '1С' 및 '1С:Предприятие'는 ООО «1С»의 상표이며 라이선스는 이에 대한 권리를 부여하지 않습니다(Apache 2.0, 섹션 6);

  • 저장소에는 플랫폼 도움말도 구성 내보내기도 없습니다 — 원본 형태든 파싱된 형태든. 이는 1C 회사의 콘텐츠와 특정 구현의 데이터입니다. 각자는 자신의 배포판에서 가져와 data/에 넣습니다. 라이선스는 코드에 적용되며, 코드에 로드한 데이터에는 적용되지 않습니다.

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