Complete markdown documentation
Deploy / deploy (push) Successful in 37s
CI / Rust Checks (push) Successful in 27m22s
CI / UI Checks (push) Successful in 6s
CI / Deployment Manifests (push) Successful in 3s
CI / Frontend E2E (push) Successful in 20m44s

This commit is contained in:
github-ops
2026-06-21 12:49:56 +00:00
parent c77065756d
commit 9331ee1d89
11 changed files with 680 additions and 135 deletions
+3
View File
@@ -264,6 +264,9 @@ npx playwright test
- [Веб-интерфейс](docs/ui.md) - [Веб-интерфейс](docs/ui.md)
- [MCP-интерфейс](docs/mcp-interface.md) - [MCP-интерфейс](docs/mcp-interface.md)
- [Admin API](docs/admin-api.md) - [Admin API](docs/admin-api.md)
- [Практические API-примеры](docs/api-examples.md)
- [Production checklist](docs/production-checklist.md)
- [Troubleshooting](docs/troubleshooting.md)
- [Настройки запуска](docs/runtime-config.md) - [Настройки запуска](docs/runtime-config.md)
- [Английский README](docs/en/README.md) - [Английский README](docs/en/README.md)
+5 -2
View File
@@ -2,7 +2,7 @@
Crank превращает REST API endpoint-ы в MCP-инструменты, которые можно подключать к AI-агентам и MCP-клиентам. Crank превращает REST API endpoint-ы в MCP-инструменты, которые можно подключать к AI-агентам и MCP-клиентам.
Эта документация подготовлена как основа для будущего сайта. Сейчас файлы лежат в `docs/`, позже их можно перенести в Docusaurus без изменения структуры тем. Документация хранится в Markdown-файлах внутри `docs/` и читается прямо из репозитория.
## Начать ## Начать
@@ -10,6 +10,7 @@ Crank превращает REST API endpoint-ы в MCP-инструменты,
- [Установка](./installation.md) - [Установка](./installation.md)
- [Первый инструмент](./quickstart.md) - [Первый инструмент](./quickstart.md)
- [Подключение MCP-клиента](./mcp-interface.md) - [Подключение MCP-клиента](./mcp-interface.md)
- [Практические API-примеры](./api-examples.md)
## Возможности ## Возможности
@@ -17,13 +18,15 @@ Crank превращает REST API endpoint-ы в MCP-инструменты,
- [REST-инструменты](./protocols/rest.md) - [REST-инструменты](./protocols/rest.md)
- [Секреты и профили авторизации](./secrets-and-auth.md) - [Секреты и профили авторизации](./secrets-and-auth.md)
- [Журналы и использование](./observability.md) - [Журналы и использование](./observability.md)
- [Проектирование MCP-инструментов](./tool-design.md)
## Справочник ## Справочник
- [Настройки окружения](./runtime-config.md) - [Настройки окружения](./runtime-config.md)
- [Admin API](./admin-api.md) - [Admin API](./admin-api.md)
- [Развертывание](./deployment.md) - [Развертывание](./deployment.md)
- [Production checklist](./production-checklist.md)
- [Troubleshooting](./troubleshooting.md)
- [Архитектура](./architecture.md) - [Архитектура](./architecture.md)
- [Модель данных](./data-model.md) - [Модель данных](./data-model.md)
- [Тестирование](./testing-strategy.md) - [Тестирование](./testing-strategy.md)
+159 -19
View File
@@ -1,6 +1,6 @@
# Admin API # Admin API
Admin API используется UI для управления Crank Community. Admin API используется веб-интерфейсом Crank. Его можно использовать и напрямую для автоматизации настройки.
Base path: Base path:
@@ -8,7 +8,33 @@ Base path:
/api/admin /api/admin
``` ```
## Auth Auth path:
```text
/api/auth
```
## Авторизация
Администратор входит по email и паролю. После входа сервер устанавливает HttpOnly session cookie.
```bash
curl -i https://crank.example.com/api/auth/login \
-H 'Content-Type: application/json' \
--data '{
"email": "owner@example.com",
"password": "change-me"
}'
```
Дальше используйте cookie из ответа:
```bash
curl https://crank.example.com/api/auth/session \
-b 'crank_session=<cookie_value>'
```
Endpoints:
- `POST /api/auth/login` - `POST /api/auth/login`
- `POST /api/auth/logout` - `POST /api/auth/logout`
@@ -17,30 +43,60 @@ Base path:
- `PATCH /api/auth/profile` - `PATCH /api/auth/profile`
- `POST /api/auth/password` - `POST /api/auth/password`
Авторизация основана на email/password и HttpOnly session cookie.
## Capabilities ## Capabilities
- `GET /api/admin/capabilities` ```bash
curl https://crank.example.com/api/admin/capabilities \
-b 'crank_session=<cookie_value>'
```
Community capabilities: Community capabilities:
- supported protocol: `rest` - protocol: `rest`;
- supported security level: `standard` - operation security level: `standard`;
- machine access mode: static agent key - machine access: static agent API keys.
## Workspaces ## Workspaces
Community работает с одним workspace.
- `GET /api/admin/workspaces` - `GET /api/admin/workspaces`
- `GET /api/admin/workspaces/{workspace_id}` - `GET /api/admin/workspaces/{workspace_id}`
- `PATCH /api/admin/workspaces/{workspace_id}` - `PATCH /api/admin/workspaces/{workspace_id}`
Community работает с одним bootstrap workspace. API не поддерживает создание Пример:
дополнительных workspace-ов, переключение текущего workspace-а, приглашения
пользователей и управление ролями. ```bash
curl https://crank.example.com/api/admin/workspaces \
-b 'crank_session=<cookie_value>'
```
## Upstreams
Upstream хранит базовый URL внешнего REST API и необязательные статические заголовки.
- `GET /api/admin/workspaces/{workspace_id}/upstreams`
- `POST /api/admin/workspaces/{workspace_id}/upstreams`
- `PATCH /api/admin/workspaces/{workspace_id}/upstreams/{upstream_id}`
Пример создания:
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/upstreams \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"name": "Frankfurter",
"base_url": "https://api.frankfurter.dev",
"static_headers": {},
"auth_profile_id": null
}'
```
## Operations ## Operations
Операция описывает один REST endpoint как MCP-инструмент.
- `GET /api/admin/workspaces/{workspace_id}/operations` - `GET /api/admin/workspaces/{workspace_id}/operations`
- `POST /api/admin/workspaces/{workspace_id}/operations` - `POST /api/admin/workspaces/{workspace_id}/operations`
- `POST /api/admin/workspaces/{workspace_id}/operations/analyze-quality` - `POST /api/admin/workspaces/{workspace_id}/operations/analyze-quality`
@@ -53,8 +109,33 @@ Community работает с одним bootstrap workspace. API не подд
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/archive` - `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/archive`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/test-runs` - `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/test-runs`
- `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/export` - `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/export`
- `POST /api/admin/workspaces/{workspace_id}/operations/import`
`analyze-quality` принимает такой же draft payload, как создание операции, и возвращает отчет: Пример тестового запуска:
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/operations/<operation_id>/test-runs \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"version": 1,
"input": {
"base": "USD",
"quote": "EUR"
}
}'
```
Пример публикации:
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/operations/<operation_id>/publish \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{ "version": 1 }'
```
`analyze-quality` принимает payload операции и возвращает рекомендации:
```json ```json
{ {
@@ -70,9 +151,6 @@ Community работает с одним bootstrap workspace. API не подд
] ]
} }
``` ```
- `POST /api/admin/workspaces/{workspace_id}/operations/import`
Community принимает только `protocol = rest`.
## Samples ## Samples
@@ -80,6 +158,8 @@ Community принимает только `protocol = rest`.
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/samples/output-json` - `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/samples/output-json`
- `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/drafts/generate` - `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/drafts/generate`
Samples используются для генерации схемы, стартового маппинга и сохранения тестовых примеров wizard-а.
## Secrets ## Secrets
- `GET /api/admin/workspaces/{workspace_id}/secrets` - `GET /api/admin/workspaces/{workspace_id}/secrets`
@@ -88,8 +168,20 @@ Community принимает только `protocol = rest`.
- `POST /api/admin/workspaces/{workspace_id}/secrets/{secret_id}/rotate` - `POST /api/admin/workspaces/{workspace_id}/secrets/{secret_id}/rotate`
- `DELETE /api/admin/workspaces/{workspace_id}/secrets/{secret_id}` - `DELETE /api/admin/workspaces/{workspace_id}/secrets/{secret_id}`
Create-response может вернуть plaintext secret только один раз. List/read endpoints Пример создания token secret:
возвращают только metadata.
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/secrets \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"name": "production-api-token",
"kind": "token",
"value": "secret-token-value"
}'
```
После создания или ротации API возвращает только metadata. Значение секрета нельзя прочитать повторно.
## Auth profiles ## Auth profiles
@@ -99,7 +191,7 @@ Create-response может вернуть plaintext secret только один
- `PATCH /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}` - `PATCH /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}`
- `DELETE /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}` - `DELETE /api/admin/workspaces/{workspace_id}/auth-profiles/{auth_profile_id}`
Auth profile хранит ссылки на secrets и способ применения credential к REST request. Auth profile хранит ссылки на secrets и способ применения секрета к REST-запросу.
## Agents ## Agents
@@ -116,6 +208,21 @@ Auth profile хранит ссылки на secrets и способ примен
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/bindings` - `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/bindings`
- `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}/bindings/{operation_id}` - `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}/bindings/{operation_id}`
Пример создания агента:
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/agents \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"slug": "currency-rates",
"display_name": "Курсы валют",
"description": "Агент с инструментами для получения курсов валют.",
"instructions": {},
"tool_selection_policy": {}
}'
```
## Agent API keys ## Agent API keys
- `GET /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys` - `GET /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys`
@@ -123,9 +230,42 @@ Auth profile хранит ссылки на secrets и способ примен
- `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys/{key_id}/revoke` - `POST /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys/{key_id}/revoke`
- `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys/{key_id}` - `DELETE /api/admin/workspaces/{workspace_id}/agents/{agent_id}/platform-api-keys/{key_id}`
Полное значение ключа доступно только в create-response. Пример создания ключа:
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/agents/<agent_id>/platform-api-keys \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"name": "Demo MCP client",
"scopes": ["read", "write"]
}'
```
Полное значение ключа доступно только в create response.
## Logs и usage ## Logs и usage
- `GET /api/admin/workspaces/{workspace_id}/logs` - `GET /api/admin/workspaces/{workspace_id}/logs`
- `GET /api/admin/workspaces/{workspace_id}/usage` - `GET /api/admin/workspaces/{workspace_id}/usage`
Пример:
```bash
curl 'https://crank.example.com/api/admin/workspaces/ws_default/logs?limit=20' \
-b 'crank_session=<cookie_value>'
```
## Ошибки
Admin API возвращает JSON-ошибки с человекочитаемым сообщением и контекстом, если он доступен.
Частые HTTP-коды:
- `400` - неверный payload;
- `401` - нет сессии;
- `403` - действие запрещено;
- `404` - сущность не найдена;
- `409` - конфликт состояния;
- `429` - rate limit;
- `500` - внутренняя ошибка.
+139
View File
@@ -0,0 +1,139 @@
# Практические API-примеры
Здесь собраны минимальные запросы для проверки Crank без веб-интерфейса.
В примерах используется:
```text
https://crank.example.com
```
Замените адрес на свой.
## Вход
```bash
curl -i https://crank.example.com/api/auth/login \
-H 'Content-Type: application/json' \
--data '{
"email": "owner@example.com",
"password": "change-me"
}'
```
Сохраните cookie `crank_session`.
## Получить workspace
```bash
curl https://crank.example.com/api/admin/workspaces \
-b 'crank_session=<cookie_value>'
```
Для стандартной установки workspace id:
```text
ws_default
```
## Получить операции
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/operations \
-b 'crank_session=<cookie_value>'
```
После demo seed ожидается операция:
```text
frankfurter_latest_rate
```
## Запустить тест операции
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/operations/<operation_id>/test-runs \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"version": 1,
"input": {
"base": "USD",
"quote": "EUR"
}
}'
```
## Получить агентов
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/agents \
-b 'crank_session=<cookie_value>'
```
После demo seed ожидается агент:
```text
currency-rates
```
## Создать API-ключ агента
```bash
curl https://crank.example.com/api/admin/workspaces/ws_default/agents/<agent_id>/platform-api-keys \
-b 'crank_session=<cookie_value>' \
-H 'Content-Type: application/json' \
--data '{
"name": "Manual MCP test",
"scopes": ["read", "write"]
}'
```
Сохраните поле `secret`. Оно не будет показано повторно.
## Проверить MCP initialize
```bash
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` из заголовков ответа.
## Вызвать инструмент
```bash
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/call",
"params": {
"name": "frankfurter_latest_rate",
"arguments": {
"base": "USD",
"quote": "EUR"
}
}
}'
```
+29 -37
View File
@@ -1,52 +1,44 @@
# Crank # Crank
Crank Community is a self-hosted platform for publishing REST APIs as MCP tools. Crank is a self-hosted platform for turning REST API endpoints into MCP tools.
It lets operators describe an upstream REST endpoint, test it, publish it, and The product provides a web UI for describing an upstream REST endpoint, testing it, publishing it as a tool, and exposing it to MCP clients through an agent-scoped endpoint.
expose it to LLM clients through MCP without writing a custom MCP server for
each integration.
## Features ## What Crank Does
- REST operation creation from the web UI or YAML. - Creates REST tools from the web UI or YAML.
- MCP input mapping into REST query, body, and header fields. - Maps MCP input into REST path, query, headers, or JSON body.
- REST response mapping into structured MCP tool output. - Maps REST responses into structured tool output.
- Agent-scoped MCP endpoints with curated tool catalogs. - Publishes selected tools through a specific agent.
- Operation drafts, versions, samples, mappings, logs, and usage in PostgreSQL. - Issues static API keys for MCP clients.
- Simple admin authentication with a bootstrap admin user. - Stores operations, versions, samples, secrets, logs, and usage in PostgreSQL.
- PostgreSQL-backed secrets and auth profiles for upstream REST APIs. - Runs with Docker Compose.
- Docker Compose deployment.
## Community Scope ## Community Scope
This repository contains only the Community feature set: This repository contains the Community version:
- REST protocol only. - one workspace;
- Single self-hosted deployment. - one admin user;
- Simple admin authentication. - unlimited agents;
- Static agent API keys for MCP access. - REST protocol;
- PostgreSQL as the system database. - MCP Streamable HTTP;
- Optional Valkey/Redis cache for runtime coordination. - static agent API keys;
- Gitea Actions CI/CD. - PostgreSQL database;
- optional Valkey or Redis for temporary coordination state.
The repository is focused only on the scope listed above. ## Documentation
## Architecture The main documentation is currently maintained in Russian:
Core concepts: - [Documentation index](../README.md)
- [Introduction](../intro.md)
- `Workspace` is the data boundary for operations, agents, secrets, and logs. - [Installation](../installation.md)
- `Operation` is a versioned REST integration contract. - [Quickstart](../quickstart.md)
- `Agent` is an MCP surface that exposes a curated set of operations. - [MCP interface](../mcp-interface.md)
- [Admin API](../admin-api.md)
Runtime flow: - [Runtime configuration](../runtime-config.md)
- [Troubleshooting](../troubleshooting.md)
1. An operator creates or imports a REST operation.
2. Crank validates the schema and mapping.
3. The operator runs a test call against the upstream REST API.
4. The operation is published.
5. An agent exposes the published operation as an MCP tool.
6. MCP clients call the tool through `mcp-server`.
## License ## License
+3
View File
@@ -75,3 +75,6 @@ docker compose pull
docker compose up -d docker compose up -d
``` ```
## Следующий шаг
После установки пройдите [первый инструмент](./quickstart.md). Если что-то не запускается, используйте [troubleshooting](./troubleshooting.md).
+146 -75
View File
@@ -1,106 +1,177 @@
# MCP Interface # MCP-интерфейс
Crank Community публикует REST operations как MCP tools поверх Streamable HTTP. Crank публикует REST-операции как MCP-инструменты через Streamable HTTP.
## Transport ## Endpoint агента
MCP server запускается отдельным приложением `mcp-server`. Каждый агент имеет собственный MCP endpoint:
Поддерживается:
- MCP Streamable HTTP;
- JSON-RPC requests через `POST`;
- optional server-to-client stream через `GET`;
- explicit session close через `DELETE`.
`stdio` не входит в Community deployment.
## Endpoint model
Canonical endpoint:
```text ```text
/mcp/v1/{workspace_slug}/{agent_slug} /mcp/v1/{workspace_slug}/{agent_slug}
``` ```
Endpoint определяет: Для demo seed:
- workspace; ```text
- published agent; /mcp/v1/default/currency-rates
- curated tool catalog агента; ```
- labels для logs и usage.
## Authentication Полный URL зависит от вашего домена:
Community использует static agent API keys. ```text
https://crank.example.com/mcp/v1/default/currency-rates
```
Правила: ## Авторизация
- каждый published agent может иметь собственные API keys; MCP-клиент должен передавать API-ключ агента:
- key принадлежит одному workspace и одному agent;
- `mcp-server` показывает только tools, привязанные к этому agent;
- unsupported token issuance modes отклоняются.
## Tool catalog ```http
Authorization: Bearer <agent_api_key>
```
Одна published REST operation становится одним MCP tool. Ключ выдается в разделе **API ключи**. Полное значение показывается только один раз при создании.
Tool definition строится из: ## Поддерживаемые методы
- operation name или binding-level tool name;
- tool title и description;
- input schema;
- published operation version.
Draft operations никогда не публикуются через MCP.
## Supported methods
MCP methods: MCP methods:
- `initialize` - `initialize`;
- `notifications/initialized` - `notifications/initialized`;
- `ping` - `ping`;
- `tools/list` - `tools/list`;
- `tools/call` - `tools/call`.
Transport endpoints: HTTP transport:
- `POST /mcp/v1/{workspace_slug}/{agent_slug}` - `POST /mcp/v1/{workspace_slug}/{agent_slug}` - JSON-RPC запросы;
- `GET /mcp/v1/{workspace_slug}/{agent_slug}` - `GET /mcp/v1/{workspace_slug}/{agent_slug}` - server-to-client stream;
- `DELETE /mcp/v1/{workspace_slug}/{agent_slug}` - `DELETE /mcp/v1/{workspace_slug}/{agent_slug}` - закрытие сессии.
## `tools/list` ## Обязательные заголовки
1. Client authenticates через agent API key. Для `POST`:
2. `mcp-server` resolves workspace и agent из path.
3. Server loads published agent catalog.
4. Server returns only tools bound to that agent.
## `tools/call` ```http
Authorization: Bearer <agent_api_key>
Content-Type: application/json
Accept: application/json, text/event-stream
```
1. Client вызывает tool. Для `GET`:
2. `mcp-server` валидирует input по tool schema.
3. Runtime maps MCP input в REST request.
4. REST adapter вызывает upstream API.
5. Runtime maps REST response в tool output.
6. `mcp-server` возвращает normalized result.
## Refresh ```http
Authorization: Bearer <agent_api_key>
Accept: text/event-stream
MCP-Session-Id: <session_id>
```
Published catalog refresh управляется `CRANK_MCP_REFRESH_MS`. После `initialize` сервер возвращает заголовок:
После публикации operation или agent `mcp-server` подхватывает новый catalog без ```http
restart. MCP-Session-Id: <session_id>
```
## Error categories Если клиент передает `MCP-Protocol-Version`, он должен совпадать с версией, согласованной при инициализации.
MCP responses различают: ## Пример `initialize`
- authentication errors; ```bash
- missing workspace или agent; curl -i https://crank.example.com/mcp/v1/default/currency-rates \
- missing tool; -H 'Authorization: Bearer <agent_api_key>' \
- schema validation errors; -H 'Content-Type: application/json' \
- mapping errors; -H 'Accept: application/json, text/event-stream' \
- upstream REST errors; --data '{
- internal runtime errors. "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 <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 содержит инструмент:
```text
frankfurter_latest_rate
```
## Пример `tools/call`
```bash
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-запрос:
```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`.
+45
View File
@@ -0,0 +1,45 @@
# Production checklist
Этот список помогает подготовить Crank к постоянной работе на сервере.
## Перед запуском
- Сгенерирован сильный `CRANK_MASTER_KEY`.
- Сгенерирован сильный `CRANK_SESSION_SECRET`.
- Сгенерирован сильный `CRANK_PASSWORD_PEPPER`.
- Задан надежный `CRANK_BOOTSTRAP_ADMIN_PASSWORD`.
- `CRANK_BASE_URL` указывает на публичный HTTPS URL.
- PostgreSQL доступен с host, где запускаются контейнеры.
- Для PostgreSQL настроены бэкапы.
- Reverse proxy проксирует `/`, `/api/admin/` и `/mcp/`.
- Для `/mcp/` отключено proxy buffering.
- Порты опубликованы только там, где нужно: `127.0.0.1` или `0.0.0.0`.
## После запуска
- `curl /health` для `admin-api` возвращает `ok`.
- `curl /health` для `mcp-server` возвращает `ok`.
- UI открывается по публичному домену.
- Вход под bootstrap admin работает.
- Demo seed создал Frankfurter-пример, если `CRANK_DEMO_SEED=true`.
- Тест операции `frankfurter_latest_rate` проходит.
- MCP-клиент видит инструмент через агента `currency-rates`.
## Безопасность
- Не храните `.env` в Git.
- Не передавайте API-ключи агентов в чатах и тикетах.
- Выдавайте отдельный ключ на каждого MCP-клиента.
- Удаляйте или отзывайте ключи, которые больше не используются.
- Используйте secrets/auth profiles для токенов внешних API.
- Не вставляйте реальные токены в статические заголовки операции.
## Эксплуатация
- Включите мониторинг контейнеров.
- Следите за свободным местом на диске.
- Проверяйте размер PostgreSQL и директории artifact storage.
- Храните бэкапы PostgreSQL отдельно от application host.
- Перед обновлением фиксируйте текущие image tags.
- После обновления проверяйте UI, Admin API и MCP endpoint.
+1
View File
@@ -79,3 +79,4 @@ https://your-crank-host/mcp/v1/default/currency-rates
Клиент должен передавать API-ключ агента в заголовке авторизации. Клиент должен передавать API-ключ агента в заголовке авторизации.
Подробные HTTP-примеры для `initialize`, `tools/list` и `tools/call` находятся в [MCP-интерфейсе](./mcp-interface.md) и [практических API-примерах](./api-examples.md).
+2 -2
View File
@@ -9,7 +9,7 @@
- проверять доменную модель отдельно от транспорта; - проверять доменную модель отдельно от транспорта;
- ловить регрессии в mapping; - ловить регрессии в mapping;
- не дать адаптерам начать вести себя по-разному; - не дать адаптерам начать вести себя по-разному;
- обеспечить воспроизводимость для дипломной демонстрации. - обеспечить воспроизводимость для демонстрации и регрессионных проверок.
## 2. Уровни тестов ## 2. Уровни тестов
@@ -101,7 +101,7 @@
- unit tests для form helpers и schema rendering; - unit tests для form helpers и schema rendering;
- integration tests для critical user flows; - integration tests для critical user flows;
- отдельная проверка mapping editor и sample upload flows. - отдельная проверка mapping editor и sample upload flows.
- отдельный regression checklist для post-integration smoke pass: [manual-regression-checklist.md](/home/a.tolmachev/code/rust/mcpaas/docs/manual-regression-checklist.md). - отдельный regression checklist для post-integration smoke pass: [manual-regression-checklist.md](manual-regression-checklist.md).
## 6. Что нельзя оставлять без тестов ## 6. Что нельзя оставлять без тестов
+148
View File
@@ -0,0 +1,148 @@
# Troubleshooting
Этот документ помогает быстро проверить типовые проблемы при запуске и работе Crank.
## Веб-интерфейс открывается, но данные не загружаются
Проверьте `admin-api`:
```bash
curl http://127.0.0.1:3001/health
docker compose logs -f admin-api
```
Типовые причины:
- `admin-api` не подключился к PostgreSQL;
- неверные `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_USER`, `POSTGRES_PASSWORD`;
- reverse proxy не проксирует `/api/admin/`;
- браузерная сессия истекла.
## `502 Bad Gateway` через nginx
Проверьте, на каком адресе опубликованы контейнеры:
```bash
docker compose ps
```
Если nginx работает на другом host, в `.env` нужно:
```env
CRANK_PUBLISH_BIND=0.0.0.0
```
Если nginx работает на том же host, обычно достаточно:
```env
CRANK_PUBLISH_BIND=127.0.0.1
```
## MCP-клиент получает `401 Unauthorized`
Проверьте:
- API-ключ создан именно для нужного агента;
- ключ передается как `Authorization: Bearer <key>`;
- ключ не был удален или отозван;
- MCP URL содержит правильные `workspace_slug` и `agent_slug`.
## MCP-клиент не видит инструмент
Проверьте:
- операция опубликована;
- операция привязана к агенту;
- агент опубликован;
- ключ выдан на этого агента;
- прошел интервал `CRANK_MCP_REFRESH_MS`.
Для demo seed ожидаемый инструмент:
```text
frankfurter_latest_rate
```
## Тест операции возвращает ошибку внешнего API
Откройте preview запроса в wizard-е и проверьте:
- `base_url`;
- `path_template`;
- HTTP method;
- query/path/body mapping;
- auth profile;
- статические заголовки.
Для Frankfurter рабочий запрос:
```text
GET https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR
```
## Секрет не виден после создания
Это ожидаемое поведение. Crank шифрует секрет и больше не возвращает его значение через UI или API.
Если значение нужно заменить, используйте **Ротировать**.
## После обновления не появился demo-пример
Проверьте:
```env
CRANK_DEMO_SEED=true
```
Затем перезапустите `admin-api`:
```bash
docker compose up -d admin-api
```
Seed идемпотентный: он не создает дубликаты, но поддерживает Frankfurter-пример.
## Контейнеры не стартуют из-за занятых портов
Проверьте, кто занимает порт:
```bash
docker ps --format 'table {{.Names}}\t{{.Ports}}'
sudo ss -ltnp
```
Чаще всего конфликтуют:
- `3000` - UI;
- `3001` - Admin API;
- `3002` - MCP server;
- `5432` - PostgreSQL, если включен profile `local-db`.
## PostgreSQL недоступен
Проверьте доступность из контейнера:
```bash
docker compose exec admin-api sh -lc 'nc -vz "$POSTGRES_HOST" "$POSTGRES_PORT"'
```
Проверьте переменные:
```bash
docker compose exec admin-api env | grep POSTGRES
```
## Где смотреть логи
```bash
docker compose logs -f admin-api
docker compose logs -f mcp-server
docker compose logs -f ui
```
Для подробных логов временно укажите:
```env
CRANK_LOG_LEVEL=debug
```