MCP: протокол для разработчиков клиентов

> Кратко. POST /mcp — сервер Model Context Protocol (JSON-RPC 2.0 поверх HTTP, без потоков и сессий). Здесь — то, что нужно, чтобы написать свой клиент или агента: методы, формат ответов и ошибок, список инструментов с аргументами, токен. Как подключить готовый клиент (Claude Desktop, Claude Code, Cursor) и выдать токен в кабинете — на странице MCP-сервер для ИИ-клиентов.

Читаю как

Транспорт

  • Один адрес: POST <API>/mcp (у API нескольких городов — /city/<код>/mcp, за nginx — /tgid/<город>/map-api/mcp). Ответ — всегда application/json; GET и DELETE — 405 (потока событий и сессий нет, Mcp-Session-Id не выдаётся).
  • Заголовок MCP-Protocol-Version: 2025-06-18, 2025-03-26 или 2024-11-05; другая версия — 400. В initialize сервер отвечает версией клиента, если знает её, иначе последней.
  • Пакет (массив сообщений, как в 2025-03-26) — от 1 до 10 сообщений; уведомления ответа не получают (только уведомления в запросе — HTTP 202 без тела).
  • Тело — не больше 1 МБ (413). Заголовок Origin не из CORS_ALLOWED_ORIGINS — 403 (защита от DNS rebinding).
  • Вход: Authorization: Bearer <токен> — токен ИИ-клиента (scope: mcp) или токен входа веба. Нет токена, истёк, пароль сменён — 401 с WWW-Authenticate: Bearer. Токен MCP на других адресах API не принимается (401), а ключи ArcGIS и API v2 не принимаются здесь.
  • MCP_ENABLED=false — 404.

Методы

Метод Ответ
initialize protocolVersion, capabilities: {"tools": {"listChanged": false}}, serverInfo (name: "tgid"), instructions — подсказка модели о сервере
ping {}
tools/list все 19 инструментов: name, title, description, inputSchema (JSON Schema из pydantic), annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
tools/call {"name": "…", "arguments": {…}} → результат инструмента
другие ошибка JSON-RPC −32601 «Метод не поддерживается»

Подписок на ресурсы, подсказок (prompts) и notifications/tools/list_changed нет.

Результат и ошибки

Успех: {"content": [{"type": "text", "text": "<JSON>"}], "structuredContent": {…}, "isError": false} — ответ инструмента одной текстовой частью и тем же объектом в structuredContent. Геометрия из ответов убирается, списки обрезаются до 200 элементов, очень длинный ответ — с пометкой «ответ обрезан — сузьте запрос».

Ошибка инструмента (неверный аргумент, нет права, нет расчёта, превышена частота) — не ошибка JSON-RPC, а результат isError: true с текстом причины: модель видит её и может исправить вызов. Ошибки JSON-RPC — только у самого протокола: −32700 (не JSON), −32600 (не сообщение JSON-RPC, неверный пакет), −32601 (метод), −32602 (нет такого инструмента, arguments — не объект).

Персональные данные в ответах маскируются, если у пользователя токена нет права «Персональные данные». Вызовы пишутся в журнал действий (MCP).

Ограничения: 60 вызовов инструментов в минуту на пользователя (RATE_LIMIT); run_calculation — 5 запусков за 10 минут (CALC_RATE_LIMIT) и право «Запуск расчётов». Счётчики — в памяти процесса API.

Инструменты

Список на копии Алматы (tools/list, 19 инструментов). Все, кроме run_calculation, только читают.

Инструмент Аргументы (обязательные — жирным)
list_fragments —
search_network kind (node, line, source, consumer), text, text2, fragment_id
select_network target (lines, nodes), conditions, match (all, any), near, near_poi, in_view, fragment_ids, order_by, order_desc, limit
network_trace trace_type (connected, upstream, downstream, subnetwork), config_id, stop_at (valves, pumpstations, setpress, sources), start_node_ids, start_line_ids, barrier_node_ids, barrier_line_ids
list_trace_configs —
valve_isolation line_id, node_id, failed_valve_ids
network_statistics query (length, volume, length_by_diameter, length_by_diameter_laying, heat_consumption, closed_consumers), fragment_ids
regime_analysis fragment_id, kind (negative_dp, airlock, low_temperature, closed_sections, hydrostatic_zones), calculation_id
thematic_summary theme, fragment_ids, top
wear_priorities fragment_id, min_category, limit
similar_defects text, lon, lat, radius_m, limit
failure_hotspots years
data_quality fragment_id
run_calculation fragment_ids, mode (plan, emergency), tn, name
task_status task_id
list_calculations fragment_ids, limit
list_scenarios include_archived
scenario_diff scenario_id, limit
scenario_compare scenario_id, base_calculation_id, scenario_calculation_id, limit

Точные типы, границы и описания аргументов — в inputSchema ответа tools/list. Девять инструментов (в том числе run_calculation) доступны и как процессы OGC API — Processes с теми же аргументами.

Пример

H='Content-Type: application/json'; A="Authorization: Bearer $MCP_TOKEN"
curl -s -X POST "$API/mcp" -H "$H" -H "$A" -H "MCP-Protocol-Version: 2025-06-18" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-agent","version":"1"}}}'
curl -s -X POST "$API/mcp" -H "$H" -H "$A" -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
curl -s -X POST "$API/mcp" -H "$H" -H "$A" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"network_statistics","arguments":{"query":"length","fragment_ids":[74]}}}'

Ответ на копии Алматы:

{"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"{\"query\": \"length\", …}"}],"isError":false,
 "structuredContent":{"query":"length","title":"Длина теплопроводов, м","fragment_ids":[74],
  "length_supply_m":197263.2,"length_return_m":197576.4,"length_total_m":394839.6}}}

Неизвестный метод: {"jsonrpc":"2.0","id":4,"error":{"code":-32601,"message":"Метод не поддерживается: nope"}}. Запрос с Origin: https://evil.example — 403 {"detail":"Origin не разрешён"}.

task_status отвечает тем же, что GET /api/v1/task/{task_id}: состояние задания и, когда оно готово, итог расчёта. Так агент следит за расчётом, который сам запустил через run_calculation.

Токен

POST /api/v1/mcp/token с токеном входа → {"token", "expires_at", "days", "path": "/mcp"}. Срок — MCP_TOKEN_DAYS (по умолчанию 30, не больше 90). Токен — JWT с scope: mcp и отпечатком пароля (pwf); отозвать его по одному нельзя — только сменой пароля или блокировкой учётной записи. GET /api/v1/mcp/info — включён ли сервер, срок токена и инструменты (name, title, permission).

На стенде с AUTH_DISABLED=true /mcp принимает вызовы без токена от имени администратора.

Для разработчика

  • API: routers/mcp.py (транспорт, Origin, токен), tgid_mcp/protocol.py (JSON-RPC, PROTOCOL_VERSIONS), tgid_mcp/tools.py (реестр TOOLS, describe_tools, RATE_LIMIT, MAX_LIST_ITEMS). Новый инструмент — pydantic-модель параметров, функция run, право и пометка read_only в реестре; он сразу появится у MCP, у помощника ИИ и (если добавить в PROCESSES) в OGC Processes.
  • Тесты: API — tests/test_mcp.py; e2e — e2e/functions/ai.spec.ts, e2e/functions/developer-api.spec.ts.
Хотите увидеть эту функцию на своих данных?Покажем ТГИД на демонстрации и ответим на вопросы инженеров.
Запросить демо