5.8.3.3. MCP-сервер (readonly)¶
Added in version 1.29.0-ms2.
5.8.3.3.1. Обзор¶
Readonly MCP-сервер — реализация Model Context Protocol поверх сервера приложений Global3, дающая внешнему агенту (LLM-клиенту) доступ к прикладным выборкам (Selection) только на чтение. Сервер выступает MCP-сервером для агента-клиента: агент через свой MCP-транспорт вызывает инструменты (tools), которыми сервер публикует метаданные выборок для discovery и постраничное чтение их строк.
Ключевые свойства:
Протокол — JSON-RPC 2.0 поверх транспорта Streamable HTTP (без SSE-стрима).
Область (Этап 1, readonly-MVP) — discovery выборок, разрешённых агенту серверной политикой доступа, и headless-чтение их строк. Инструменты записи (
set_field,run_operation,commitи т.п.) намеренно исключены.Exclusive Session —
initializeсоздаёт монопольный серверный рабочий сеанс (по образцу сервиса es/pkg); каждый вызов инструмента исполняется под монопольным захватом сессии («один tool-call за раз»).Политика доступа — какие выборки видны агенту, определяет серверная политика в секции конфига
Configuration.Mcp(см. Политика доступа агента к выборкам).
Внешний путь эндпоинта — /app/sys/rest/es/mcp (см. Справочник URI эндпоинтов).
Attention
MCP-сервер поддерживается только на решениях PostgreSQL (база с секцией
eclipseLink в конфиге, режим соединений proxyShared). Oracle-режим
не поддерживается: там применяется другой контур работы с БД —
соединение захватывается на всё время жизни выборки, а курсор остаётся открытым
до её закрытия, поэтому долгоживущие открытые выборки MCP удерживали бы
соединения пула.
5.8.3.3.2. Подключение и транспорт¶
Адрес сервиса
http://{server:port}/app/sys/rest/es/mcp
Ресурс смонтирован Jersey-сервлетом /app/sys/rest/*; отдельной настройки
web.xml для MCP не требуется — контейнерная аутентификация уже покрывает эту зону.
5.8.3.3.2.1. HTTP-методы¶
Метод |
Назначение |
|---|---|
|
Единая точка входа: диспетчеризация конверта JSON-RPC 2.0
( |
|
Закрытие сессии по заголовку |
|
Не поддерживается: всегда |
Транспорт — Streamable HTTP: тело запроса и ответа несёт конверт JSON-RPC 2.0, SSE-стрим не используется.
5.8.3.3.2.2. Заголовки запроса¶
Заголовок |
Обяз. |
Значение |
|---|---|---|
|
да |
|
|
нет |
Алиас целевой БД/решения; при отсутствии берётся
|
|
для |
Идентификатор сессии, выданный сервером в ответе на |
|
нет |
Проверяется на НЕ- |
Note
Заголовок Database можно слать в любом регистре — сервер приводит имя
решения к верхнему регистру. Но для схемы Bearer claim sln внутри JWT
сверяется с нормализованным именем побайтно (регистрозависимо), поэтому имя
решения в самом токене должно быть уже в ВЕРХНЕМ регистре, иначе 401. См.
Аутентификация.
5.8.3.3.2.3. Версии протокола MCP¶
Версия по умолчанию — 2025-06-18. Поддерживаемый набор (от новой к старой):
2025-06-182025-03-26
Согласование: в initialize берётся params.protocolVersion, если он входит
в набор, иначе — дефолт; согласованная версия возвращается в result.protocolVersion.
На последующих запросах заголовок MCP-Protocol-Version, если присутствует,
должен принадлежать этому же набору, иначе ответ — 400 с JSON-RPC-ошибкой
Invalid Request.
5.8.3.3.2.4. Методы JSON-RPC и коды ответа¶
Диспетчер поддерживает ровно пять методов; прочие → METHOD_NOT_FOUND (-32601).
Метод |
Назначение и результат |
|---|---|
|
Запрос (обязан нести |
|
Нотификация (без |
|
Запрос. |
|
Запрос. |
|
Запрос. Требует валидный |
Код |
Условие |
|---|---|
|
Успешный JSON-RPC-ответ. Важно: протокольные ошибки JSON-RPC
( |
|
Принята нотификация (запрос без |
|
|
|
Единственный случай не-200 для JSON-RPC-ошибки: неподдерживаемая
|
|
Нет/невалидные учётные данные; ответ несёт |
|
|
|
|
|
Сервер в режиме обслуживания (пользователь не SYSTEM); тело text/plain. |
5.8.3.3.2.5. Порядок хендшейка¶
POST initialize(сAuthorizationиDatabase) →200; из заголовков ответа клиент запоминаетMcp-Session-Id, из тела —result.protocolVersion/serverInfo.POST notifications/initialized(безid) →202.Рабочие запросы:
tools/list(сессия не нужна),tools/call(обязателенMcp-Session-Id). Каждыйtools/callисполняется монопольно.POST ping— опциональная проверка живости эндпоинта. Сессию не продлевает (исполняется без неё), поэтому от закрытия по простою не спасает.DELETE(сMcp-Session-Id) →204; сессия и её открытые выборки закрываются каскадно.
5.8.3.3.2.6. Пример: initialize¶
curl -sS -D - "http://localhost:8080/app/sys/rest/es/mcp" \
-H "Authorization: Bearer $JWT" -H "Database: GSTEST" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}'
Ответ — HTTP 200, заголовок Mcp-Session-Id: <uuid>, тело:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {"tools": {"listChanged": false}},
"serverInfo": {"name": "Global3 AS MCP", "version": "1.29.0"}
}
}
Конфигурация MCP-клиента (Streamable HTTP):
{
"type": "http",
"url": "http://localhost:8080/app/sys/rest/es/mcp",
"headers": {"Authorization": "Bearer <jwt>", "Database": "GSTEST"}
}
5.8.3.3.3. Аутентификация¶
MCP-эндпоинт не содержит собственного кода логина: аутентификацию выполняет
транспортный слой (сервлет-фильтр), а ресурс дополнительно делает defense-in-depth
(проверяет режим обслуживания и наличие principal) и берёт готовый principal из
контейнера. Запрос без валидных учётных данных → 401 с
WWW-Authenticate: Bearer.
Эндпоинт принимает обе HTTP-схемы — Basic
и Bearer (один фильтр обслуживает обе;
источники учётных данных перебираются в порядке: cookie access_token →
заголовок Authorization → параметр access_token).
Выбор решения (алиас БД) резолвится единой цепочкой fallback: request-атрибут →
заголовок Database → request-параметр Database → defaultDatabaseAlias
из global3.config.xml. Прежде чем использовать, сервер нормализует имя решения
в UPPER-CASE.
Warning
Для схемы Bearer имя решения зашито в JWT как приватный claim sln и
сверяется с нормализованным (UPPER-CASE) значением побайтно. Поэтому токен,
выпущенный с решением в нижнем регистре (sln="gstest"), даёт 401 —
имя БД в токене должно совпадать с нормализованным, то есть быть в ВЕРХНЕМ
регистре (sln="GSTEST"). Токены, которые сервер выпускает сам после логина,
всегда несут уже заглавное имя решения; проблема воспроизводится для токенов,
собранных вне сервера.
Пример «сырого» запроса:
POST /app/sys/rest/es/mcp HTTP/1.1
Authorization: Bearer ast_<jwt...>
Database: GSTEST
MCP-Protocol-Version: 2025-06-18
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}
Полное описание типов аутентификации — Аутентификация в HTTP сервисах.
5.8.3.3.4. Сессия и её жизненный цикл¶
MCP-сессия — это серверный рабочий сеанс (Exclusive Session), создаваемый обработкой
метода initialize (только запрос с id; initialize без id сессию НЕ
создаёт). При создании сервер генерирует случайный UUID и возвращает его клиенту
в заголовке Mcp-Session-Id ответа. Внутренний ключ рабочего сеанса
детерминирован от тройки (db, user, mcpSessionId) (вид
MCP-{db}/{user}[mcp-{mcpSessionId}]); последующие tools/call и DELETE
реконструируют его из principal и заголовка Mcp-Session-Id. Сессия строго
привязана к тому же principal (db + user).
5.8.3.3.4.1. Открытые выборки¶
Инструмент open_selection открывает выборку в собственном рабочем контексте,
переживающем вызов, и регистрирует её в реестре сессии по handle (UUID),
возвращаемому агенту как sessionRef. Инструменты get_opened_meta/read_rows
резолвят выборку по sessionRef. Отдельного инструмента close_selection в
каталоге НЕТ — открытые выборки закрываются только вместе со всей сессией
(каскадно).
Что открытая выборка удерживает до закрытия сессии: сам объект выборки с
DataStore и прочитанными строками в памяти сервера, свой
WorkSessionContext и объект соединения движка. Физическое соединение с БД
при этом НЕ занимается: на PostgreSQL оно берётся из пула на время выполнения
запроса и сразу возвращается (короткая транзакция), серверный курсор между
вызовами не живёт — строки уже прочитаны в кэш выборки. Поэтому цена открытой
выборки измеряется памятью сервера, а не занятыми соединениями пула.
5.8.3.3.4.2. Когда сессия закрывается¶
Единый путь закрытия каскадно закрывает все открытые выборки сессии (а затем и их контексты). Триггеры:
Явный
DELETEсMcp-Session-Id→204. Закрытие идёт под монитором сессии: если параллельно исполняетсяtools/call,DELETEдождётся его завершения.Простой по таймауту. Если клиент разорвал HTTP без
DELETE, сессию закрывает фоновый поток-уборщикRestSession-Eviction(общий для всех Rest-сессий). Таймаут простоя — 15 минут, период обхода — тоже 15 минут, поэтому фактическая зачистка простаивающей сессии наступает через 15–30 минут после последней активности. Уборщик закрывает только ПРОСТАИВАЮЩИЕ просроченные сессии (не рвёт активныйtools/call).Остановка сервера (
contextDestroyed) — закрываются все Rest-сессии.
5.8.3.3.4.3. Лимиты¶
Лимит |
Значение |
Поведение при достижении |
|---|---|---|
Открытых выборок на сессию |
32 |
|
Живых MCP-сессий на пользователя |
8 |
|
Оба значения — константы кода (McpSessionAbst, McpRestServiceImpl);
конфигом они не настраиваются.
Note
Утечки выборок и их контекстов в штатных путях нет: каждый open_selection
завершается либо регистрацией в сессии (гарантированное каскадное закрытие),
либо немедленным закрытием на месте (при исчерпании лимита или гонке с закрытием
сессии). Брошенная клиентом сессия не живёт вечно — её закроет уборщик простоя
за 15–30 минут. Накопление сверху ограничено произведением лимитов (8 × 32).
5.8.3.3.5. Политика доступа агента к выборкам¶
Какие выборки доступны агенту, решает серверная политика — секция конфига
Configuration.Mcp файла global3.config.xml. Это отдельный слой
поверх обычной авторизации: даже успешно аутентифицированный агент видит через MCP
только разрешённые политикой выборки. Права самого пользователя политика не меняет
и строки данных не фильтрует — она сужает перечень выборок, которые агенту вообще
можно назвать.
Проверку проходит каждый инструмент, называющий выборку: find_selections
ищет только среди разрешённых имён, а адресные инструменты (включая
open_selection) отвергают выборку вне перечня ошибкой «Выборка ‘…’ не найдена
или недоступна для MCP-discovery».
5.8.3.3.5.1. Два атрибута и правило их чтения¶
Политика описывается элементом Configuration.Mcp.AgentAccess с двумя
атрибутами, и они не равноправны — у каждого своя роль:
Configuration.Mcp.AgentAccess.override— рубильник: переключает весь MCP-контур целиком, не трогая базовую политику. По умолчаниюoff— «не вмешиваться».Configuration.Mcp.AgentAccess.default— базовая политика: ответ сервера, когда рубильник отпущен. По умолчаниюdeny— «запрещено».
Отсюда правило чтения ровно в два шага:
Сервер смотрит
override. Любое значение, кромеoff, определяет исход само —defaultпри этом не читается вовсе.И только при
override="off"исход задаётdefault.
|
Агенту доступны |
Читается ли |
|---|---|---|
|
при |
да, это единственный такой режим |
|
все выборки |
нет |
|
ни одной выборки |
нет |
|
только перечисленные в |
нет |
«Все выборки» здесь — все существующие в решении (*.avm.xml). Открыть
несуществующее имя не даёт ни один режим: в list лишние имена перечня просто
ни на что не отображаются, а allowAll открывает ровно то, что в решении есть.
Attention
Конфигурация без секции <mcp> — равно как и пустой <agentAccess> —
означает override="off" плюс default="deny": внешний агент не видит
ни одной выборки, пока доступ не открыт явно (fail-closed).
Note
Двух атрибутов кажется много там, где исход почти всегда решает один. Они
отвечают за разное: default описывает намерение решения («в норме доступ
закрыт»), а override — рубильник поверх него.
Положения allowAll и denyAll при этом отладочные: они открывают или
закрывают контур целиком, не читая ни default, ни перечень
Configuration.Mcp.Selections, — место им на стендах разработки и
тестирования (allowAll стоит в dev-конфиге). Рабочий контур на Этапе 1
настраивают перечнем: default="deny" плюс override="list" — так
выглядит пример в шаблоне конфига дистрибутива.
5.8.3.3.5.2. Примеры XML-конфигурации¶
Режим list — рабочая настройка: агенту разрешены ровно перечисленные выборки:
<mcp>
<agentAccess default="deny" override="list"/>
<selections>
<selection name="Gs3_McpOrder"/>
<selection name="Gs3_McpCustomer"/>
</selections>
</mcp>
Режим allowAll — отладочный: агенту открыты все выборки решения. Так
публикует их dev-конфиг стенда разработки:
<mcp>
<agentAccess default="deny" override="allowAll"/>
</mcp>
В обоих примерах default="deny" записан для явности намерения, но на исход не
влияет: рубильник переведён. Перечень допустимых значений обоих атрибутов — в
справочнике XSD: Configuration.Mcp.DefaultAccess и
Configuration.Mcp.OverrideMode.
5.8.3.3.6. Инструменты¶
Каталог публикует ровно 10 readonly-инструментов в стабильном порядке
регистрации. Все вызываются методом tools/call (params.name +
params.arguments); inputSchema каждого — JSON Schema draft-07.
5.8.3.3.6.1. Упаковка результата и ошибки¶
Результат любого инструмента — MCP-контент {content:[{type:"text",text}], isError};
полезная нагрузка лежит строкой JSON в content[0].text. Успех — isError:false.
Любая прикладная ошибка (неизвестный sessionRef, недоступная выборка, отсутствующий
обязательный аргумент, неизвестное имя инструмента) — НЕ протокольная ошибка
JSON-RPC, а нормальный result с isError:true и текстом сообщения. Протокольную
ошибку INVALID_PARAMS даёт лишь невалидный конверт вызова (отсутствующий/нестроковый
name).
Инструмент |
Группа |
Назначение |
|---|---|---|
|
|
Найти выборки по подстроке в имени/заголовке. |
|
|
Сквозной поиск операций/атрибутов/полей фильтра по подстроке. |
|
|
Узкие метаданные выборки: caption, description, представления (с caption/description/documentation), поля фильтра. |
|
|
Список атрибутов выборки. |
|
|
Статические метаданные одного атрибута. |
|
|
Список операций выборки (без служебных). |
|
|
Поля фильтра представления (ключи для |
|
|
Открыть выборку headless, вернуть |
|
|
Метаданные открытой выборки с наложенными настройками администрирования. |
|
|
Страница строк открытой выборки. |
Attention
Расхождение discovery ↔ open: инструменты группы A отдают статическое описание из
метаданных выборки, к которому ещё не применены настройки системы администрирования.
Поэтому в get_attribute_meta поля visible/readOnly приходят нейтральными
заглушками (жёстко true/false), а fieldType у прикладных сущностных
атрибутов — ftUnknown: реальный тип движок разворачивает лишь при активации
выборки. Значения, отражающие открытую выборку — с наложенными настройками
администрирования и развёрнутым типом поля, — даёт ТОЛЬКО get_opened_meta.
5.8.3.3.6.2. Группа A. Discovery без открытия выборки¶
Семь инструментов читают статические и рантайм-метаданные разрешённых агенту выборок
(политика доступа) без открытия выборки — каждый
работает под своим короткоживущим контекстом с соединением, освобождаемым по выходу
из вызова. Типичный
маршрут: find_selections → get_selection_meta →
list_attributes/list_operations/get_attribute_meta/get_filter_meta →
переход к open_selection.
5.8.3.3.6.2.1. find_selections¶
Назначение: найти доступные агенту выборки по подстроке в имени ИЛИ заголовке.
Аргументы:
query(string, обязателен).Результат:
{selections:[{name, caption, module}], truncatedResults?, truncatedCaptionSearch?, note?}.Ограничения/флаги: список усечён верхним пределом 200 результатов (
truncatedResults:true); поиск по caption ограничен бюджетом 500 загрузок (truncatedCaptionSearch:true). Каждый флаг сопровождается человекочитаемымnote. При флаге клиент должен сузитьqueryили указать точное имя.Ошибки: пустой
query→ «Не задан обязательный аргумент ‘query’».
5.8.3.3.6.2.2. find_in_selection¶
Назначение: поиск операций и/или атрибутов (и полей фильтра) по подстроке — по всем доступным выборкам или в одной.
Аргументы:
query(string, обязателен);selection(string, опц.) — имя выборки;scope(string enum, опц.) — строгоoperation|attribute.Результат:
{matches:[{selection, kind, name, caption, description}], truncated?, note?};kind∈ {operation,attribute,filter} (filter— только когдаscopeне задан).Ограничения/флаги: без
selectionобход ограничен 200 просмотренными выборками, совпадений — не более 500; достижение любого лимита →truncated:true.Ошибки: пустой
query; недопустимыйscope→ «Недопустимый scope ‘…’. Допустимые значения: operation, attribute (или не задавать).»
5.8.3.3.6.2.3. get_selection_meta¶
Назначение: метаданные выборки —
caption,description(человекочитаемое описание выборки из<documentation>уровня view), представления (сcaption/description/documentation) и поля фильтра (список атрибутов НЕ возвращает — для негоlist_attributes).Аргументы:
name(string, обязателен).Результат:
{caption, description, representations:[{name, caption, description, documentation}], detailSelections:[string], filters:[{name, caption, fieldType, defaultValue, editorType}]}. Тексты представлений (caption/description/documentation) могут бытьnull, если соответствующий узел метаданных не заведён. Замечание:detailSelectionsлёгким путём не резолвятся — всегда пустой список.Ограничения: при недоступности живых метаданных деградирует до минимальной нагрузки (
captionравен имени,description=null,representationsи прочие списки пусты) без падения.Ошибки: пустой
name; выборка не разрешена политикой доступа.
5.8.3.3.6.2.4. list_attributes¶
Назначение: список атрибутов выборки (статические discovery-метаданные).
Аргументы:
name(string, обязателен).Результат:
{attributes:[{name, caption, description}]}.Ошибки: пустой
name; выборка не разрешена политикой доступа.
5.8.3.3.6.2.5. get_attribute_meta¶
Назначение: статические метаданные одного атрибута.
Аргументы:
name(string, обязателен) — имя выборки;attr(string, обязателен) — имя атрибута.Результат:
{name, caption, fieldType, visible, readOnly, required}.Ограничения:
visibleвсегдаtrue,readOnlyвсегдаfalse— заглушки, НЕ реальные права (см.get_opened_meta);fieldTypeчастоftUnknown.Ошибки: пустой
name/attr; атрибут не найден → «Атрибут ‘<attr>’ не найден в выборке ‘<name>’.»; выборка не разрешена политикой доступа.
5.8.3.3.6.2.6. list_operations¶
Назначение: список операций выборки (служебные исключены).
Аргументы:
name(string, обязателен).Результат:
{operations:[{name, caption, description}]}.Ошибки: пустой
name; выборка не разрешена политикой доступа.
5.8.3.3.6.2.7. get_filter_meta¶
Назначение: поля фильтра представления; их имена — КЛЮЧИ объекта
filterвopen_selection.Аргументы:
name(string, обязателен).Результат:
{filters:[{name, caption, fieldType, defaultValue, editorType}]}.Ограничения: при недоступности метаданных фильтра деградирует до пустого списка без падения. Для detail-представлений ключ мастера —
super$id.Ошибки: пустой
name; выборка не разрешена политикой доступа.
5.8.3.3.6.3. Группа B. Работа по открытой выборке¶
Три инструмента работают ТОЛЬКО по уже открытой выборке, адресуемой sessionRef.
Жизненный цикл и лимиты — см. Сессия и её жизненный цикл.
5.8.3.3.6.3.1. open_selection¶
Назначение: открыть выборку headless на чтение и вернуть
sessionRef.Аргументы:
name(string, обязателен);representation(string, опц.) — имя представления (по умолчанию основное);filter(object, опц.) — свободный объект имя_поля→значение (additionalProperties:true). Имена полейfilterберутся изget_filter_meta(напримерflt_dOrderDateFrom); для detail-представлений ключ мастера —super$id.Результат:
{sessionRef, name, representation}.Ограничения: регистрация в сессии с лимитом 32 открытых выборок; открытие выборки, не разрешённой политикой доступа, запрещено.
Ошибки: пустой
name; выборка не разрешена политикой доступа; превышение лимита 32; ошибка активации/сборки выборки (какisError, ресурсы освобождаются).
5.8.3.3.6.3.2. get_opened_meta¶
Назначение: прочитать метаданные открытой выборки — поля и операции с наложенными настройками системы администрирования.
Аргументы:
sessionRef(string, обязателен).Результат:
{name, representation, caption, attributes:[{name, caption, fieldType, visible, readOnly, required}], operations:[{name, caption, description, visible, enabled}]}. У атрибутовvisible/readOnly— значения системы администрирования (Attribute.isAdminVisible/isAdminReadOnly),fieldType— развёрнутый тип живой выборки. У операцийvisible/enabled— настройки администрирования вместе с прикладной логикой (isVisible() && isAdminVisible(),isEnabled() && isAdminEnabled()).Ошибки: пустой
sessionRef; неизвестный/закрытыйsessionRef→ «Неизвестный sessionRef: <ref>» / «Открытая выборка не найдена по ссылке ‘…’ (не открыта или уже закрыта).»
5.8.3.3.6.3.3. read_rows¶
Назначение: прочитать страницу строк открытой выборки. Фильтр задаётся ТОЛЬКО в
open_selection— повторная фильтрация не поддерживается.Аргументы:
sessionRef(string, обязателен);page(object, опц.) —{offset, limit}. По умолчаниюoffset=0,limit=100.Результат:
{columns:[string], rows:[{колонка→значение}], offset, loadedCount, allFetched}.Ограничения:
limitограничивается сверху значением 1000 (защита от вычитывания всей таблицы); отрицательныеoffset/limitнормализуются к 0; читается только запрошенная страница. Пагинация: увеличиватьoffset, покаallFetched=false;allFetched=trueозначает конец данных.Ошибки: пустой
sessionRef; неизвестныйsessionRef(те же два слоя, что уget_opened_meta).
5.8.3.3.7. Типовой сценарий¶
Discovery → открытие заказа → чтение строк → lookup клиента (на фикстурах
Gs3_McpOrder/Gs3_McpCustomer). Заголовки во всех запросах: Authorization,
Database, Content-Type: application/json, а для tools/call — ещё
Mcp-Session-Id (из ответа на initialize).
1. Найти выборку заказов (find_selections):
{"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{"name":"find_selections","arguments":{"query":"Gs3_McpOrder"}}}
Ответ (нагрузка — строкой JSON в content[0].text):
{"jsonrpc":"2.0","id":3,"result":{
"content":[{"type":"text",
"text":"{\"selections\":[{\"name\":\"Gs3_McpOrder\",\"caption\":\"Заказы\",\"module\":\"gs3\"}]}"}],
"isError":false}}
2. Открыть выборку в списочном представлении (open_selection) — возвращает
sessionRef:
{"jsonrpc":"2.0","id":4,"method":"tools/call",
"params":{"name":"open_selection",
"arguments":{"name":"Gs3_McpOrder","representation":"List"}}}
{"jsonrpc":"2.0","id":4,"result":{
"content":[{"type":"text",
"text":"{\"sessionRef\":\"a1b2c3d4-...\",\"name\":\"Gs3_McpOrder\",\"representation\":\"List\"}"}],
"isError":false}}
3. Прочитать первую страницу строк (read_rows) по полученному sessionRef:
{"jsonrpc":"2.0","id":5,"method":"tools/call",
"params":{"name":"read_rows",
"arguments":{"sessionRef":"a1b2c3d4-...","page":{"offset":0,"limit":100}}}}
В ответе content[0].text несёт {columns, rows, offset, loadedCount, allFetched}.
Если allFetched=false — продолжать, увеличивая offset.
4. Lookup клиента: взять из строки заказа идентификатор клиента, открыть
Gs3_McpCustomer (шаг open_selection с filter по нужному полю, имена полей
берутся из get_filter_meta) и прочитать его строку через read_rows.
5. Завершить диалог — DELETE с Mcp-Session-Id → 204 (открытые
выборки закрываются каскадно).
5.8.3.3.8. За рамками Этапа 1¶
Этап 1 намеренно ограничен чтением и грубой серверной политикой доступа. Ниже перечислено то, чего в нём нет, — чтобы отсутствие не выглядело недоработкой.
Note
Состав и сроки следующего этапа не зафиксированы, имена настроек и аннотаций в этом разделе рабочие и могут измениться. Раздел описывает направление, а не принятые решения.
5.8.3.3.8.1. Запись¶
Инструментов записи (set_field, set_param, run_operation,
run_validate, commit) в каталоге нет. Дело не в правах и не в headless:
открытым остаётся вопрос транзакционной границы. insert/edit/установка
значений копят черновик в памяти DataStore, фиксация идёт отдельной операцией —
и между двумя вызовами инструментов агент может оставить наполовину заполненный
объект или частично зафиксированные данные. Этап записи начинается с прототипа
именно этой границы, а не с добавления инструментов.
5.8.3.3.8.2. Права: декларация на уровне выборки¶
Сегодня доступ агента задаётся только серверной секцией <mcp>: она одна на весь
контур и ничего не знает о конкретной выборке. Прорабатывается отдельная ось
«доступно агенту» — декларативная характеристика в самом прикладном коде: признак
на классе выборки плюс свойство операции, наследуемое от выборки по умолчанию.
Смысл оси в том, что права пользователя не отличают «человек осознанно нажал
кнопку» от «модель решила вызвать операцию», и решать это должен прикладной
разработчик, а не только администратор контура.
Когда декларации появятся, перечень доступного агенту переедет в код выборок, а серверная секция останется тем, чем она полезна на стенде, — переключателем контура целиком.
5.8.3.3.8.3. Описания для агента¶
Качество работы агента упирается в описания: у многих выборок description пуст,
а у атрибутов роль описания играет заголовок. Поэтому Этап 1 отдаёт ровно то, что
уже есть в коде — @Oper и заголовки avm/dvm. Отдельный слой описаний,
написанных специально для агента (в том числе примеры значений), в рантайм MCP не
загружается и остаётся предметом проработки.
See also
Справочник URI эндпоинтов — справочник URI (пункт
/es/mcp).Аутентификация в HTTP сервисах — типы HTTP-аутентификации (Basic/Bearer).
Прикладные пакеты — соседний сервис
es/pkgв режиме Exclusive Session.Configuration.Mcp— секция конфига с политикой доступа, а такжеConfiguration.Mcp.AgentAccess,Configuration.Mcp.AgentAccess.default,Configuration.Mcp.AgentAccess.override,Configuration.Mcp.Selections.