Files
crank/docs/mcp-interface.md
T
github-ops 78d3052a61
CI / Rust Checks (push) Successful in 1h25m31s
CI / UI Checks (push) Successful in 6s
CI / Deployment Manifests (push) Successful in 2s
CI / Deploy (push) Has been cancelled
CI / Frontend E2E (push) Has been cancelled
Document human approval flow
2026-06-24 11:43:34 +00:00

7.8 KiB

MCP-интерфейс

Crank публикует REST-операции как MCP-инструменты через Streamable HTTP.

Endpoint агента

Каждый агент имеет собственный MCP endpoint:

/mcp/v1/{workspace_slug}/{agent_slug}

Для demo seed:

/mcp/v1/default/currency-rates

Полный URL зависит от вашего домена:

https://crank.example.com/mcp/v1/default/currency-rates

Авторизация

MCP-клиент должен передавать API-ключ агента:

Authorization: Bearer <agent_api_key>

Ключ выдается в разделе API ключи. Полное значение показывается только один раз при создании.

Для операций с подтверждением человеком нужен отдельный ключ подтверждения. Его тоже выдают в разделе API ключи, но в режиме Подтверждения. Такой ключ нельзя передавать LLM или MCP-клиенту. Он нужен только вашему внешнему интерфейсу, где пользователь нажимает «Подтвердить» или «Отклонить».

Поддерживаемые методы

MCP methods:

  • initialize;
  • notifications/initialized;
  • ping;
  • tools/list;
  • tools/call.

HTTP transport:

  • POST /mcp/v1/{workspace_slug}/{agent_slug} - JSON-RPC запросы;
  • GET /mcp/v1/{workspace_slug}/{agent_slug} - server-to-client stream;
  • DELETE /mcp/v1/{workspace_slug}/{agent_slug} - закрытие сессии.

Обязательные заголовки

Для POST:

Authorization: Bearer <agent_api_key>
Content-Type: application/json
Accept: application/json, text/event-stream

Для GET:

Authorization: Bearer <agent_api_key>
Accept: text/event-stream
MCP-Session-Id: <session_id>

После initialize сервер возвращает заголовок:

MCP-Session-Id: <session_id>

Если клиент передает MCP-Protocol-Version, он должен совпадать с версией, согласованной при инициализации.

Пример initialize

curl -i https://crank.example.com/mcp/v1/default/currency-rates \
  -H 'Authorization: Bearer <agent_api_key>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": {
        "name": "curl",
        "version": "1.0.0"
      }
    }
  }'

Сохраните MCP-Session-Id из ответа.

Пример tools/list

curl https://crank.example.com/mcp/v1/default/currency-rates \
  -H 'Authorization: Bearer <agent_api_key>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'MCP-Session-Id: <session_id>' \
  --data '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {}
  }'

Ожидаемый результат для demo seed содержит инструмент:

frankfurter_latest_rate

Пример tools/call

curl https://crank.example.com/mcp/v1/default/currency-rates \
  -H 'Authorization: Bearer <agent_api_key>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'MCP-Session-Id: <session_id>' \
  --data '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "frankfurter_latest_rate",
      "arguments": {
        "base": "USD",
        "quote": "EUR"
      }
    }
  }'

Crank выполнит REST-запрос:

GET https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR

Операции с подтверждением человеком

Если в мастере операции включено Подтверждение человеком, первый tools/call не выполняет REST-запрос сразу. Вместо этого Crank создает ожидающий запрос на подтверждение и возвращает MCP-клиенту структурированный результат:

{
  "status": "approval_required",
  "approval_id": "approval_...",
  "approval_url": "/v1/default/sales/approvals/approval_...",
  "approve": {
    "method": "POST",
    "url": "/v1/default/sales/approvals/approval_.../approve",
    "body": { "approve": "yes" }
  },
  "deny": {
    "method": "POST",
    "url": "/v1/default/sales/approvals/approval_.../deny",
    "body": { "approve": "no" }
  }
}

approval_url в ответе является путем на MCP-сервере. Если вы публикуете MCP через префикс /mcp, внешний URL будет начинаться с /mcp/v1/....

Внешний интерфейс подтверждения работает отдельным ключом подтверждения:

curl https://crank.example.com/mcp/v1/default/sales/approvals \
  -H 'Authorization: Bearer <approval_api_key>'

Подтверждение:

curl https://crank.example.com/mcp/v1/default/sales/approvals/<approval_id>/approve \
  -H 'Authorization: Bearer <approval_api_key>' \
  -H 'Content-Type: application/json' \
  --data '{ "approve": "yes", "note": "Пользователь подтвердил действие" }'

Отклонение:

curl https://crank.example.com/mcp/v1/default/sales/approvals/<approval_id>/deny \
  -H 'Authorization: Bearer <approval_api_key>' \
  -H 'Content-Type: application/json' \
  --data '{ "approve": "no", "note": "Пользователь отклонил действие" }'

Ключ MCP-клиента не подходит для этих endpoints. Ключ подтверждения, наоборот, не подходит для initialize, tools/list и tools/call.

Как формируется каталог инструментов

MCP-клиент видит только опубликованные операции, которые привязаны к опубликованному агенту.

Черновики операций не попадают в MCP-каталог. Если два пользователя работают в одном workspace, один может редактировать черновик, а второй публиковать агента. В опубликованный каталог попадут только опубликованные версии операций.

Обновление каталога

mcp-server периодически обновляет опубликованный каталог. Интервал задается:

CRANK_MCP_REFRESH_MS=5000

После публикации операции или агента подождите один интервал обновления или перезапустите mcp-server.

Ошибки

Частые причины ошибок:

  • 401 Unauthorized - отсутствует или неверен API-ключ агента.
  • 403 Forbidden - ключ не имеет нужного доступа.
  • 404 Not Found - workspace, агент или инструмент не опубликованы.
  • 400 Bad Request - неверный MCP-заголовок, session id или JSON-RPC payload.
  • 429 Too Many Requests - сработал rate limit.

Runtime-ошибки инструмента возвращаются как структурированный MCP tool error с кодом, сообщением и request_id.