# MCP-интерфейс Crank публикует REST-операции как MCP-инструменты через Streamable HTTP. ## Endpoint агента Каждый агент имеет собственный MCP endpoint: ```text /mcp/v1/{workspace_slug}/{agent_slug} ``` Для demo seed: ```text /mcp/v1/default/currency-rates ``` Полный URL зависит от вашего домена: ```text https://crank.example.com/mcp/v1/default/currency-rates ``` ## Авторизация MCP-клиент должен передавать API-ключ агента: ```http Authorization: Bearer ``` Ключ выдается в разделе **API ключи**. Полное значение показывается только один раз при создании. ## Поддерживаемые методы 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`: ```http Authorization: Bearer Content-Type: application/json Accept: application/json, text/event-stream ``` Для `GET`: ```http Authorization: Bearer Accept: text/event-stream MCP-Session-Id: ``` После `initialize` сервер возвращает заголовок: ```http MCP-Session-Id: ``` Если клиент передает `MCP-Protocol-Version`, он должен совпадать с версией, согласованной при инициализации. ## Пример `initialize` ```bash curl -i https://crank.example.com/mcp/v1/default/currency-rates \ -H 'Authorization: Bearer ' \ -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` ```bash curl https://crank.example.com/mcp/v1/default/currency-rates \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'MCP-Session-Id: ' \ --data '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }' ``` Ожидаемый результат для demo seed содержит инструмент: ```text frankfurter_latest_rate ``` ## Пример `tools/call` ```bash curl https://crank.example.com/mcp/v1/default/currency-rates \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'MCP-Session-Id: ' \ --data '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "frankfurter_latest_rate", "arguments": { "base": "USD", "quote": "EUR" } } }' ``` Crank выполнит REST-запрос: ```text GET https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR ``` ## Как формируется каталог инструментов MCP-клиент видит только опубликованные операции, которые привязаны к опубликованному агенту. Черновики операций не попадают в MCP-каталог. Если два пользователя работают в одном workspace, один может редактировать черновик, а второй публиковать агента. В опубликованный каталог попадут только опубликованные версии операций. ## Обновление каталога `mcp-server` периодически обновляет опубликованный каталог. Интервал задается: ```env 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`.