Claude Skill

1c-mcp-toolkit

Прямой HTTP API к живой запущенной базе 1С:Предприятие через обработку MCP_Toolkit.epf (REST на http://localhost:6003/api/*). 12 эндпоинтов: запросы (execute_query), BSL-код (execute_code), метаданные (get_metadata), ссылки и навигация (get_object_by_link, get_link_of_object), по

LLM Mart · 0 points · 13 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download Desko77-claude-code-skills-1c-skills_1c-mcp-toolkit-eb281b4.zip · 32 KB
Part of desko77/claude-code-skills-1c — 48 skills

Install

skills CLI npx skills add https://github.com/Desko77/claude-code-skills-1c/tree/main/skills/1c-mcp-toolkit
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install desko77-claude-code-skills-1c@llmmart
Git git clone https://github.com/Desko77/claude-code-skills-1c.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole desko77/claude-code-skills-1c collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

1C MCP Toolkit - прямой HTTP API к живой базе 1С

REST API на http://localhost:6003/api/* через обработку MCP_Toolkit.epf, запущенную в тонком (или толстом) клиенте 1С. Встроенный HTTP-сервер реализован нативной компонентой MCPHttpTransport. Без модификации конфигурации, без COM, без публикации через web-сервер.

Обработка MCP_Toolkit.epf - разработка ROCTUP, репозиторий: https://github.com/ROCTUP/1c-mcp-toolkit (там же исходники нативной компоненты и документация).

Используется когда LLM-агент работает с живой базой (тесты, диагностика, прямой вызов экспортных функций), и при этом классические EDT-инструменты не подходят (нет dev-проекта, нужны данные runtime, нужен реальный пользовательский контекст).

Протокол: агент делает сам, порты не переспрашивает

Правила против холостых ходов "запусти / проверь / какой порт":

  1. Карта портов проекта. Сначала взять карту "среда/ИБ -> порт" из CLAUDE.md ТЕКУЩЕГО проекта (секция "MCP Toolkit") или памяти проекта. Есть карта - работать с нужным портом, probe пропустить. Нет карты - после probe предложить пользователю добавить ее в CLAUDE.md.

  2. Health-probe вместо вопросов. Не спрашивать "toolkit запущен? какой порт?": pwsh scripts/health-probe.ps1 (обход типовых 6003/6004/6005/6010/6013/6023/6033/7003) или bash-цикл:

    for p in 6003 6004 6005 6010 6013 6023 6033 7003; do
      curl -sS -m 2 "http://localhost:$p/health" >/dev/null 2>&1 && echo "порт $p жив"
    done
    
  3. Ничего не живо - запустить самому. scripts/start-1c.ps1 -AutoStart, если параметры базы (платформа, путь, пользователь) известны из карты/памяти. Спрашивать пользователя только при неизвестных параметрах.

  4. Полный цикл - самостоятельно. Обновить ИБ и проверить данные = один заход без ручного handoff: stop-1c.ps1 (или execute_code ЗавершитьРаботуСистемы) -> update_database (EDT MCP) -> start-1c.ps1 -AutoStart -> health -> запросы. Пользователя дергать только если неизвестны платформа/база/учетка ИЛИ он явно просил паузу (демо, живой показ).

  5. Ошибка "функция не определена" / connection refused - чаще всего toolkit просто не запущен: сначала health-probe и перезапуск, потом разбор кода.

  6. Не предлагать рестарт rphost/rmngr при обычном обновлении конфигурации - это не нужно (зона администраторов).

Быстрый старт

1. Запуск 1С с авто-открытием обработки

EPF лежит прямо в скилле:

Запускать .ps1-скрипты ниже строго через PowerShell 7 (pwsh), НЕ через powershell.exe (5.1). PS 5.1 спотыкается на кириллице в JSON-телах toolkit (stop-1c.ps1 со ЗавершитьРаботуСистемы и т.п. - "не смог распарсить stop-скрипт"). Инструмент PowerShell агента уже работает на pwsh 7 - используй его. Из Bash tool вызывай pwsh явно (не powershell.exe):

'/c/Program Files/PowerShell/7/pwsh.exe' -NoProfile -ExecutionPolicy Bypass -Command '& "$HOME\.claude\skills\1c-mcp-toolkit\scripts\start-1c.ps1" -Platform "8.3.27.2074" -Database "..." -User "..." -Password "..."'

Минимальная PowerShell-команда (в pwsh 7):

& "C:\Program Files\1cv8\<версия>\bin\1cv8c.exe" `
    /F"<путь к файловой базе>" `
    /N"<имя пользователя>" `
    /P"<пароль>" `
    /Execute"$HOME\.claude\skills\1c-mcp-toolkit\bin\MCP_Toolkit.epf"

Готовый параметризованный скрипт: scripts/start-1c.ps1.

Пример:

& "$HOME\.claude\skills\1c-mcp-toolkit\scripts\start-1c.ps1" `
    -Platform "8.3.27.2074" `
    -Database "C:\Bases\MyDB" `
    -User "Admin" `
    -Password "<пароль>"

Без /N и /P 1С зависает на форме авторизации, HTTP-сервер не поднимается.

После запуска в обработке на вкладке "Подключение" выбрать "Встроенный сервер", порт 6003, формат TOON, нажать "Запустить сервер" (если не настроен автостарт).

2. Проверка готовности

curl http://localhost:6003/health

200 OK - сервер на 6003 работает, можно делать запросы.

3. Закрытие 1С (например, для deploy через EDT)

curl -sS -X POST "http://localhost:6003/api/execute_code" \
  -H "Content-Type: application/json" \
  -d '{"code":"ЗавершитьРаботуСистемы(Ложь, Ложь); Результат=\"OK\";","execution_context":"client"}'

Готовый скрипт: scripts/stop-1c.ps1.

execution_context: "client" обязателен - ЗавершитьРаботуСистемы доступна только на клиенте.

Когда использовать MCP Toolkit

  • Проверка реальных данных в живой БД (полнота тестовых данных, корректность миграции, количество записей)
  • Прямой вызов экспортных функций модулей выгрузки/обмена без UI
  • Поиск конкретных проводок/документов для воспроизведения багов
  • Чтение метаданных из живой БД (когда нет открытого EDT-проекта)
  • Чтение журнала регистрации с фильтрацией
  • Поиск ссылок на объект ("где используется этот контрагент")
  • Диагностика прав доступа

Когда НЕ использовать (есть альтернатива получше)

Задача Лучше использовать
Чтение BSL-кода, навигация по модулям mcp__ai-edt__read_method_source, get_module_structure
Валидация запроса до запуска mcp__ai-edt__validate_query
Метаданные в режиме разработки (XML) mcp__ai-edt__get_metadata_objects/get_metadata_details
Семантический поиск по коду mcp__ai-edt__search_in_code, find_references
Запрос без живой БД (только EDT) mcp__ai-edt__execute_query (если доступен)
Проверка качества BSL mcp__1c-naparnik__ask_1c_ai

MCP Toolkit заточен под живую запущенную базу, EDT - под dev-режим с исходниками. Не дублируй вызовы.

Базовые запросы

Health

curl http://localhost:6003/health

execute_query (минимум)

curl -sS -X POST "http://localhost:6003/api/execute_query" \
  -H "Content-Type: application/json" \
  -d '{"query":"ВЫБРАТЬ ПЕРВЫЕ 5 Наименование ИЗ Справочник.Контрагенты"}'

execute_code (минимум)

curl -sS -X POST "http://localhost:6003/api/execute_code" \
  -H "Content-Type: application/json" \
  -d '{"code":"Результат = ТекущаяДата();"}'

get_metadata (root summary)

curl http://localhost:6003/api/get_metadata

12 эндпоинтов

# Эндпоинт Метод Назначение
1 get_metadata GET/POST Метаданные: типы, объекты, реквизиты, поиск по атрибуту
2 execute_query POST Выполнить запрос 1С, вернуть набор записей
3 execute_code POST Выполнить BSL-код, вернуть значение Результат
4 get_object_by_link POST Получить объект по navigation link
5 get_link_of_object POST Сформировать navigation link из object_description
6 find_references_to_object POST Найти все ссылки на объект в БД
7 get_access_rights POST Права на объект для роли/пользователя
8 get_event_log POST Журнал регистрации с фильтрацией и пагинацией
9 get_bsl_syntax_help POST Встроенная справка платформы 1С
10 submit_for_deanonymization POST Деанонимизация ответа (если анонимизация включена)
11 restart_1c_session POST Перезапуск сессии (подхват изменений конфигурации)
12 close_1c_session POST Закрытие сессии (для эксклюзивного доступа к БД)

Полная справка по всем параметрам, ответам, граничным случаям, всем вариантам curl - references/tools-full-reference.md.

Формат ответов: TOON по умолчанию

Внешняя обертка всегда JSON:

{"success": true, "data": <result>}
{"success": false, "error": "описание"}

Поле data по умолчанию закодировано в TOON (компактный текстовый формат, экономит 30-60% токенов по сравнению с JSON). Переключается через env RESPONSE_FORMAT=json на сервере или в форме обработки.

TOON-формат:

  • [N] - массив длины N
  • [N]{"Колонка1","Колонка2"}: ... - таблица с N строк и колонками
  • Скаляры - как "ключ": значение

Передача ссылок: object_description

В ответах execute_query поля ссылочного типа возвращаются как:

{
  "_objectRef": true,
  "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
  "ТипОбъекта": "СправочникСсылка.Контрагенты",
  "Представление": "ООО Рога и Копыта"
}

Эта структура - input для get_link_of_object, find_references_to_object, get_event_log (фильтр по объекту), а также передается в params для execute_query:

{
  "query": "ВЫБРАТЬ ... ИЗ Документ.Реализация ГДЕ Контрагент = &К",
  "params": {
    "К": {
      "_objectRef": true,
      "УникальныйИдентификатор": "ba7e5a3d-...",
      "ТипОбъекта": "СправочникСсылка.Контрагенты"
    }
  }
}

Полная спецификация - references/object-description-format.md.

Правила экранирования curl

При сборке curl-команд с JSON-payload, содержащим BSL-код и запросы 1С, участвует несколько уровней кавычек. Правила ниже - для bash/sh (Bash tool). В PowerShell экранирование иное: одинарные кавычки тоже литерал, но ! не раскрывается, а $ в двойных кавычках подставляется.

Правило 1: одинарные кавычки для payload -d (рекомендуется)

Одинарные кавычки запрещают bash интерпретировать $, !, &, обратные кавычки и прочие спецсимволы внутри payload. Двойные кавычки тоже работают, но требуют аккуратности.

# Рекомендуется - одинарные кавычки, bash ничего внутри не трогает:
curl ... -d '{"query":"ВЫБРАТЬ 1"}'

# Тоже работает, но bash интерпретирует спецсимволы - осторожно:
curl ... -d "{\"query\":\"ВЫБРАТЬ 1\"}"

Правило 2: строковые значения в запросах - всегда через параметры

Вместо встраивания строковых литералов прямо в текст запроса (что требует сложного экранирования) - всегда передавать их как параметры. Это полностью устраняет вложенные кавычки.

# ХОРОШО - значение передано параметром, без вложенных кавычек:
curl ... -d '{"query":"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Статус = &Статус", "params":{"Статус":"Активный"}}'

# ХОРОШО - то же для execute_code:
curl ... -d '{"code":"Запрос = Новый Запрос;\nЗапрос.Текст = \"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Статус = &Статус\";\nЗапрос.УстановитьПараметр(\"Статус\", \"Активный\");\nРезультат = Запрос.Выполнить().Выгрузить();"}'

Правило 3: избегать ! в строковых значениях

Bash интерпретирует ! как history expansion даже внутри некоторых контекстов кавычек. Никогда не использовать ! в строковых литералах - заменять безопасными альтернативами.

# ПЛОХО - ! запускает history expansion:
-d '{"code":"...ТОГДА \"!!! ВЫСОКАЯ\"..."}'

# ХОРОШО - без восклицательных знаков:
-d '{"code":"...ТОГДА \"ВЫСОКАЯ\"..."}'

Правило 4: строковые литералы внутри запроса (edge-case)

Если литерал в тексте запроса без параметра неизбежен, экранирование зависит от контекста:

execute_query - один уровень JSON-экранирования (\"):

curl ... -d '{"query":"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО \"%Рога%\""}'

execute_code - экранирование строки 1С "" плюс JSON-экранирование (\"\"):

curl ... -d '{"code":"Запрос.Текст = \"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО \"\"%Рога%\"\"\";"}'

По возможности всегда предпочитать Правило 2 (параметры).

Краткая справка

Символ Проблема Решение
" внутри строки запроса Вложенное экранирование Передать значение параметром (Правило 2)
! Bash history expansion Избегать полностью
& Bash интерпретирует в двойных кавычках Безопасно внутри payload в одинарных кавычках
\n Перенос строки в JSON-строке Для разделения операторов 1С, НЕ внутри текста запроса

Типичные ошибки и обходы

"Не задано значение параметра"

В execute_query параметр запроса передан не как params. Использовать ключ params, не parameters.

Регистр бухгалтерии Хозрасчетный: "Поле не найдено X.Счет" / "X.Субконто1"

Регистр двусторонний (Корреспонденция=true). В физической таблице есть только СчетДт, СчетКт. Поля Счет, Субконто1..3 доступны только в виртуальных таблицах: ОборотыДтКт, ДвиженияССубконто, Обороты, Остатки.

"Поле не найдено Организация" в условии ОборотыДтКт

В виртуальных таблицах Хозрасчетного условие на Организация через 6-й параметр не всегда работает. Использовать ДвиженияССубконто (условие в 3-м параметре, на физические поля), либо отбор через КорСубконтоИзмерения.

"Неверные параметры РегистрБухгалтерии.Хозрасчетный.Обороты"

Параметры виртуальных таблиц регистра бухгалтерии (важна последовательность):

  • .Остатки(): 3 параметра (Период, Субконто, Условие)
  • .Обороты(): 6 параметров (НачП, КонП, Периодичность, Субконто, Условие, КорСубконто)
  • .ОстаткиИОбороты(): 6 параметров
  • .ОборотыДтКт(): 6 параметров (НачП, КонП, Периодичность, СубконтоДт, СубконтоКт, Условие)
  • .ДвиженияССубконто(): 5 параметров (НачП, КонП, Условие, Порядок, Первые)

execute_code: "Процедура или функция с именем не определена (ДатаВремя)"

В BSL ДатаВремя - это токен языка запросов, не функция платформы. В коде использовать Дата(2026, 1, 1).

execute_code: запрос внутри Запрос.Текст должен быть однострочным

Внутри литерала Запрос.Текст = "..." текст запроса должен быть на одной строке. Многострочное форматирование через \n внутри литерала ломает парсер.

Правильно:

Запрос.Текст = "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Контрагенты ГДЕ НЕ ПометкаУдаления";

execute_code: запрещенные ключевые слова

По умолчанию блокируются: Удалить, Записать, УстановитьПривилегированныйРежим, COMОбъект, УдалитьФайлы и др. Список настраивается в обработке. Для тестов на запись - либо снять защиту в форме, либо использовать API объектов в обход ключевого слова (например, Объект = Документ.СоздатьДокумент(); Объект.Записать() не пройдет из-за Записать).

Типичные паттерны

Открытие формы в сеансе 1С (execution_context=client)

Отдельного эндпоинта open_form НЕТ (проверено по ROCTUP, 27.07.2026: 12 эндпоинтов без него). Форму открывает ОткрытьФорму(...) в КЛИЕНТСКОМ контексте - проверено рабочим:

curl -sS -X POST "http://localhost:6003/api/execute_code"   -d '{"code":"ОткрытьФорму(\"Документ.Х.ФормаСписка\"); Результат=\"OK\";","execution_context":"client"}'

Форма откроется в окне ЗАПУЩЕННОГО сеанса 1С (не headless - пользователь видит ее на экране). Список: .ФормаСписка (или без указания формы - автоформа списка); объект: ОткрытьФорму("Документ.Х.ФормаОбъекта", Новый Структура("Ключ", СсылкаНаОбъект)). Для АГЕНТА картинку формы дает EDT MCP get_form_screenshot (сам toolkit возвращает только текст/данные, не изображение).

Прямой вызов экспортной функции модуля выгрузки

curl -sS -X POST "http://localhost:6003/api/execute_code" \
  -H "Content-Type: application/json" \
  -d '{"code":"Орг = Справочники.Организации.НайтиПоНаименованию(\"МояОрганизация\"); Дата1 = Дата(2026,1,1); Дата2 = Дата(2026,3,31,23,59,59); Рез = МойМодульВыгрузки.СформироватьДанные(Дата1, Дата2, Орг); Результат = Новый Структура(\"КоличествоСтрок,Ошибки\", Рез.Данные.Количество(), Рез.Ошибки);"}'

Сводка по проводкам двустороннего Хозрасчетного через UNION

ВЫБРАТЬ Сторона.КодСчета, СУММА(Сторона.СуммаДт), СУММА(Сторона.СуммаКт)
ИЗ (
    ВЫБРАТЬ ПСД.Код КАК КодСчета, Х.Сумма КАК СуммаДт, 0 КАК СуммаКт
    ИЗ РегистрБухгалтерии.Хозрасчетный КАК Х
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланСчетов.Хозрасчетный КАК ПСД ПО Х.СчетДт = ПСД.Ссылка
    ГДЕ Х.Период МЕЖДУ &Д1 И &Д2
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ ПСК.Код, 0, Х.Сумма
    ИЗ РегистрБухгалтерии.Хозрасчетный КАК Х
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланСчетов.Хозрасчетный КАК ПСК ПО Х.СчетКт = ПСК.Ссылка
    ГДЕ Х.Период МЕЖДУ &Д1 И &Д2
) КАК Сторона
СГРУППИРОВАТЬ ПО Сторона.КодСчета

Передача параметра-ссылки в запрос

curl -sS -X POST "http://localhost:6003/api/execute_query" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Кол ИЗ Документ.РеализацияТоваровУслуг ГДЕ Организация = &Орг",
    "params": {
      "Орг": {
        "_objectRef": true,
        "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
        "ТипОбъекта": "СправочникСсылка.Организации"
      }
    }
  }'

Готовые workflow

Полные многошаговые сценарии с командами и ответами - в references/workflow-examples.md:

  1. Explore an unfamiliar database - разведка БД (health → metadata summary → list → detail → sample query)
  2. Investigate object dependencies - проверка зависимостей объекта (execute_query → find_references → access_rights → event_log)
  3. Diagnose event log errors - диагностика ошибок из журнала (get_event_log с пагинацией → execute_query вокруг ошибочных объектов)

Цикл deploy через MCP Toolkit + EDT

Типичный цикл "правка кода - проверка в живой базе":

  1. Внести изменения в код в EDT, запустить mcp__ai-edt__validate_query для запросов
  2. Закрыть 1С через MCP Toolkit:
    curl -sS -X POST "http://localhost:6003/api/execute_code" \
      -H "Content-Type: application/json" \
      -d '{"code":"ЗавершитьРаботуСистемы(Ложь, Ложь);","execution_context":"client"}'
    
  3. Обновить конфигурацию: mcp__ai-edt__update_database
  4. Запустить 1С с MCP Toolkit: scripts/start-1c.ps1 ...
  5. Дождаться поднятия: polling curl http://localhost:6003/health до 200
  6. Прогнать тестовые запросы через execute_query / execute_code

Совместимость

  • Платформа 1С: 8.2.13+ и 8.3.25+ (включая 8.3.27)
  • Архитектура: x64 (основной EPF) и x86 (отдельный EPF)
  • Запуск только в тонком (1cv8c.exe) или толстом (1cv8.exe) клиенте. Через web-клиент нативная компонента не работает.

Channel routing (multi-database)

Если запущено несколько обработок MCP_Toolkit с разными channel - передавать ?channel=<name> в URL:

curl -sS "http://localhost:6003/api/execute_query?channel=dev" \
  -H "Content-Type: application/json" \
  -d '{"query":"ВЫБРАТЬ 1"}'

Regex для имени: ^[a-zA-Z0-9_-]{1,64}$. По умолчанию default.

Связанные скиллы

  • composing-1c-queries - синтаксис языка запросов 1С (составление query для execute_query, виртуальные таблицы регистров, временные таблицы, JOIN-ы)

Ссылки на references

Источник

Репозиторий: https://github.com/ROCTUP/1c-mcp-toolkit

Этот скилл собран на основе родного скилла calling-1c-rest-api-via-curl из репо MCP-toolkit с дополнениями: раздел запуска 1С, готовые PowerShell-скрипты, EPF в bin/, типичные ошибки и паттерны.

Files (claude-code-skills-1c)
  • references
    • object-description-format.md 4.4 KB
      # Object Description Format
      
      ## Overview
      
      The `object_description` is a JSON structure that represents a reference to a 1C object. It flows between tools as a universal object identifier - it appears in query results and serves as input for several other tools.
      
      ## Structure
      
      ```json
      {
        "_objectRef": true,
        "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
        "ТипОбъекта": "СправочникСсылка.Контрагенты",
        "Представление": "ООО Рога и Копыта"
      }
      ```
      
      ### Fields
      
      | Field | Type | Required | Description |
      |-------|------|----------|-------------|
      | `_objectRef` | boolean | Yes | Must be `true`. Marks this object as a reference. |
      | `УникальныйИдентификатор` | string | Yes | UUID in format `8-4-4-4-12` (e.g., `ba7e5a3d-1234-5678-9abc-def012345678`). |
      | `ТипОбъекта` | string | Yes | Full type name (e.g., `СправочникСсылка.Контрагенты`, `ДокументСсылка.РеализацияТоваровУслуг`). |
      | `Представление` | string | No | Human-readable string representation (e.g., object name or document number). |
      
      ### UUID validation
      
      The `УникальныйИдентификатор` must match the regex:
      ```
      ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
      ```
      
      ## Where it appears as output
      
      ### 1. execute_query results
      
      When a query selects a reference column, each row contains an `object_description` for that column:
      
      ```sh
      curl -sS "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Ссылка, Контрагент ИЗ Документ.РеализацияТоваровУслуг","limit":2}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": [
          {
            "Ссылка": {
              "_objectRef": true,
              "УникальныйИдентификатор": "a1b2c3d4-5678-9012-3456-789012345678",
              "ТипОбъекта": "ДокументСсылка.РеализацияТоваровУслуг",
              "Представление": "Реализация №001 от 15.01.2024"
            },
            "Контрагент": {
              "_objectRef": true,
              "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
              "ТипОбъекта": "СправочникСсылка.Контрагенты",
              "Представление": "ООО Рога и Копыта"
            }
          }
        ]
      }
      ```
      
      ### 2. find_references_to_object results
      
      The `found_in_object` field in hits contains an `object_description` (for documents/catalogs):
      
      ```json
      {
        "found_in_object": {
          "_objectRef": true,
          "УникальныйИдентификатор": "...",
          "ТипОбъекта": "ДокументСсылка.РеализацияТоваровУслуг",
          "Представление": "Реализация №001 от 01.01.2024"
        }
      }
      ```
      
      ## Where it is required as input
      
      ### 1. get_link_of_object
      
      Pass `object_description` to generate a navigation link:
      
      ```sh
      curl -sS "$BASE_URL/api/get_link_of_object?channel=$CHANNEL" $J \
        -d '{"object_description":{"_objectRef":true,"УникальныйИдентификатор":"ba7e5a3d-1234-5678-9abc-def012345678","ТипОбъекта":"СправочникСсылка.Контрагенты"}}'
      ```
      
      ### 2. find_references_to_object
      
      Pass as `target_object_description`:
      
      ```sh
      curl -sS "$BASE_URL/api/find_references_to_object?channel=$CHANNEL" $J \
        -d '{"target_object_description":{"_objectRef":true,"УникальныйИдентификатор":"ba7e5a3d-1234-5678-9abc-def012345678","ТипОбъекта":"СправочникСсылка.Контрагенты"},"search_scope":["documents"]}'
      ```
      
      ### 3. get_event_log (object filter)
      
      Pass as `object_description` to filter event log by object:
      
      ```sh
      curl -sS "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"object_description":{"_objectRef":true,"УникальныйИдентификатор":"ba7e5a3d-1234-5678-9abc-def012345678","ТипОбъекта":"СправочникСсылка.Контрагенты"},"limit":50}'
      ```
      
      ## Typical flow: query → extract → use
      
      ```
      Step 1: execute_query  →  get object_description from result rows
      Step 2: use that object_description as input to:
              - get_link_of_object (generate clickable link)
              - find_references_to_object (find where it is used)
              - get_event_log (view history for this object)
      ```
      
    • tools-full-reference.md 40.7 KB
      # Tools Full Reference
      
      Complete parameter tables, curl examples, and response structures for all 12 REST API endpoints.
      
      > **Convention**: all examples use the variables from Quick Start:
      > ```sh
      > BASE_HOST=localhost
      > BASE_URL="http://$BASE_HOST:6003"
      > CHANNEL="default"
      > J='-H Content-Type:application/json'
      > ```
      
      ---
      
      ## 1. get_metadata - `GET/POST /api/get_metadata`
      
      Explore database structure. Summary/list/details modes depend on parameters; the configuration scope is controlled via `extension_name`.
      
      Request rules:
      - **GET**: parameters come from the URL query string; the request body is ignored
      - **POST**: parameters come from the JSON body; the query string is ignored **except** `?channel=<id>`
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `filter` | string | null | - | Exact object name for detailed structure (e.g., `Справочник.Номенклатура`) or full path to a collection element (e.g., `Справочник.Контрагенты.Реквизит.ИНН`) |
      | `meta_type` | string or string[] | null | Use `"*"` for all types | Root metadata type(s): Справочник, Документ, РегистрСведений, РегистрНакопления, РегистрБухгалтерии, РегистрРасчета, ПланВидовХарактеристик, ПланСчетов, ПланВидовРасчета, ПланОбмена, БизнесПроцесс, Задача, Константа, Перечисление, Отчет, Обработка, РегламентноеЗадание, ПараметрыСеанса |
      | `name_mask` | string | null | - | Case-insensitive search in name/synonym |
      | `limit` | integer | 100 | 1-1000 | Max objects in list mode |
      | `offset` | integer | 0 | 0-1000000 | Pagination offset in list mode |
      | `sections` | string[] | null | Requires `filter`; incompatible with `attribute_mask` | Detail sections: `properties`, `forms`, `commands`, `layouts`, `predefined`, `movements`, `characteristics`. Note: `movements` only applies to `Документ` objects - silently ignored for other types |
      | `extension_name` | string | null | No whitespace-only | `null`=main config, `""`=list extensions, `"Name"`=extension objects |
      | `attribute_mask` | string | null | Incompatible with `sections` | Case-insensitive substring search across all attribute names/synonyms (реквизиты, измерения, ресурсы, реквизиты ТЧ). Returns same list contract as Mode 2. Compatible with `meta_type`, `name_mask`, `filter` (root object only), `extension_name`. `extension_name=""` takes priority (returns extension list, ignores `attribute_mask`). |
      
      ### Mode 1: Summary (no filter/meta_type/name_mask)
      
      ```sh
      # Root type counts
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL"
      ```
      
      Response:
      ```json
      {
        "success": true,
        "configuration": {
          "platform_version": "8.3.25.1000",
          "infobase_name": "MyDB",
          "metadata": {"Имя": "MyConfiguration", "Синоним": "My Configuration"}
        },
        "data": [
          {"Тип": "Справочник", "Количество": 265},
          {"Тип": "Документ", "Количество": 27},
          {"Тип": "РегистрСведений", "Количество": 150}
        ]
      }
      ```
      
      Notes:
      - If you call summary **inside a specific extension** (`extension_name="MyExtension"` and no `filter/meta_type/name_mask`), the response includes the same `data` (root type counts) plus top-level fields `extension` and `configuration`.
      - `extension_name=""` is **not** summary - it returns the list of connected extensions (see “Extensions” below).
      
      ### Mode 2: List (meta_type and/or name_mask, without filter)
      
      ```sh
      # All documents containing "реализ"
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" \
        --data-urlencode "meta_type=Документ" \
        --data-urlencode "name_mask=реализ" \
        --data-urlencode "limit=50"
      
      # Multiple types via comma in GET
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" \
        --data-urlencode "meta_type=Документ,РегистрСведений" \
        --data-urlencode "limit=50" \
        --data-urlencode "offset=0"
      
      # All objects across all types
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" \
        --data-urlencode "meta_type=*" \
        --data-urlencode "limit=200"
      
      # POST variant
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"meta_type":"Справочник","name_mask":"номенклат","limit":50}'
      
      # Multiple types via POST (array)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"meta_type":["Документ","РегистрСведений"],"limit":200}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "truncated": false,
        "limit": 50,
        "offset": 0,
        "returned": 2,
        "has_more": false,
        "next_offset": 2,
        "data": [
          {"ПолноеИмя": "Документ.РеализацияТоваровУслуг", "Синоним": "Реализация товаров и услуг"},
          {"ПолноеИмя": "Документ.РеализацияОтгруженныхТоваров", "Синоним": "Реализация отгруженных товаров"}
        ]
      }
      ```
      
      ### Mode 3: Detail (filter specified)
      
      ```sh
      # Basic detail
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" \
        --data-urlencode "filter=РегистрНакопления.ОстаткиТоваров"
      
      # Rich card with all sections
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"filter":"Справочник.Номенклатура","sections":["properties","forms","commands","layouts","predefined","movements","characteristics"]}'
      ```
      
      Response (detail):
      ```json
      {
        "success": true,
        "data": {
          "ТипОбъектаМетаданных": "РегистрНакопления",
          "Имя": "ОстаткиТоваров",
          "Синоним": "Остатки товаров",
          "ПолноеИмя": "РегистрНакопления.ОстаткиТоваров",
          "Измерения": [
            {"Имя": "Номенклатура", "Синоним": "Номенклатура", "Тип": "СправочникСсылка.Номенклатура"},
            {"Имя": "Склад", "Синоним": "Склад", "Тип": "СправочникСсылка.Склады"}
          ],
          "Ресурсы": [
            {"Имя": "Количество", "Синоним": "Количество", "Тип": "Число(15,3)"}
          ],
          "Реквизиты": [
            {"Имя": "Партия", "Синоним": "Партия", "Тип": "СправочникСсылка.Партии"}
          ]
        }
      }
      ```
      
      ### Mode 3a: Collection element (filter with full path)
      
      Collection names use singular segment names: `Реквизит`, `Измерение`, `Ресурс`, `ТабличнаяЧасть`, `СтандартныйРеквизит`, `РеквизитАдресации`.
      
      ```sh
      # Catalog attribute
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"filter":"Справочник.Контрагенты.Реквизит.ИНН"}'
      
      # Register dimension with extended properties
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"filter":"РегистрНакопления.Остатки.Измерение.Номенклатура","sections":["properties"]}'
      
      # Nested tabular section attribute
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"filter":"Документ.Реализация.ТабличнаяЧасть.Товары.Реквизит.Номенклатура"}'
      ```
      
      Response (collection element):
      ```json
      {
        "success": true,
        "data": {
          "ПолноеИмя": "Справочник.Контрагенты.Реквизит.ИНН",
          "Имя": "ИНН",
          "Синоним": "ИНН",
          "Тип": "Строка(12)"
        }
      }
      ```
      
      ### Extensions
      
      ```sh
      # List all extensions
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"extension_name":""}'
      
      # Objects inside a specific extension (list mode)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"extension_name":"MyExtension","meta_type":"Справочник"}'
      ```
      
      Extension list response (`extension_name=""`):
      ```json
      {
        "success": true,
        "data": [
          {"Имя": "MyExtension", "Синоним": "My Extension", "УникальныйИдентификатор": "a1b2c3d4-..."}
        ]
      }
      ```
      
      Note: for `extension_name="MyExtension"` (specific extension), responses include a top-level `extension` field in all modes (summary/list/details). In list mode it looks like this:
      ```json
      {
        "success": true,
        "extension": "MyExtension",
        "truncated": false,
        "limit": 50,
        "returned": 2,
        "count": 2,
        "offset": 0,
        "has_more": false,
        "next_offset": 2,
        "data": [
          {"ПолноеИмя": "Справочник.МойСправочник", "Синоним": "Мой справочник"}
        ]
      }
      ```
      
      ### Mode 5: Attribute search (attribute_mask)
      
      Search all attribute names/synonyms across all objects (or scoped to one object via `filter`).
      Returns the same list contract as Mode 2. `ПолноеИмя` uses singular segment names and can be passed directly to `filter` for round-trip detail lookup.
      
      ```sh
      # Find all attributes whose name or synonym contains "контраг"
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"attribute_mask":"контраг"}'
      
      # Scoped to one object
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"attribute_mask":"дата","filter":"Документ.Реализация"}'
      
      # With pagination
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"attribute_mask":"сумма","limit":50,"offset":0}'
      
      # Round-trip: find attribute, then get its detail
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"attribute_mask":"контраг","limit":1}'
      # → data[0]["ПолноеИмя"] = "Документ.Реализация.Реквизит.Контрагент"
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"filter":"Документ.Реализация.Реквизит.Контрагент","sections":["properties"]}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "truncated": false,
        "limit": 100,
        "offset": 0,
        "returned": 2,
        "count": 2,
        "has_more": false,
        "next_offset": 2,
        "data": [
          {"ПолноеИмя": "Документ.Реализация.Реквизит.Контрагент", "Синоним": "Контрагент"},
          {"ПолноеИмя": "Справочник.Контрагенты.Реквизит.ОсновнойДоговор", "Синоним": "Основной договор"}
        ]
      }
      ```
      
      Notes:
      - **Incompatible with `sections`** - returns error. Use round-trip instead: get `ПолноеИмя` from attribute search, then pass it to `filter` with `sections`.
      - Compatible with `meta_type` (restrict object types), `name_mask` (filter object names), `filter` (restrict to one root object), `extension_name` (specific extension).
      - `extension_name=""` (list extensions) takes priority - `attribute_mask` is ignored in that case.
      
      ---
      
      ## 2. execute_query - `POST /api/execute_query`
      
      Execute 1C query language queries and return results.
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `query` | string | **required** | min 1 char | 1C query language text |
      | `params` | object | null | - | Query parameters as key-value pairs |
      | `limit` | integer | 100 | 1-1000 | Max rows to return |
      | `include_schema` | boolean | false | Strict boolean only | Include column type schema in response |
      
      ### Examples
      
      ```sh
      # Simple query
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Код, Наименование ИЗ Справочник.Номенклатура","limit":5}'
      
      # With parameters
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ * ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО &Маска","params":{"Маска":"%Рога%"},"limit":10}'
      
      # With schema (useful for understanding data types)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ ПЕРВЫЕ 0 * ИЗ Справочник.Номенклатура","include_schema":true}'
      
      # Selecting references (returns object_description in rows)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Ссылка, Контрагент ИЗ Документ.РеализацияТоваровУслуг","limit":3}'
      ```
      
      Response (with schema):
      ```json
      {
        "success": true,
        "data": [
          {"Код": "001", "Наименование": "Товар 1", "Цена": 100.50}
        ],
        "schema": {
          "columns": [
            {"name": "Код", "types": ["Строка"]},
            {"name": "Наименование", "types": ["Строка"]},
            {"name": "Цена", "types": ["Число"]}
          ]
        },
        "count": 1
      }
      ```
      
      Response (with object_description in data):
      ```json
      {
        "success": true,
        "data": [
          {
            "Ссылка": {
              "_objectRef": true,
              "УникальныйИдентификатор": "a1b2c3d4-5678-9012-3456-789012345678",
              "ТипОбъекта": "ДокументСсылка.РеализацияТоваровУслуг",
              "Представление": "Реализация №001 от 15.01.2024"
            },
            "Контрагент": {
              "_objectRef": true,
              "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
              "ТипОбъекта": "СправочникСсылка.Контрагенты",
              "Представление": "ООО Рога и Копыта"
            }
          }
        ],
        "count": 1
      }
      ```
      
      ### Tip: explore table structure without loading data
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ ПЕРВЫЕ 0 * ИЗ Документ.РеализацияТоваровУслуг","include_schema":true}'
      ```
      
      ---
      
      ## 3. execute_code - `POST /api/execute_code`
      
      Execute arbitrary 1C code (statement block via `Выполнить`).
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `code` | string | **required** | min 1 char | 1C code to execute |
      | `execution_context` | string | `"server"` | `"server"` or `"client"` | Execution context: `"server"` - `&НаСервереБезКонтекста` (DB access, 1C objects); `"client"` - `&НаКлиенте` (form attributes, UI functions, no DB queries) |
      
      ### Rules
      
      - Must assign result to `Результат` variable: `Результат = <expression>;`
      - Cannot declare `Процедура` / `Функция`
      - Cannot use `Возврат`
      
      ### Dangerous keywords
      
      The following keywords are blocked by default (configurable via `DANGEROUS_KEYWORDS` env var):
      
      `Удалить`, `Delete`, `Записать`, `Write`, `УстановитьПривилегированныйРежим`, `SetPrivilegedMode`, `ПодключитьВнешнююКомпоненту`, `AttachAddIn`, `УстановитьВнешнююКомпоненту`, `InstallAddIn`, `COMОбъект`, `COMObject`, `УстановитьМонопольныйРежим`, `SetExclusiveMode`, `УдалитьФайлы`, `DeleteFiles`, `КопироватьФайл`, `CopyFile`, `ПереместитьФайл`, `MoveFile`, `СоздатьКаталог`, `CreateDirectory`
      
      Behavior when dangerous keyword detected:
      - `ALLOW_DANGEROUS_WITH_APPROVAL=false` (default): returns `success=false` immediately
      - `ALLOW_DANGEROUS_WITH_APPROVAL=true`: sends to 1C with `requires_approval=true`, waits for user decision in 1C UI
      
      ### Examples
      
      ```sh
      # Simple expression (server context, default)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_code?channel=$CHANNEL" $J \
        -d '{"code":"Результат = ТекущаяДата();"}'
      
      # Multi-line code
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_code?channel=$CHANNEL" $J \
        -d '{"code":"Запрос = Новый Запрос; Запрос.Текст = \"ВЫБРАТЬ 1 КАК Поле\"; Результат = Запрос.Выполнить().Выгрузить().Количество();"}'
      
      # Client context - open a form, read form attributes
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_code?channel=$CHANNEL" $J \
        -d '{"code":"ОткрытьФорму(\"Справочник.Номенклатура.ФормаСписка\"); Результат = \"OK\";","execution_context":"client"}'
      
      # With extended timeout (for long operations)
      curl --max-time 200 -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_code?channel=$CHANNEL" $J \
        -d '{"code":"Результат = 1;"}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": "2024-01-15T10:30:00"
      }
      ```
      
      Error response (dangerous keyword):
      ```json
      {
        "success": false,
        "error": "Код содержит потенциально опасные операции: ['Записать']. Выполнение запрещено / Code contains potentially dangerous operations: ['Записать']. Execution denied."
      }
      ```
      
      ---
      
      ## 4. get_object_by_link - `POST /api/get_object_by_link`
      
      Retrieve complete 1C object data by navigation link.
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `link` | string | **required** | Must match `e1cib/data/Type.Name?ref=HexGUID32` | Navigation link |
      
      ### Link format
      
      ```
      e1cib/data/Справочник.Контрагенты?ref=80c6cc1a7e58902811ebcda8cb07c0f5
               ├─ prefix: e1cib/data/
               ├─ type:   Справочник.Контрагенты
               └─ ref:    32 hex characters (HexGUID)
      ```
      
      ### Examples
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_object_by_link?channel=$CHANNEL" $J \
        -d '{"link":"e1cib/data/Справочник.Контрагенты?ref=80c6cc1a7e58902811ebcda8cb07c0f5"}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": {
          "_type": "Справочник.Контрагенты",
          "_presentation": "ООО Рога и Копыта",
          "Код": "001",
          "Наименование": "ООО Рога и Копыта",
          "ИНН": "7701234567",
          "КонтактныеЛица": [
            {"Имя": "Иванов И.И.", "Телефон": "+7-999-123-45-67"}
          ]
        }
      }
      ```
      
      ---
      
      ## 5. get_link_of_object - `POST /api/get_link_of_object`
      
      Generate a navigation link from an object description.
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `object_description` | object | **required** | Must have `_objectRef`, `УникальныйИдентификатор`, `ТипОбъекта` | Object description from execute_query results. See [object-description-format.md](object-description-format.md). |
      
      ### Examples
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_link_of_object?channel=$CHANNEL" $J \
        -d '{"object_description":{"_objectRef":true,"УникальныйИдентификатор":"ba7e5a3d-1234-5678-9abc-def012345678","ТипОбъекта":"СправочникСсылка.Контрагенты"}}'
      ```
      
      Response (**`data` is a string**, not an object):
      ```json
      {
        "success": true,
        "data": "e1cib/data/Справочник.Контрагенты?ref=ba7e5a3d12345678def012345678"
      }
      ```
      
      ---
      
      ## 6. find_references_to_object - `POST /api/find_references_to_object`
      
      Find all references to a given object across metadata collections.
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `target_object_description` | object | **required** | See [object-description-format.md](object-description-format.md) | Object to search for |
      | `search_scope` | string[] | **required** | Min 1 element | Areas to search |
      | `meta_filter` | object | null | - | Filter by metadata objects |
      | `meta_filter.names` | string[] | null | Format: `ТипМетаданных.ИмяОбъекта` | Exact metadata names (priority over name_mask) |
      | `meta_filter.name_mask` | string | null | - | Substring search in name/synonym |
      | `limit_hits` | integer | 200 | 1-10000 | Max total hits |
      | `limit_per_meta` | integer | 20 | 1-1000 | Max hits per metadata object |
      | `timeout_budget_sec` | integer | 30 | 5-300 | Time budget in seconds |
      
      ### Valid search_scope values
      
      | Value | Searches in |
      |-------|-------------|
      | `documents` | Documents (attributes, tabular sections) |
      | `catalogs` | Catalogs (attributes, tabular sections) |
      | `information_registers` | Information registers (dimensions, resources, attributes) |
      | `accumulation_registers` | Accumulation registers (dimensions, resources, attributes) |
      | `accounting_registers` | Accounting registers (dimensions, resources, attributes) |
      | `calculation_registers` | Calculation registers (dimensions, resources, attributes) |
      
      ### Examples
      
      ```sh
      # Find documents referencing a customer
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/find_references_to_object?channel=$CHANNEL" $J \
        -d '{
          "target_object_description": {
            "_objectRef": true,
            "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
            "ТипОбъекта": "СправочникСсылка.Контрагенты"
          },
          "search_scope": ["documents"],
          "limit_hits": 50
        }'
      
      # Search everywhere with meta_filter
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/find_references_to_object?channel=$CHANNEL" $J \
        -d '{
          "target_object_description": {
            "_objectRef": true,
            "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
            "ТипОбъекта": "СправочникСсылка.Номенклатура"
          },
          "search_scope": ["documents", "accumulation_registers", "information_registers"],
          "meta_filter": {"names": ["Документ.РеализацияТоваровУслуг", "РегистрНакопления.ОстаткиТоваров"]},
          "limit_per_meta": 10,
          "timeout_budget_sec": 60
        }'
      
      # Quick check: is the object referenced at all?
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/find_references_to_object?channel=$CHANNEL" $J \
        -d '{
          "target_object_description": {
            "_objectRef": true,
            "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
            "ТипОбъекта": "СправочникСсылка.Контрагенты"
          },
          "search_scope": ["documents", "catalogs", "information_registers", "accumulation_registers"],
          "limit_hits": 1,
          "timeout_budget_sec": 10
        }'
      ```
      
      ### Response structure
      
      ```json
      {
        "success": true,
        "data": {
          "hits": [
            {
              "found_in_meta": "Документ.РеализацияТоваровУслуг",
              "found_in_object": {
                "_objectRef": true,
                "УникальныйИдентификатор": "...",
                "ТипОбъекта": "ДокументСсылка.РеализацияТоваровУслуг",
                "Представление": "Реализация №001 от 01.01.2024"
              },
              "path": "Контрагент",
              "match_kind": "attribute",
              "note": "Реализация №001 от 01.01.2024"
            },
            {
              "found_in_meta": "РегистрНакопления.ОстаткиТоваров",
              "found_in_object": null,
              "record_key": {
                "Номенклатура": {"_objectRef": true, "ТипОбъекта": "СправочникСсылка.Номенклатура", "Представление": "Товар А"},
                "Склад": {"_objectRef": true, "ТипОбъекта": "СправочникСсылка.Склады", "Представление": "Основной"},
                "Период": "2024-01-15T00:00:00"
              },
              "path": "Номенклатура",
              "match_kind": "dimension",
              "note": "Номенклатура=Товар А; Склад=Основной; Период=15.01.2024"
            }
          ],
          "total_hits": 2,
          "candidates_checked": 12,
          "timeout_exceeded": false,
          "skipped_names": []
        }
      }
      ```
      
      Hit fields for documents/catalogs: `found_in_object` is an object_description, `match_kind` is `attribute` or `tabular_section`.
      
      Hit fields for registers: `found_in_object` is null, `record_key` contains dimensions/period/registrar, `match_kind` is `dimension`, `resource`, or `requisite`.
      
      ---
      
      ## 7. get_access_rights - `POST /api/get_access_rights`
      
      Get role permissions for a metadata object, optionally with effective rights for a user.
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `metadata_object` | string | **required** | Format `Type.Name`, must contain dot | Full metadata object name |
      | `user_name` | string | null | Case-insensitive search | User name (from IB users or Пользователи catalog) |
      | `rights_filter` | string[] | null | - | Show only these rights (null = default list for object type) |
      | `roles_filter` | string[] | null | Case-insensitive match | Show only these roles (null = all roles with rights) |
      
      ### Limitations
      
      - `effective_rights` is "sum of roles", NOT a guarantee of actual access
      - Row-Level Security (RLS) is NOT taken into account
      - Contextual restrictions (by organizations, departments) are NOT considered
      - Admin rights required for user-specific queries
      - Privileged mode forbidden (would make all results `true`)
      
      ### Examples
      
      ```sh
      # Role permissions for a catalog
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_access_rights?channel=$CHANNEL" $J \
        -d '{"metadata_object":"Справочник.Контрагенты"}'
      
      # With user effective rights
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_access_rights?channel=$CHANNEL" $J \
        -d '{"metadata_object":"Документ.РеализацияТоваровУслуг","user_name":"Иванов"}'
      
      # Filtered by specific rights and roles
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_access_rights?channel=$CHANNEL" $J \
        -d '{"metadata_object":"Справочник.Контрагенты","rights_filter":["Чтение","Изменение","Добавление","Удаление"],"roles_filter":["ПолныеПрава","Менеджер"]}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": {
          "metadata_object": "Справочник.Контрагенты",
          "metadata_type": "Справочник",
          "applicable_rights": ["Чтение", "Изменение", "Добавление", "Удаление", "Просмотр", "ИнтерактивноеДобавление"],
          "roles": [
            {
              "name": "Менеджер",
              "rights": {"Чтение": true, "Изменение": true, "Добавление": true, "Удаление": false}
            },
            {
              "name": "ПолныеПрава",
              "rights": {"Чтение": true, "Изменение": true, "Добавление": true, "Удаление": true}
            }
          ],
          "total_roles": 2,
          "roles_with_rights": 2,
          "user": {
            "name": "Иванов",
            "full_name": "Иванов Иван Иванович",
            "roles": ["Менеджер"],
            "effective_rights": {
              "Чтение": true,
              "Изменение": true,
              "Добавление": true,
              "Удаление": false
            }
          }
        }
      }
      ```
      
      ---
      
      ## 8. get_event_log - `POST /api/get_event_log`
      
      Get event log entries with filtering and cursor-based pagination.
      
      ### Parameters
      
      | Parameter | Type | Default | Constraints | Description |
      |-----------|------|---------|-------------|-------------|
      | `start_date` | string | null | ISO 8601: `YYYY-MM-DDTHH:MM:SS` | Start date |
      | `end_date` | string | null | ISO 8601: `YYYY-MM-DDTHH:MM:SS` | End date |
      | `levels` | string[] | null | `Information`, `Warning`, `Error`, `Note` | Importance levels |
      | `events` | string[] | null | e.g., `_$Data$_.New`, `_$Data$_.Update` | Event types |
      | `limit` | integer | 100 | 1-1000 | Max records per page |
      | `same_second_offset` | integer | 0 | 0-10000, requires `start_date` | Skip N records at same second (for pagination) |
      | `object_description` | object | null | See [object-description-format.md](object-description-format.md) | Filter by object (priority 1) |
      | `link` | string | null | `e1cib/data/...?ref=HexGUID32` | Filter by nav link (priority 2) |
      | `data` | string | null | - | Filter by nav link (priority 3, backward compat) |
      | `metadata_type` | string or string[] | null | e.g., `Документ.РеализацияТоваровУслуг` | Filter by metadata object type |
      | `user` | string[] | null | - | Filter by user name(s) |
      | `session` | integer[] | null | - | Filter by session number(s) |
      | `application` | string[] | null | See valid values below | Filter by application type |
      | `computer` | string | null | - | Filter by computer name |
      | `comment_contains` | string | null | - | Substring search in comments |
      | `transaction_status` | string | null | `Committed`, `RolledBack`, `NotApplicable`, `Unfinished` | Transaction status filter |
      
      ### Valid application values
      
      `ThinClient`, `WebClient`, `ThickClient`, `BackgroundJob`, `Designer`, `COMConnection`, `Server`, `WebService`, `HTTPService`, `ODataInterface`, `MobileAppClient`, `MobileAppServer`, `MobileAppBackgroundJob`, `MobileClient`, `MobileStandaloneServer`, `FileVariantBackgroundJob`, `FileVariantServerSide`, `WebSocket`, `FileVariantWebSocket`, `1CV8C`, `1CV8`
      
      ### Examples
      
      ```sh
      # Errors in a date range
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-01T00:00:00","end_date":"2024-01-31T23:59:59","levels":["Error","Warning"],"limit":100}'
      
      # Events for a specific user
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-15T00:00:00","user":["Иванов"],"limit":50}'
      
      # Events for a specific object (using object_description)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"object_description":{"_objectRef":true,"УникальныйИдентификатор":"ba7e5a3d-1234-5678-9abc-def012345678","ТипОбъекта":"СправочникСсылка.Контрагенты"},"limit":50}'
      
      # Events for a specific metadata type
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-01T00:00:00","metadata_type":["Документ.РеализацияТоваровУслуг"],"limit":100}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": [
          {
            "date": "2024-01-15T10:30:00",
            "level": "Error",
            "event": "_$Data$_.Update",
            "comment": "Ошибка при проведении документа",
            "user": "Иванов",
            "metadata": "Документ.РеализацияТоваровУслуг",
            "data_presentation": "Реализация №001 от 15.01.2024",
            "session": 12345,
            "application": "ThinClient",
            "computer": "WORKSTATION01",
            "transaction_status": "RolledBack"
          }
        ],
        "count": 1,
        "last_date": "2024-01-15T10:30:00",
        "next_same_second_offset": 1,
        "has_more": true
      }
      ```
      
      ### Cursor pagination
      
      To get the next page, use `last_date` as `start_date` and `next_same_second_offset` as `same_second_offset`:
      
      ```sh
      # Page 1
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-01T00:00:00","levels":["Error"],"limit":100}'
      # → returns last_date="2024-01-15T10:30:00", next_same_second_offset=3, has_more=true
      
      # Page 2
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-15T10:30:00","same_second_offset":3,"levels":["Error"],"limit":100}'
      # → returns last_date="2024-01-20T15:45:00", next_same_second_offset=1, has_more=false
      ```
      
      **Stop condition**: `has_more=false` means no more records.
      
      ---
      
      ## 9. get_bsl_syntax_help - `POST /api/get_bsl_syntax_help`
      
      Search the built-in BSL language reference. Returns candidates (breadcrumb paths); when exactly one candidate matches, returns Markdown content. Requires SyntaxHelpReader component loaded on the 1C side.
      
      ### Parameters
      
      | Parameter | Type | Required | Default | Constraints | Description |
      |-----------|------|----------|---------|-------------|-------------|
      | `keywords` | string[] | Yes | - | Non-empty array | Search terms, or a single exact candidate path / link target |
      | `match` | string | No | `"all"` | `"all"` / `"any"` | `"all"`: all keywords must appear; `"any"`: any keyword matches |
      | `limit` | integer | No | 100 | 1-300 | Max candidates per page |
      | `offset` | integer | No | 0 | 0-1000000 | Candidates to skip (pagination) |
      | `content_page` | integer | No | 1 | ≥ 1 | Page of content to return (1-based) |
      
      ### Search logic
      
      - Multiple candidates → `content` is `null`. Narrow keywords or use a candidate path directly.
      - Exactly one candidate → `content` contains Markdown reference page.
      - Candidate paths (e.g. `Массив/Методы/Найти`) and link targets from content (`topic:Path`) can be passed as `keywords` for exact lookup - pass the full string including `topic:` prefix as-is.
      
      ### Examples
      
      ```sh
      # Broad search
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_bsl_syntax_help?channel=$CHANNEL" $J \
        -d '{"keywords":["Найти"]}'
      
      # Narrow to methods of a type
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_bsl_syntax_help?channel=$CHANNEL" $J \
        -d '{"keywords":["Найти","Массив"]}'
      
      # Exact lookup by candidate path
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_bsl_syntax_help?channel=$CHANNEL" $J \
        -d '{"keywords":["Массив/Методы/Найти"]}'
      
      # Follow a link from content (topic: prefix passed as-is)
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_bsl_syntax_help?channel=$CHANNEL" $J \
        -d '{"keywords":["topic:Массив/Методы/Найти"]}'
      
      # Find all methods of a type
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_bsl_syntax_help?channel=$CHANNEL" $J \
        -d '{"keywords":["ТаблицаЗначений","Методы"]}'
      
      # Get next content page
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_bsl_syntax_help?channel=$CHANNEL" $J \
        -d '{"keywords":["Запрос"],"content_page":2}'
      ```
      
      ### Response - multiple candidates
      
      ```json
      {
        "success": true,
        "data": {
          "candidates": ["Массив/Методы/Найти", "Строка/Методы/Найти"],
          "total": 2,
          "offset": 0,
          "limit": 100,
          "has_more": false,
          "content": null
        }
      }
      ```
      
      ### Response - one match, single content page
      
      ```json
      {
        "success": true,
        "data": {
          "candidates": ["Массив/Методы/Найти"],
          "total": 1,
          "offset": 0,
          "limit": 100,
          "has_more": false,
          "content": "# Найти\n\n**Синтаксис:** `Найти(<Что>)`\n\n...",
          "content_page": 1,
          "content_total_pages": 1,
          "content_has_more": false
        }
      }
      ```
      
      ### Response - one match, content paginated
      
      ```json
      {
        "success": true,
        "data": {
          "candidates": ["Запрос"],
          "total": 1,
          "has_more": false,
          "content": "# Запрос\n\n...",
          "content_page": 1,
          "content_total_pages": 4,
          "content_has_more": true
        }
      }
      ```
      
      Fields `content_page`, `content_total_pages`, `content_has_more` are present **only when `content` is not null**.
      
      ---
      
      ## 10. submit_for_deanonymization - `POST /api/submit_for_deanonymization`
      
      Submit the final user-facing response for de-anonymization display. **Available only when anonymization is enabled.**
      
      > **Note:** This tool returns `{"received": true}` on success (not `{"success": true, "data": ...}`).
      
      ### Parameters
      
      | Parameter | Type | Required | Default | Constraints | Description |
      |-----------|------|----------|---------|-------------|-------------|
      | `text` | string | Yes | - | String (empty allowed) | The complete final response text containing anonymization tokens |
      
      ### Examples
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/submit_for_deanonymization?channel=$CHANNEL" $J \
        -d '{"text":"Компания [ORG-00001], ИНН [INN-00001], директор: [PER-00001]"}'
      ```
      
      Response (success):
      ```json
      {
        "received": true
      }
      ```
      
      Error (anonymization disabled):
      ```json
      {
        "success": false,
        "error": "Tool is not available: anonymization is disabled"
      }
      ```
      
      Error (missing or invalid parameter):
      ```json
      {
        "success": false,
        "error": "Ошибка валидации параметров: Field 'text': ..."
      }
      ```
      
      Error (wrong method, built-in mode):
      ```json
      {
        "success": false,
        "error": "Method not allowed: submit_for_deanonymization requires POST"
      }
      ```
      
      ---
      
      ## 11. restart_1c_session - `POST /api/restart_1c_session`
      
      Restart the current 1C session. A new session starts automatically with the same database and connection settings; anonymization state is preserved. The old session shuts down once the new one is ready.
      
      > **IMPORTANT**: Do NOT call on your own initiative. Only invoke when explicitly instructed by the user or as a defined step in a pipeline specification.
      
      ### Parameters
      
      None. Send an empty body `{}` or omit the body entirely.
      
      ### Timeout
      
      The operation can take up to 120 seconds (new session startup). Use `curl --max-time 200` (or above the proxy timeout).
      
      ### Example
      
      ```sh
      curl --max-time 200 -sS --noproxy $BASE_HOST "$BASE_URL/api/restart_1c_session?channel=$CHANNEL" $J \
        -d '{}'
      ```
      
      ### Response (success)
      
      ```json
      {
        "success": true,
        "data": "Session restarted successfully. Note: the first MCP request to the new session may fail - retry once if it does."
      }
      ```
      
      ### Error responses
      
      ```json
      {"success": false, "error": "Restart timeout: new session did not start in 120 seconds"}
      {"success": false, "error": "Failed to launch new session: <OS error detail>"}
      {"success": false, "error": "Cannot restart: data processor path is not available (not running from file?)"}
      {"success": false, "error": "Cannot restart: data processor file not found: /path/to/file.epf"}
      {"success": false, "error": "Windows authentication is not available on the current OS"}
      ```
      
      HTTP 500 (concurrent call):
      ```json
      {"success": false, "error": "Restart or close already in progress"}
      ```
      
      ---
      
      ## 12. close_1c_session - `POST /api/close_1c_session`
      
      Close the current 1C session and receive a launcher script command to start a new one. Use when exclusive database access is needed (e.g., configuration update).
      
      On success the session closes immediately, and `data` contains the shell command to launch a fresh session. Run it synchronously: exit 0 = session ready; non-zero = startup failed.
      
      > **IMPORTANT**: Do NOT call on your own initiative. Only invoke when explicitly instructed.
      
      ### Parameters
      
      None. Send an empty body `{}` or omit the body entirely.
      
      ### Timeout
      
      Use `curl --max-time 200`. The endpoint responds as soon as the launcher script is prepared and the old session begins shutting down (fast).
      
      ### Example
      
      ```sh
      curl --max-time 200 -sS --noproxy $BASE_HOST "$BASE_URL/api/close_1c_session?channel=$CHANNEL" $J \
        -d '{}'
      ```
      
      ### Response (success)
      
      `data` is a multi-line **string** containing the command and usage notes:
      
      ```json
      {
        "success": true,
        "data": "Session closed. To start a new session, run:\npowershell -ExecutionPolicy Bypass -File 'C:\\path\\to\\launcher.ps1'\nRun synchronously. Exit 0 = session ready. Non-zero = startup failed. On Windows, run this command in PowerShell (not cmd.exe). On timeout: startup state is unknown - check whether 1C was already started before launching another. On non-timeout exit 1: the launcher either did not start 1C, or the failed new instance was closed - safe to retry."
      }
      ```
      
      ### Launcher script behavior
      
      | Exit code | Meaning |
      |-----------|---------|
      | 0 | New session started successfully |
      | 1 (non-timeout) | Pre-launch error or failed startup - safe to retry after fixing the cause |
      | 1 (timeout after 120 s) | State unknown - check whether a 1C process was already started before launching another |
      
      - **Windows**: run the command in PowerShell (not cmd.exe)
      - **Linux with password auth**: `python3` must be available on PATH
      
      ### Error responses
      
      ```json
      {"success": false, "error": "Cannot close: data processor path not available"}
      {"success": false, "error": "Cannot close: data processor file not found: /path/to/file.epf"}
      {"success": false, "error": "Windows authentication is not available on the current OS"}
      {"success": false, "error": "close_1c_session error: <detail>"}
      ```
      
      HTTP 500 (concurrent call):
      ```json
      {"success": false, "error": "Restart or close already in progress"}
      ```
      
      
      
    • workflow-examples.md 12.8 KB
      # Workflow Examples
      
      Detailed multi-step workflows with full curl commands and expected responses at each step.
      
      > **Convention**: all examples use the variables from Quick Start:
      > ```sh
      > BASE_HOST=localhost
      > BASE_URL="http://$BASE_HOST:6003"
      > CHANNEL="default"
      > J='-H Content-Type:application/json'
      > ```
      
      ---
      
      ## Workflow 1: Explore an Unfamiliar Database
      
      **Trigger**: user asks "what's in this 1C database", "show me the structure", "what tables are available"
      
      ### Step 1: Health check
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/health"
      ```
      
      Response:
      ```json
      {"status": "ok", "channels_count": 1}
      ```
      
      ### Step 2: Get root summary
      
      ```sh
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL"
      ```
      
      Response:
      ```json
      {
        "success": true,
        "configuration": {
          "platform_version": "8.3.25.1000",
          "infobase_name": "TradeDB",
          "metadata": {"Имя": "УправлениеТорговлей", "Синоним": "Управление торговлей"}
        },
        "data": [
          {"Тип": "Справочник", "Количество": 265},
          {"Тип": "Документ", "Количество": 27},
          {"Тип": "РегистрСведений", "Количество": 150},
          {"Тип": "РегистрНакопления", "Количество": 42}
        ]
      }
      ```
      
      **Decision**: The database is "Управление торговлей" with 27 documents and 265 catalogs. Drill into documents.
      
      ### Step 3: List documents
      
      ```sh
      curl -sS -G --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" \
        --data-urlencode "meta_type=Документ" \
        --data-urlencode "limit=50"
      ```
      
      Response:
      ```json
      {
        "success": true,
        "returned": 27,
        "has_more": false,
        "data": [
          {"ПолноеИмя": "Документ.ЗаказПокупателя", "Синоним": "Заказ покупателя"},
          {"ПолноеИмя": "Документ.РеализацияТоваровУслуг", "Синоним": "Реализация товаров и услуг"},
          {"ПолноеИмя": "Документ.ПоступлениеТоваровУслуг", "Синоним": "Поступление товаров и услуг"}
        ]
      }
      ```
      
      ### Step 4: Get detailed structure of an interesting object
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_metadata?channel=$CHANNEL" $J \
        -d '{"filter":"Документ.РеализацияТоваровУслуг","sections":["properties"]}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": {
          "Тип": "Документ",
          "Имя": "РеализацияТоваровУслуг",
          "ПолноеИмя": "Документ.РеализацияТоваровУслуг",
          "Реквизиты": [
            {"Имя": "Контрагент", "Тип": "СправочникСсылка.Контрагенты"},
            {"Имя": "Склад", "Тип": "СправочникСсылка.Склады"},
            {"Имя": "Валюта", "Тип": "СправочникСсылка.Валюты"}
          ],
          "ТабличныеЧасти": [
            {
              "Имя": "Товары",
              "Реквизиты": [
                {"Имя": "Номенклатура", "Тип": "СправочникСсылка.Номенклатура"},
                {"Имя": "Количество", "Тип": "Число(15,3)"},
                {"Имя": "Цена", "Тип": "Число(15,2)"},
                {"Имя": "Сумма", "Тип": "Число(15,2)"}
              ]
            }
          ]
        }
      }
      ```
      
      ### Step 5: Sample real data
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Ссылка, Дата, Номер, Контрагент ИЗ Документ.РеализацияТоваровУслуг УПОРЯДОЧИТЬ ПО Дата УБЫВ","limit":5}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": [
          {
            "Ссылка": {"_objectRef": true, "ТипОбъекта": "ДокументСсылка.РеализацияТоваровУслуг", "Представление": "Реализация №015 от 15.01.2024", "УникальныйИдентификатор": "..."},
            "Дата": "2024-01-15T10:30:00",
            "Номер": "015",
            "Контрагент": {"_objectRef": true, "ТипОбъекта": "СправочникСсылка.Контрагенты", "Представление": "ООО Рога и Копыта", "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678"}
          }
        ],
        "count": 1
      }
      ```
      
      **Result**: Agent now understands the database structure and can answer questions about available data.
      
      ---
      
      ## Workflow 2: Investigate Object Dependencies
      
      **Trigger**: user asks "where is this customer used", "can I delete this item", "show all references to this object"
      
      ### Step 1: Find the object
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО &Маска","params":{"Маска":"%Рога%"},"limit":1}'
      ```
      
      Response - extract `object_description` from the `Ссылка` field:
      ```json
      {
        "success": true,
        "data": [
          {
            "Ссылка": {
              "_objectRef": true,
              "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
              "ТипОбъекта": "СправочникСсылка.Контрагенты",
              "Представление": "ООО Рога и Копыта"
            }
          }
        ]
      }
      ```
      
      ### Step 2: Find all references
      
      Use the `object_description` from Step 1 as `target_object_description`:
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/find_references_to_object?channel=$CHANNEL" $J \
        -d '{
          "target_object_description": {
            "_objectRef": true,
            "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
            "ТипОбъекта": "СправочникСсылка.Контрагенты"
          },
          "search_scope": ["documents", "catalogs", "information_registers", "accumulation_registers"],
          "limit_hits": 100
        }'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": {
          "hits": [
            {
              "found_in_meta": "Документ.РеализацияТоваровУслуг",
              "found_in_object": {"_objectRef": true, "ТипОбъекта": "ДокументСсылка.РеализацияТоваровУслуг", "Представление": "Реализация №015 от 15.01.2024", "УникальныйИдентификатор": "..."},
              "path": "Контрагент",
              "match_kind": "attribute",
              "note": "Реализация №015 от 15.01.2024"
            },
            {
              "found_in_meta": "Документ.ЗаказПокупателя",
              "found_in_object": {"_objectRef": true, "ТипОбъекта": "ДокументСсылка.ЗаказПокупателя", "Представление": "Заказ №003 от 10.01.2024", "УникальныйИдентификатор": "..."},
              "path": "Контрагент",
              "match_kind": "attribute",
              "note": "Заказ №003 от 10.01.2024"
            }
          ],
          "total_hits": 2,
          "candidates_checked": 15,
          "timeout_exceeded": false,
          "skipped_names": []
        }
      }
      ```
      
      ### Step 3: Check access rights
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_access_rights?channel=$CHANNEL" $J \
        -d '{"metadata_object":"Справочник.Контрагенты","user_name":"Иванов"}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": {
          "metadata_object": "Справочник.Контрагенты",
          "user": {
            "name": "Иванов",
            "roles": ["Менеджер"],
            "effective_rights": {"Чтение": true, "Изменение": true, "Добавление": true, "Удаление": false}
          }
        }
      }
      ```
      
      ### Step 4: Check recent changes in event log
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{
          "object_description": {
            "_objectRef": true,
            "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
            "ТипОбъекта": "СправочникСсылка.Контрагенты"
          },
          "limit": 20
        }'
      ```
      
      **Result**: Agent can now tell the user: "This customer is referenced by 2 documents (1 sales order, 1 shipment). User Иванов can read/modify but not delete it. Last modified on 2024-01-10."
      
      ---
      
      ## Workflow 3: Diagnose Event Log Errors
      
      **Trigger**: user asks "what errors happened", "investigate recent problems", "show error log"
      
      ### Step 1: Fetch recent errors
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-01T00:00:00","end_date":"2024-01-31T23:59:59","levels":["Error"],"limit":100}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": [
          {
            "date": "2024-01-15T10:30:00",
            "level": "Error",
            "event": "_$Data$_.Update",
            "comment": "Ошибка при проведении документа: Недостаточно товара на складе",
            "user": "Иванов",
            "metadata": "Документ.РеализацияТоваровУслуг",
            "data_presentation": "Реализация №015 от 15.01.2024",
            "session": 12345,
            "application": "ThinClient"
          },
          {
            "date": "2024-01-14T16:20:00",
            "level": "Error",
            "event": "_$Data$_.Update",
            "comment": "Ошибка блокировки данных",
            "user": "Петров",
            "metadata": "Документ.ПоступлениеТоваровУслуг",
            "data_presentation": "Поступление №008 от 14.01.2024"
          }
        ],
        "count": 2,
        "last_date": "2024-01-15T10:30:00",
        "next_same_second_offset": 1,
        "has_more": false
      }
      ```
      
      ### Step 2: Paginate if needed
      
      If `has_more=true`, fetch next page using cursor:
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_event_log?channel=$CHANNEL" $J \
        -d '{"start_date":"2024-01-15T10:30:00","same_second_offset":1,"end_date":"2024-01-31T23:59:59","levels":["Error"],"limit":100}'
      ```
      
      ### Step 3: Examine objects from errors
      
      Use the data_presentation link to get the problematic document:
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Ссылка, Дата, Номер, Контрагент, Склад ИЗ Документ.РеализацияТоваровУслуг ГДЕ Номер = &Номер","params":{"Номер":"015"},"limit":1}'
      ```
      
      ### Step 4: Investigate context
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Номенклатура, Количество ИЗ Документ.РеализацияТоваровУслуг.Товары ГДЕ Ссылка.Номер = &Номер","params":{"Номер":"015"},"limit":100}'
      ```
      
      **Result**: Agent identifies error patterns, affected documents, and provides diagnostic summary to the user.
      
      ---
      
      ## Workflow 4: Generate Clickable Links for Users
      
      **Trigger**: user asks "give me links to these documents", "show results with navigation links"
      
      ### Step 1: Query documents
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/execute_query?channel=$CHANNEL" $J \
        -d '{"query":"ВЫБРАТЬ Ссылка, Дата, Номер, Контрагент ИЗ Документ.РеализацияТоваровУслуг ГДЕ Дата >= &Дата","params":{"Дата":"2024-01-01T00:00:00"},"limit":10}'
      ```
      
      Response (contains `object_description` in each row's `Ссылка` field).
      
      ### Step 2: Generate navigation links for each result
      
      For each row, pass the `Ссылка` object_description to get_link_of_object:
      
      ```sh
      curl -sS --noproxy $BASE_HOST "$BASE_URL/api/get_link_of_object?channel=$CHANNEL" $J \
        -d '{"object_description":{"_objectRef":true,"УникальныйИдентификатор":"a1b2c3d4-5678-9012-3456-789012345678","ТипОбъекта":"ДокументСсылка.РеализацияТоваровУслуг"}}'
      ```
      
      Response:
      ```json
      {
        "success": true,
        "data": "e1cib/data/Документ.РеализацияТоваровУслуг?ref=a1b2c3d456789012345678901234"
      }
      ```
      
      ### Step 3: Present to user
      
      Combine query data with navigation links to present a formatted list:
      
      ```
      1. Реализация №015 от 15.01.2024 - ООО Рога и Копыта
         Link: e1cib/data/Документ.РеализацияТоваровУслуг?ref=a1b2c3d456789012345678901234
      
      2. Реализация №016 от 16.01.2024 - ООО Звезда
         Link: e1cib/data/Документ.РеализацияТоваровУслуг?ref=b2c3d4e567890123456789012345
      ```
      
      **Result**: User gets a structured list with links they can paste into 1C navigation bar to open documents directly.
      
  • scripts
    • health-probe.ps1 1.9 KB · in bundle
    • start-1c.ps1 13.6 KB · in bundle
    • stop-1c.ps1 4 KB · in bundle
  • SKILL.md 29.4 KB
    ---
    name: 1c-mcp-toolkit
    description: >
      Прямой HTTP API к живой запущенной базе 1С:Предприятие через обработку
      MCP_Toolkit.epf (REST на http://localhost:6003/api/*). 12 эндпоинтов: запросы
      (execute_query), BSL-код (execute_code), метаданные (get_metadata), ссылки и
      навигация (get_object_by_link, get_link_of_object), поиск ссылок на объект
      (find_references_to_object), права (get_access_rights), журнал регистрации
      (get_event_log), справка платформы (get_bsl_syntax_help), управление сессией
      (restart_1c_session, close_1c_session). EPF и скрипты запуска включены в скилл.
      Используй когда нужно проверить реальные данные в живой БД, выполнить
      exploratory-запрос, прямо вызвать экспортную функцию модуля выгрузки, прочитать
      журнал регистрации, диагностировать данные до или после доработки. Триггеры на
      русском: "выполни запрос в живой базе", "проверить данные в БД", "сколько
      записей в", "вызвать функцию модуля 1С", "что в журнале регистрации",
      "выполни BSL-код в живой 1С", "запусти 1С с MCP-toolkit". Триггеры на
      английском: "query live 1C database", "execute BSL in 1C", "check 1C data",
      "explore 1C metadata at runtime".
    ---
    
    # 1C MCP Toolkit - прямой HTTP API к живой базе 1С
    
    REST API на `http://localhost:6003/api/*` через обработку `MCP_Toolkit.epf`,
    запущенную в тонком (или толстом) клиенте 1С. Встроенный HTTP-сервер реализован
    нативной компонентой `MCPHttpTransport`. Без модификации конфигурации, без COM,
    без публикации через web-сервер.
    
    Обработка `MCP_Toolkit.epf` - разработка ROCTUP, репозиторий: https://github.com/ROCTUP/1c-mcp-toolkit (там же исходники нативной компоненты и документация).
    
    Используется когда LLM-агент работает с живой базой (тесты, диагностика, прямой
    вызов экспортных функций), и при этом классические EDT-инструменты не подходят
    (нет dev-проекта, нужны данные runtime, нужен реальный пользовательский
    контекст).
    
    ## Протокол: агент делает сам, порты не переспрашивает
    
    Правила против холостых ходов "запусти / проверь / какой порт":
    
    1. **Карта портов проекта.** Сначала взять карту "среда/ИБ -> порт" из CLAUDE.md
       ТЕКУЩЕГО проекта (секция "MCP Toolkit") или памяти проекта. Есть карта -
       работать с нужным портом, probe пропустить. Нет карты - после probe предложить
       пользователю добавить ее в CLAUDE.md.
    2. **Health-probe вместо вопросов.** Не спрашивать "toolkit запущен? какой порт?":
       `pwsh scripts/health-probe.ps1` (обход типовых 6003/6004/6005/6010/6013/6023/6033/7003)
       или bash-цикл:
    
       ```sh
       for p in 6003 6004 6005 6010 6013 6023 6033 7003; do
         curl -sS -m 2 "http://localhost:$p/health" >/dev/null 2>&1 && echo "порт $p жив"
       done
       ```
    
    3. **Ничего не живо - запустить самому.** `scripts/start-1c.ps1 -AutoStart`,
       если параметры базы (платформа, путь, пользователь) известны из карты/памяти.
       Спрашивать пользователя только при неизвестных параметрах.
    4. **Полный цикл - самостоятельно.** Обновить ИБ и проверить данные = один заход без
       ручного handoff: `stop-1c.ps1` (или execute_code ЗавершитьРаботуСистемы) ->
       `update_database` (EDT MCP) -> `start-1c.ps1 -AutoStart` -> health ->
       запросы. Пользователя дергать только если неизвестны платформа/база/учетка ИЛИ он
       явно просил паузу (демо, живой показ).
    5. **Ошибка "функция не определена" / connection refused** - чаще всего toolkit просто
       не запущен: сначала health-probe и перезапуск, потом разбор кода.
    6. **Не предлагать рестарт rphost/rmngr** при обычном обновлении конфигурации - это
       не нужно (зона администраторов).
    
    ## Быстрый старт
    
    ### 1. Запуск 1С с авто-открытием обработки
    
    EPF лежит прямо в скилле:
    - [bin/MCP_Toolkit.epf](bin/MCP_Toolkit.epf) - x64 (основная)
    - [bin/MCP_Toolkit_x86.epf](bin/MCP_Toolkit_x86.epf) - x86
    
    > **Запускать `.ps1`-скрипты ниже строго через PowerShell 7 (`pwsh`), НЕ через `powershell.exe` (5.1).**
    > PS 5.1 спотыкается на кириллице в JSON-телах toolkit (`stop-1c.ps1` со `ЗавершитьРаботуСистемы`
    > и т.п. - "не смог распарсить stop-скрипт"). Инструмент **PowerShell** агента уже работает на
    > pwsh 7 - используй его. Из **Bash tool** вызывай pwsh явно (не `powershell.exe`):
    > ```sh
    > '/c/Program Files/PowerShell/7/pwsh.exe' -NoProfile -ExecutionPolicy Bypass -Command '& "$HOME\.claude\skills\1c-mcp-toolkit\scripts\start-1c.ps1" -Platform "8.3.27.2074" -Database "..." -User "..." -Password "..."'
    > ```
    
    Минимальная PowerShell-команда (в pwsh 7):
    
    ```powershell
    & "C:\Program Files\1cv8\<версия>\bin\1cv8c.exe" `
        /F"<путь к файловой базе>" `
        /N"<имя пользователя>" `
        /P"<пароль>" `
        /Execute"$HOME\.claude\skills\1c-mcp-toolkit\bin\MCP_Toolkit.epf"
    ```
    
    Готовый параметризованный скрипт: [scripts/start-1c.ps1](scripts/start-1c.ps1).
    
    Пример:
    
    ```powershell
    & "$HOME\.claude\skills\1c-mcp-toolkit\scripts\start-1c.ps1" `
        -Platform "8.3.27.2074" `
        -Database "C:\Bases\MyDB" `
        -User "Admin" `
        -Password "<пароль>"
    ```
    
    Без `/N` и `/P` 1С зависает на форме авторизации, HTTP-сервер не поднимается.
    
    После запуска в обработке на вкладке "Подключение" выбрать "Встроенный сервер",
    порт 6003, формат TOON, нажать "Запустить сервер" (если не настроен автостарт).
    
    ### 2. Проверка готовности
    
    ```sh
    curl http://localhost:6003/health
    ```
    
    `200 OK` - сервер на 6003 работает, можно делать запросы.
    
    ### 3. Закрытие 1С (например, для deploy через EDT)
    
    ```sh
    curl -sS -X POST "http://localhost:6003/api/execute_code" \
      -H "Content-Type: application/json" \
      -d '{"code":"ЗавершитьРаботуСистемы(Ложь, Ложь); Результат=\"OK\";","execution_context":"client"}'
    ```
    
    Готовый скрипт: [scripts/stop-1c.ps1](scripts/stop-1c.ps1).
    
    `execution_context: "client"` обязателен - `ЗавершитьРаботуСистемы` доступна
    только на клиенте.
    
    ## Когда использовать MCP Toolkit
    
    - Проверка реальных данных в живой БД (полнота тестовых данных, корректность
      миграции, количество записей)
    - Прямой вызов экспортных функций модулей выгрузки/обмена без UI
    - Поиск конкретных проводок/документов для воспроизведения багов
    - Чтение метаданных из живой БД (когда нет открытого EDT-проекта)
    - Чтение журнала регистрации с фильтрацией
    - Поиск ссылок на объект ("где используется этот контрагент")
    - Диагностика прав доступа
    
    ## Когда НЕ использовать (есть альтернатива получше)
    
    | Задача | Лучше использовать |
    |--------|--------------------|
    | Чтение BSL-кода, навигация по модулям | `mcp__ai-edt__read_method_source`, `get_module_structure` |
    | Валидация запроса до запуска | `mcp__ai-edt__validate_query` |
    | Метаданные в режиме разработки (XML) | `mcp__ai-edt__get_metadata_objects/get_metadata_details` |
    | Семантический поиск по коду | `mcp__ai-edt__search_in_code`, `find_references` |
    | Запрос без живой БД (только EDT) | `mcp__ai-edt__execute_query` (если доступен) |
    | Проверка качества BSL | `mcp__1c-naparnik__ask_1c_ai` |
    
    MCP Toolkit заточен под **живую запущенную базу**, EDT - под dev-режим с
    исходниками. Не дублируй вызовы.
    
    ## Базовые запросы
    
    ### Health
    ```sh
    curl http://localhost:6003/health
    ```
    
    ### execute_query (минимум)
    ```sh
    curl -sS -X POST "http://localhost:6003/api/execute_query" \
      -H "Content-Type: application/json" \
      -d '{"query":"ВЫБРАТЬ ПЕРВЫЕ 5 Наименование ИЗ Справочник.Контрагенты"}'
    ```
    
    ### execute_code (минимум)
    ```sh
    curl -sS -X POST "http://localhost:6003/api/execute_code" \
      -H "Content-Type: application/json" \
      -d '{"code":"Результат = ТекущаяДата();"}'
    ```
    
    ### get_metadata (root summary)
    ```sh
    curl http://localhost:6003/api/get_metadata
    ```
    
    ## 12 эндпоинтов
    
    | # | Эндпоинт | Метод | Назначение |
    |---|----------|-------|------------|
    | 1 | get_metadata | GET/POST | Метаданные: типы, объекты, реквизиты, поиск по атрибуту |
    | 2 | execute_query | POST | Выполнить запрос 1С, вернуть набор записей |
    | 3 | execute_code | POST | Выполнить BSL-код, вернуть значение `Результат` |
    | 4 | get_object_by_link | POST | Получить объект по navigation link |
    | 5 | get_link_of_object | POST | Сформировать navigation link из object_description |
    | 6 | find_references_to_object | POST | Найти все ссылки на объект в БД |
    | 7 | get_access_rights | POST | Права на объект для роли/пользователя |
    | 8 | get_event_log | POST | Журнал регистрации с фильтрацией и пагинацией |
    | 9 | get_bsl_syntax_help | POST | Встроенная справка платформы 1С |
    | 10 | submit_for_deanonymization | POST | Деанонимизация ответа (если анонимизация включена) |
    | 11 | restart_1c_session | POST | Перезапуск сессии (подхват изменений конфигурации) |
    | 12 | close_1c_session | POST | Закрытие сессии (для эксклюзивного доступа к БД) |
    
    **Полная справка** по всем параметрам, ответам, граничным случаям, всем
    вариантам curl - [references/tools-full-reference.md](references/tools-full-reference.md).
    
    ## Формат ответов: TOON по умолчанию
    
    Внешняя обертка всегда JSON:
    ```json
    {"success": true, "data": <result>}
    {"success": false, "error": "описание"}
    ```
    
    Поле `data` по умолчанию закодировано в **TOON** (компактный текстовый формат,
    экономит 30-60% токенов по сравнению с JSON). Переключается через env
    `RESPONSE_FORMAT=json` на сервере или в форме обработки.
    
    TOON-формат:
    - `[N]` - массив длины N
    - `[N]{"Колонка1","Колонка2"}: ...` - таблица с N строк и колонками
    - Скаляры - как `"ключ": значение`
    
    ## Передача ссылок: object_description
    
    В ответах `execute_query` поля ссылочного типа возвращаются как:
    ```json
    {
      "_objectRef": true,
      "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
      "ТипОбъекта": "СправочникСсылка.Контрагенты",
      "Представление": "ООО Рога и Копыта"
    }
    ```
    
    Эта структура - input для `get_link_of_object`, `find_references_to_object`,
    `get_event_log` (фильтр по объекту), а также передается в `params` для
    `execute_query`:
    
    ```json
    {
      "query": "ВЫБРАТЬ ... ИЗ Документ.Реализация ГДЕ Контрагент = &К",
      "params": {
        "К": {
          "_objectRef": true,
          "УникальныйИдентификатор": "ba7e5a3d-...",
          "ТипОбъекта": "СправочникСсылка.Контрагенты"
        }
      }
    }
    ```
    
    Полная спецификация - [references/object-description-format.md](references/object-description-format.md).
    
    ## Правила экранирования curl
    
    При сборке curl-команд с JSON-payload, содержащим BSL-код и запросы 1С, участвует
    несколько уровней кавычек. Правила ниже - для bash/sh (Bash tool). В PowerShell
    экранирование иное: одинарные кавычки тоже литерал, но `!` не раскрывается, а `$` в
    двойных кавычках подставляется.
    
    ### Правило 1: одинарные кавычки для payload `-d` (рекомендуется)
    
    Одинарные кавычки запрещают bash интерпретировать `$`, `!`, `&`, обратные кавычки и
    прочие спецсимволы внутри payload. Двойные кавычки тоже работают, но требуют
    аккуратности.
    
    ```sh
    # Рекомендуется - одинарные кавычки, bash ничего внутри не трогает:
    curl ... -d '{"query":"ВЫБРАТЬ 1"}'
    
    # Тоже работает, но bash интерпретирует спецсимволы - осторожно:
    curl ... -d "{\"query\":\"ВЫБРАТЬ 1\"}"
    ```
    
    ### Правило 2: строковые значения в запросах - всегда через параметры
    
    Вместо встраивания строковых литералов прямо в текст запроса (что требует сложного
    экранирования) - всегда передавать их как параметры. Это полностью устраняет
    вложенные кавычки.
    
    ```sh
    # ХОРОШО - значение передано параметром, без вложенных кавычек:
    curl ... -d '{"query":"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Статус = &Статус", "params":{"Статус":"Активный"}}'
    
    # ХОРОШО - то же для execute_code:
    curl ... -d '{"code":"Запрос = Новый Запрос;\nЗапрос.Текст = \"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Статус = &Статус\";\nЗапрос.УстановитьПараметр(\"Статус\", \"Активный\");\nРезультат = Запрос.Выполнить().Выгрузить();"}'
    ```
    
    ### Правило 3: избегать `!` в строковых значениях
    
    Bash интерпретирует `!` как history expansion даже внутри некоторых контекстов
    кавычек. Никогда не использовать `!` в строковых литералах - заменять безопасными
    альтернативами.
    
    ```sh
    # ПЛОХО - ! запускает history expansion:
    -d '{"code":"...ТОГДА \"!!! ВЫСОКАЯ\"..."}'
    
    # ХОРОШО - без восклицательных знаков:
    -d '{"code":"...ТОГДА \"ВЫСОКАЯ\"..."}'
    ```
    
    ### Правило 4: строковые литералы внутри запроса (edge-case)
    
    Если литерал в тексте запроса без параметра неизбежен, экранирование зависит от
    контекста:
    
    execute_query - один уровень JSON-экранирования (`\"`):
    ```sh
    curl ... -d '{"query":"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО \"%Рога%\""}'
    ```
    
    execute_code - экранирование строки 1С `""` плюс JSON-экранирование (`\"\"`):
    ```sh
    curl ... -d '{"code":"Запрос.Текст = \"ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО \"\"%Рога%\"\"\";"}'
    ```
    
    По возможности всегда предпочитать Правило 2 (параметры).
    
    ### Краткая справка
    
    | Символ | Проблема | Решение |
    |--------|----------|---------|
    | `"` внутри строки запроса | Вложенное экранирование | Передать значение параметром (Правило 2) |
    | `!` | Bash history expansion | Избегать полностью |
    | `&` | Bash интерпретирует в двойных кавычках | Безопасно внутри payload в одинарных кавычках |
    | `\n` | Перенос строки в JSON-строке | Для разделения операторов 1С, НЕ внутри текста запроса |
    
    ## Типичные ошибки и обходы
    
    ### "Не задано значение параметра"
    
    В `execute_query` параметр запроса передан не как `params`. Использовать ключ
    `params`, не `parameters`.
    
    ### Регистр бухгалтерии Хозрасчетный: "Поле не найдено X.Счет" / "X.Субконто1"
    
    Регистр двусторонний (`Корреспонденция=true`). В физической таблице есть только
    `СчетДт`, `СчетКт`. Поля `Счет`, `Субконто1..3` доступны **только в виртуальных
    таблицах**: `ОборотыДтКт`, `ДвиженияССубконто`, `Обороты`, `Остатки`.
    
    ### "Поле не найдено Организация" в условии ОборотыДтКт
    
    В виртуальных таблицах Хозрасчетного условие на `Организация` через 6-й параметр
    не всегда работает. Использовать `ДвиженияССубконто` (условие в 3-м параметре, на
    физические поля), либо отбор через `КорСубконтоИзмерения`.
    
    ### "Неверные параметры РегистрБухгалтерии.Хозрасчетный.Обороты"
    
    Параметры виртуальных таблиц регистра бухгалтерии (важна последовательность):
    - `.Остатки()`: 3 параметра (Период, Субконто, Условие)
    - `.Обороты()`: 6 параметров (НачП, КонП, Периодичность, Субконто, Условие, КорСубконто)
    - `.ОстаткиИОбороты()`: 6 параметров
    - `.ОборотыДтКт()`: 6 параметров (НачП, КонП, Периодичность, СубконтоДт, СубконтоКт, Условие)
    - `.ДвиженияССубконто()`: 5 параметров (НачП, КонП, Условие, Порядок, Первые)
    
    ### execute_code: "Процедура или функция с именем не определена (ДатаВремя)"
    
    В BSL `ДатаВремя` - это **токен языка запросов**, не функция платформы. В коде
    использовать `Дата(2026, 1, 1)`.
    
    ### execute_code: запрос внутри Запрос.Текст должен быть однострочным
    
    Внутри литерала `Запрос.Текст = "..."` текст запроса должен быть **на одной
    строке**. Многострочное форматирование через `\n` внутри литерала ломает парсер.
    
    Правильно:
    ```bsl
    Запрос.Текст = "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Контрагенты ГДЕ НЕ ПометкаУдаления";
    ```
    
    ### execute_code: запрещенные ключевые слова
    
    По умолчанию блокируются: `Удалить`, `Записать`, `УстановитьПривилегированныйРежим`,
    `COMОбъект`, `УдалитьФайлы` и др. Список настраивается в обработке. Для тестов на
    запись - либо снять защиту в форме, либо использовать API объектов в обход
    ключевого слова (например, `Объект = Документ.СоздатьДокумент(); Объект.Записать()`
    не пройдет из-за `Записать`).
    
    ## Типичные паттерны
    
    ### Открытие формы в сеансе 1С (execution_context=client)
    
    Отдельного эндпоинта `open_form` НЕТ (проверено по ROCTUP, 27.07.2026: 12 эндпоинтов без
    него). Форму открывает `ОткрытьФорму(...)` в КЛИЕНТСКОМ контексте - проверено рабочим:
    
    ```sh
    curl -sS -X POST "http://localhost:6003/api/execute_code"   -d '{"code":"ОткрытьФорму(\"Документ.Х.ФормаСписка\"); Результат=\"OK\";","execution_context":"client"}'
    ```
    
    Форма откроется в окне ЗАПУЩЕННОГО сеанса 1С (не headless - пользователь видит ее на
    экране). Список: `.ФормаСписка` (или без указания формы - автоформа списка); объект:
    `ОткрытьФорму("Документ.Х.ФормаОбъекта", Новый Структура("Ключ", СсылкаНаОбъект))`.
    Для АГЕНТА картинку формы дает EDT MCP `get_form_screenshot` (сам toolkit возвращает
    только текст/данные, не изображение).
    
    ### Прямой вызов экспортной функции модуля выгрузки
    
    ```sh
    curl -sS -X POST "http://localhost:6003/api/execute_code" \
      -H "Content-Type: application/json" \
      -d '{"code":"Орг = Справочники.Организации.НайтиПоНаименованию(\"МояОрганизация\"); Дата1 = Дата(2026,1,1); Дата2 = Дата(2026,3,31,23,59,59); Рез = МойМодульВыгрузки.СформироватьДанные(Дата1, Дата2, Орг); Результат = Новый Структура(\"КоличествоСтрок,Ошибки\", Рез.Данные.Количество(), Рез.Ошибки);"}'
    ```
    
    ### Сводка по проводкам двустороннего Хозрасчетного через UNION
    
    ```sql
    ВЫБРАТЬ Сторона.КодСчета, СУММА(Сторона.СуммаДт), СУММА(Сторона.СуммаКт)
    ИЗ (
        ВЫБРАТЬ ПСД.Код КАК КодСчета, Х.Сумма КАК СуммаДт, 0 КАК СуммаКт
        ИЗ РегистрБухгалтерии.Хозрасчетный КАК Х
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланСчетов.Хозрасчетный КАК ПСД ПО Х.СчетДт = ПСД.Ссылка
        ГДЕ Х.Период МЕЖДУ &Д1 И &Д2
        ОБЪЕДИНИТЬ ВСЕ
        ВЫБРАТЬ ПСК.Код, 0, Х.Сумма
        ИЗ РегистрБухгалтерии.Хозрасчетный КАК Х
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланСчетов.Хозрасчетный КАК ПСК ПО Х.СчетКт = ПСК.Ссылка
        ГДЕ Х.Период МЕЖДУ &Д1 И &Д2
    ) КАК Сторона
    СГРУППИРОВАТЬ ПО Сторона.КодСчета
    ```
    
    ### Передача параметра-ссылки в запрос
    
    ```sh
    curl -sS -X POST "http://localhost:6003/api/execute_query" \
      -H "Content-Type: application/json" \
      -d '{
        "query": "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Кол ИЗ Документ.РеализацияТоваровУслуг ГДЕ Организация = &Орг",
        "params": {
          "Орг": {
            "_objectRef": true,
            "УникальныйИдентификатор": "ba7e5a3d-1234-5678-9abc-def012345678",
            "ТипОбъекта": "СправочникСсылка.Организации"
          }
        }
      }'
    ```
    
    ## Готовые workflow
    
    Полные многошаговые сценарии с командами и ответами - в
    [references/workflow-examples.md](references/workflow-examples.md):
    
    1. **Explore an unfamiliar database** - разведка БД (health → metadata summary →
       list → detail → sample query)
    2. **Investigate object dependencies** - проверка зависимостей объекта
       (execute_query → find_references → access_rights → event_log)
    3. **Diagnose event log errors** - диагностика ошибок из журнала
       (get_event_log с пагинацией → execute_query вокруг ошибочных объектов)
    
    ## Цикл deploy через MCP Toolkit + EDT
    
    Типичный цикл "правка кода - проверка в живой базе":
    
    1. Внести изменения в код в EDT, запустить `mcp__ai-edt__validate_query` для
       запросов
    2. Закрыть 1С через MCP Toolkit:
       ```sh
       curl -sS -X POST "http://localhost:6003/api/execute_code" \
         -H "Content-Type: application/json" \
         -d '{"code":"ЗавершитьРаботуСистемы(Ложь, Ложь);","execution_context":"client"}'
       ```
    3. Обновить конфигурацию: `mcp__ai-edt__update_database`
    4. Запустить 1С с MCP Toolkit: `scripts/start-1c.ps1 ...`
    5. Дождаться поднятия: polling `curl http://localhost:6003/health` до 200
    6. Прогнать тестовые запросы через `execute_query` / `execute_code`
    
    ## Совместимость
    
    - Платформа 1С: 8.2.13+ и 8.3.25+ (включая 8.3.27)
    - Архитектура: x64 (основной EPF) и x86 (отдельный EPF)
    - Запуск только в **тонком** (`1cv8c.exe`) или **толстом** (`1cv8.exe`) клиенте.
      Через web-клиент нативная компонента не работает.
    
    ## Channel routing (multi-database)
    
    Если запущено несколько обработок MCP_Toolkit с разными channel - передавать
    `?channel=<name>` в URL:
    
    ```sh
    curl -sS "http://localhost:6003/api/execute_query?channel=dev" \
      -H "Content-Type: application/json" \
      -d '{"query":"ВЫБРАТЬ 1"}'
    ```
    
    Regex для имени: `^[a-zA-Z0-9_-]{1,64}$`. По умолчанию `default`.
    
    ## Связанные скиллы
    
    - `composing-1c-queries` - синтаксис языка запросов 1С (составление `query` для
      execute_query, виртуальные таблицы регистров, временные таблицы, JOIN-ы)
    
    ## Ссылки на references
    
    - [references/tools-full-reference.md](references/tools-full-reference.md) -
      полная справка по всем 12 эндпоинтам: параметры, ответы, граничные случаи
    - [references/object-description-format.md](references/object-description-format.md) -
      спецификация формата `object_description`
    - [references/workflow-examples.md](references/workflow-examples.md) -
      готовые многошаговые сценарии с полным curl-выводом
    
    ## Источник
    
    Репозиторий: https://github.com/ROCTUP/1c-mcp-toolkit
    
    Этот скилл собран на основе родного скилла `calling-1c-rest-api-via-curl` из
    репо MCP-toolkit с дополнениями: раздел запуска 1С, готовые PowerShell-скрипты,
    EPF в `bin/`, типичные ошибки и паттерны.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related