Refresh community demo and docs
Deploy / deploy (push) Successful in 1m42s
CI / Rust Checks (push) Successful in 6m9s
CI / UI Checks (push) Successful in 5s
CI / Deployment Manifests (push) Successful in 2s
CI / Frontend E2E (push) Successful in 4m42s

This commit is contained in:
github-ops
2026-06-21 11:20:12 +00:00
parent cab9282c50
commit c77065756d
24 changed files with 688 additions and 807 deletions
+29
View File
@@ -0,0 +1,29 @@
# Документация Crank
Crank превращает REST API endpoint-ы в MCP-инструменты, которые можно подключать к AI-агентам и MCP-клиентам.
Эта документация подготовлена как основа для будущего сайта. Сейчас файлы лежат в `docs/`, позже их можно перенести в Docusaurus без изменения структуры тем.
## Начать
- [Введение](./intro.md)
- [Установка](./installation.md)
- [Первый инструмент](./quickstart.md)
- [Подключение MCP-клиента](./mcp-interface.md)
## Возможности
- [Веб-интерфейс](./ui.md)
- [REST-инструменты](./protocols/rest.md)
- [Секреты и профили авторизации](./secrets-and-auth.md)
- [Журналы и использование](./observability.md)
## Справочник
- [Настройки окружения](./runtime-config.md)
- [Admin API](./admin-api.md)
- [Развертывание](./deployment.md)
- [Архитектура](./architecture.md)
- [Модель данных](./data-model.md)
- [Тестирование](./testing-strategy.md)
+39 -47
View File
@@ -1,17 +1,16 @@
# Deployment
# Развертывание
Документ описывает поддерживаемый путь деплоя Crank Community.
Документ описывает поддерживаемый путь запуска Crank на сервере.
Crank Community запускается как три application containers за reverse proxy:
Crank запускается как три контейнера за reverse proxy:
- `ui`
- `admin-api`
- `mcp-server`
Приложение использует внешний PostgreSQL. Compose manifest не поднимает
PostgreSQL самостоятельно.
Можно использовать внешний PostgreSQL или локальный PostgreSQL из compose-профиля `local-db`.
## Runtime topology
## Схема
```text
reverse proxy
@@ -21,28 +20,27 @@ reverse proxy
admin-api -> PostgreSQL
mcp-server -> PostgreSQL
admin-api -> optional Valkey/Redis
mcp-server -> optional Valkey/Redis
admin-api -> Valkey/Redis, опционально
mcp-server -> Valkey/Redis, опционально
```
## Deployment files
## Файлы запуска
- `deploy/community/docker-compose.yml`
- `deploy/community/.env.example`
- `.gitea/workflows/ci.yml`
- `.gitea/workflows/deploy.yml`
- `.gitea/workflows/release.yml`
- `deploy/community/docker-compose.images.yml`
- `deploy/community/.env.images.example`
## Порты
Default service ports:
Порты по умолчанию:
- `ui`: `3000`
- `admin-api`: `3001`
- `mcp-server`: `3002`
- optional `valkey`: `6379`, только loopback
`CRANK_PUBLISH_BIND` управляет публикацией application ports:
`CRANK_PUBLISH_BIND` управляет публикацией портов:
- `127.0.0.1`, если reverse proxy работает на том же host;
- `0.0.0.0`, если reverse proxy работает на другом host.
@@ -94,9 +92,9 @@ server {
Замените `192.168.1.106` на адрес deployment host.
## Compose
## Запуск из исходников
Проверка manifest:
Проверка compose-файла:
```bash
docker compose \
@@ -105,7 +103,7 @@ docker compose \
config -q
```
Запуск без внешнего cache:
Запуск с внешним PostgreSQL:
```bash
docker compose \
@@ -132,7 +130,24 @@ CRANK_CACHE_URL=redis://valkey:6379/0
CRANK_CACHE_DEFAULT_TTL_MS=60000
```
## Health checks
## Запуск готовых образов
```bash
mkdir -p crank
cd crank
curl -fsSLo docker-compose.yml https://git.itexp.me/bsodfather/crank/raw/branch/main/deploy/community/docker-compose.images.yml
curl -fsSLo .env.example https://git.itexp.me/bsodfather/crank/raw/branch/main/deploy/community/.env.images.example
cp .env.example .env
docker compose --profile local-db up -d
```
Если используется внешний PostgreSQL, заполните `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD` и запустите:
```bash
docker compose up -d
```
## Проверка состояния
```bash
curl http://127.0.0.1:3001/health
@@ -146,38 +161,15 @@ curl http://127.0.0.1:3002/health
{"service":"mcp-server","status":"ok"}
```
UI root должен возвращать `200 OK`:
UI должен возвращать `200 OK`:
```bash
curl -I http://127.0.0.1:3000/
```
## Gitea CI/CD
## Эксплуатация
Репозиторий использует Gitea Actions:
- `.gitea/workflows/ci.yml` запускает Rust, UI, E2E и deployment manifest checks.
- `.gitea/workflows/deploy.yml` собирает images и деплоит `main`.
- `.gitea/workflows/release.yml` собирает release artifacts для tags.
Deploy workflow читает из Gitea secrets только OpenBao bootstrap credentials:
- `BAO_ADDR`
- `BAO_ROLE_ID`
- `BAO_SECRET_ID`
Дальше workflow читает KV v2 secrets из OpenBao:
```text
ci/shared/registry
ci/shared/deploy-ssh
ci/projects/crank/deploy
ci/projects/crank/runtime
```
## Operational notes
- Бэкапы БД должны жить вне application host.
- Runtime secrets хранятся в OpenBao, не в Git.
- Для rollback используйте immutable image tags.
- `CRANK_PUBLISH_BIND=0.0.0.0` нужен только если другой host должен обращаться к published ports напрямую.
- Делайте регулярные бэкапы PostgreSQL.
- Не храните реальные секреты в Git.
- Для rollback используйте конкретные image tags, а не только `main`.
- `CRANK_PUBLISH_BIND=0.0.0.0` нужен только если reverse proxy работает на другом host.
+77
View File
@@ -0,0 +1,77 @@
# Установка
Самый простой способ запустить Crank - использовать готовые Docker-образы и `docker compose`.
## Требования
- Docker;
- Docker Compose;
- PostgreSQL или локальный compose-профиль `local-db`;
- свободные порты `3000`, `3001`, `3002`.
## Быстрый запуск
```bash
mkdir -p crank
cd crank
curl -fsSLo docker-compose.yml https://git.itexp.me/bsodfather/crank/raw/branch/main/deploy/community/docker-compose.images.yml
curl -fsSLo .env.example https://git.itexp.me/bsodfather/crank/raw/branch/main/deploy/community/.env.images.example
cp .env.example .env
```
Откройте `.env` и замените значения:
- `POSTGRES_PASSWORD`;
- `CRANK_MASTER_KEY`;
- `CRANK_SESSION_SECRET`;
- `CRANK_PASSWORD_PEPPER`;
- `CRANK_BOOTSTRAP_ADMIN_EMAIL`;
- `CRANK_BOOTSTRAP_ADMIN_PASSWORD`;
- `CRANK_BASE_URL`.
Секреты можно сгенерировать командой:
```bash
openssl rand -hex 32
```
Запуск с локальным PostgreSQL из compose:
```bash
docker compose --profile local-db up -d
```
Если PostgreSQL уже есть отдельно, укажите его в `.env` и запустите без профиля:
```bash
docker compose up -d
```
## Проверка
```bash
docker compose ps
curl http://127.0.0.1:3001/health
curl http://127.0.0.1:3002/health
```
После запуска откройте веб-интерфейс:
```text
http://localhost:3000
```
## Обновление
```bash
docker compose --profile local-db pull
docker compose --profile local-db up -d
```
Если используете внешний PostgreSQL:
```bash
docker compose pull
docker compose up -d
```
+50
View File
@@ -0,0 +1,50 @@
# Что такое Crank
Crank - это свободная платформа для создания MCP-инструментов из REST API endpoint-ов.
Обычный REST API удобен для программ, но не всегда удобен для AI-агента. Агенту нужен понятный каталог инструментов: название, описание, входные параметры, ожидаемый результат и стабильный способ вызова. Crank берет существующий REST endpoint и описывает его как MCP-инструмент.
## Что можно сделать
- Описать REST endpoint через веб-интерфейс.
- Проверить запрос перед публикацией.
- Опубликовать инструмент в каталоге конкретного агента.
- Выдать API-ключ для MCP-клиента.
- Смотреть журнал вызовов и статистику использования.
- Хранить секреты для внешних API без отображения значения после сохранения.
## Как это работает
```text
MCP-клиент
-> Crank MCP server
-> опубликованный агент
-> выбранный MCP-инструмент
-> REST API
```
В Crank агент - это отдельный MCP endpoint со своим набором инструментов и своими API-ключами. MCP-клиент, подключенный к одному агенту, видит только инструменты этого агента.
## Что входит в Community
- один workspace;
- один пользователь администратора;
- любое количество агентов;
- REST-инструменты;
- MCP Streamable HTTP;
- статические API-ключи агентов;
- PostgreSQL как основное хранилище;
- опциональный Valkey или Redis для служебного кэша.
## Демо при первом запуске
В примерах окружения включен `CRANK_DEMO_SEED=true`. После первого запуска Crank создает:
- upstream `Frankfurter`;
- операцию `frankfurter_latest_rate`;
- агента `currency-rates`;
- API-ключ агента;
- пример записи в журнале вызовов.
Демо можно отключить, указав `CRANK_DEMO_SEED=false`.
+1 -1
View File
@@ -158,7 +158,7 @@ cd apps/ui && npm run e2e
Обязательный кейс:
- REST: [rest-open-meteo.operation.json](../examples/mcp-smoke/rest-open-meteo.operation.json)
- REST: [Frankfurter examples](../examples/frankfurter/README.md)
## 7. Acceptance criteria
+34
View File
@@ -0,0 +1,34 @@
# Журналы и использование
Crank сохраняет данные о тестовых запусках и вызовах опубликованных MCP-инструментов.
## Журналы
В журнал попадают:
- операция;
- агент, если вызов пришел через MCP;
- request id;
- статус;
- HTTP status code внешнего API;
- время выполнения;
- краткий preview запроса и ответа;
- категория ошибки, если вызов завершился ошибкой.
## Использование
Раздел использования агрегирует:
- количество вызовов;
- успешные и ошибочные вызовы;
- долю ошибок;
- задержки p50, p95 и p99;
- распределение вызовов по операциям.
## Для чего это нужно
- проверить, вызывают ли агенты нужные инструменты;
- увидеть ошибки маппинга или внешнего API;
- найти медленные endpoint-ы;
- понять, какие инструменты реально используются.
+15 -82
View File
@@ -1,99 +1,32 @@
# Public Smoke Targets
# Публичный тестовый API
Этот документ фиксирует публичный upstream-сервис, который можно использовать для ручной проверки `REST` operation в `crank-community` без поднятия своего тестового backend-а.
Для демонстрации и ручных проверок Crank использует Frankfurter.
Для Community канонический smoke target только один:
Frankfurter - публичный API курсов валют без ключа доступа.
- `REST`
Все примеры ниже дублируются готовыми payload-файлами в [examples/mcp-smoke](../examples/mcp-smoke).
## 1. Источник
- REST: Open-Meteo Weather Forecast API
`https://open-meteo.com/en/docs`
## 2. Готовые operation payload-ы
- REST: [rest-open-meteo.operation.json](../examples/mcp-smoke/rest-open-meteo.operation.json)
- REST test input: [rest-open-meteo.test-input.json](../examples/mcp-smoke/rest-open-meteo.test-input.json)
## 3. Как использовать
### 3.1. Через UI
1. Создать operation вручную в `Wizard`.
2. Подставить значения из `rest-open-meteo.operation.json`.
3. На шаге теста использовать `rest-open-meteo.test-input.json`.
### 3.2. Через admin-api
Пример для `ws_default`:
```bash
curl -sS -X POST \
https://rmcp.itexp.me/api/admin/workspaces/ws_default/operations \
-H 'content-type: application/json' \
-b cookie.txt \
--data @examples/mcp-smoke/rest-open-meteo.operation.json
```text
https://api.frankfurter.dev
```
Потом test-run:
Рабочий пример:
```bash
curl -sS -X POST \
https://rmcp.itexp.me/api/admin/workspaces/ws_default/operations/<operation_id>/test-runs \
-H 'content-type: application/json' \
-b cookie.txt \
--data '{
"version": 1,
"input": '"$(cat examples/mcp-smoke/rest-open-meteo.test-input.json)"'
}'
curl 'https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR'
```
Логин перед этим:
```bash
curl -sS -c cookie.txt \
-H 'content-type: application/json' \
-X POST https://rmcp.itexp.me/api/auth/login \
--data '{"email":"<your-email>","password":"<your-password>"}'
```
## 4. Что именно проверяет пример
### 4.1. REST: Open-Meteo
- Protocol: `REST`
- Endpoint: `https://api.open-meteo.com/v1/forecast`
- Проверка:
- query mapping
- fixed query defaults
- JSON response extraction
Ожидаемый upstream response shape:
Ожидаемый ответ:
```json
{
"timezone": "Europe/Moscow",
"current": {
"time": "2026-04-05T22:30",
"temperature_2m": 3.4,
"wind_speed_10m": 8.3
"amount": 1.0,
"base": "USD",
"date": "2026-06-19",
"rates": {
"EUR": 0.87207
}
}
```
## 5. Практическая рекомендация
Готовые YAML-примеры лежат в папке [`examples/frankfurter`](../examples/frankfurter/README.md).
Для первого smoke pass использовать operation:
- `weather_current_open_meteo`
Этого достаточно, чтобы проверить весь путь:
- create operation
- test-run
- publish
- bind to agent
- MCP call через `workspace + agent`
Основной demo seed создает операцию `frankfurter_latest_rate` и агента `currency-rates`.
+81
View File
@@ -0,0 +1,81 @@
# Первый инструмент
После установки в Crank уже есть демо-пример Frankfurter. Он показывает полный путь от REST endpoint-а до MCP-инструмента.
## 1. Откройте операции
Перейдите в раздел **Операции**. В списке должна быть операция:
```text
frankfurter_latest_rate
```
Она вызывает публичный API:
```text
GET https://api.frankfurter.dev/v1/latest
```
Входные параметры:
```json
{
"base": "USD",
"quote": "EUR"
}
```
Crank преобразует их в query-параметры:
```text
base=USD&symbols=EUR
```
## 2. Проверьте операцию
Откройте операцию и перейдите к тестированию. Используйте пример:
```json
{
"base": "USD",
"quote": "EUR"
}
```
Успешный ответ Frankfurter выглядит так:
```json
{
"amount": 1.0,
"base": "USD",
"date": "2026-06-19",
"rates": {
"EUR": 0.87207
}
}
```
## 3. Откройте агента
Перейдите в раздел **Агенты**. Демо создает агента:
```text
currency-rates
```
Этот агент публикует только инструмент `frankfurter_latest_rate`.
## 4. Создайте API-ключ
Перейдите в раздел **API ключи**, выберите агента `currency-rates` и создайте ключ. Полное значение ключа показывается только один раз.
## 5. Подключите MCP-клиент
MCP endpoint агента имеет вид:
```text
https://your-crank-host/mcp/v1/default/currency-rates
```
Клиент должен передавать API-ключ агента в заголовке авторизации.
+90 -289
View File
@@ -1,313 +1,114 @@
# Runtime Config
# Настройки окружения
## 1. Назначение документа
Crank настраивается через переменные окружения. Один и тот же набор переменных используется при запуске из исходников и при запуске готовых Docker-образов.
Этот документ фиксирует конфигурацию окружения, storage и базовые operational assumptions для MVP.
## PostgreSQL
Его задача - убрать неявные решения, которые обычно всплывают уже в процессе написания кода.
## 2. Базовые решения для MVP
- каноническая БД: `PostgreSQL`
- локальная разработка и тесты используют ту же `PostgreSQL`-модель хранения
- artifact storage: локальная файловая система
- MCP transport: `Streamable HTTP`
- admin API и mcp-server запускаются как отдельные приложения
## 3. Artifact storage
В MVP sample JSON, `.proto`, `descriptor set` и YAML import payload должны храниться в локальном файловом storage.
Требования:
- все файлы кладутся в контролируемый базовый каталог;
- в БД хранится только `storage_ref`;
- структура каталогов должна быть детерминированной;
- storage слой должен быть абстрагирован, чтобы потом заменить его на S3-compatible backend.
Рекомендуемая структура:
```text
var/crank/
samples/
descriptors/
yaml-imports/
```
## 4. Секреты и auth profiles
Для целевой модели:
- operation хранит только `auth_profile_ref`;
- `AuthProfile` хранит только ссылки на `secret_id`;
- plaintext секреты не должны попадать в YAML export;
- plaintext секреты не должны логироваться;
- runtime получает секрет только на короткое время перед upstream вызовом.
Стартовая реализация:
- `PostgreSQL`-backed secret store;
- `ciphertext` хранится в БД;
- шифрование выполняется через `CRANK_MASTER_KEY`;
- ключ шифрования приходит только из env.
## 5. Переменные окружения
Минимально ожидаются:
Обязательные параметры:
- `POSTGRES_HOST`
- `POSTGRES_PORT`
- `POSTGRES_DB`
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `POSTGRES_MAX_CONNECTIONS`
- `POSTGRES_MIN_CONNECTIONS`
- `POSTGRES_ACQUIRE_TIMEOUT_MS`
- `POSTGRES_IDLE_TIMEOUT_MS`
- `POSTGRES_MAX_LIFETIME_MS`
- `CRANK_ADMIN_API_IMAGE`
- `CRANK_MCP_SERVER_IMAGE`
- `CRANK_UI_IMAGE`
- `CRANK_STORAGE_ROOT`
- `CRANK_PUBLISH_BIND`
- `CRANK_ADMIN_BIND`
- `CRANK_ADMIN_RATE_LIMIT_RPS`
- `CRANK_ADMIN_RATE_LIMIT_BURST`
- `CRANK_MCP_BIND`
- `CRANK_MCP_REFRESH_MS`
- `CRANK_MCP_RATE_LIMIT_RPS`
- `CRANK_MCP_RATE_LIMIT_BURST`
Параметры пула соединений:
- `POSTGRES_MAX_CONNECTIONS`, по умолчанию `20`;
- `POSTGRES_MIN_CONNECTIONS`, по умолчанию `2`;
- `POSTGRES_ACQUIRE_TIMEOUT_MS`, по умолчанию `5000`;
- `POSTGRES_IDLE_TIMEOUT_MS`, по умолчанию `600000`;
- `POSTGRES_MAX_LIFETIME_MS`, по умолчанию `1800000`.
Если используется PgBouncer, укажите его адрес в `POSTGRES_HOST` и порт в `POSTGRES_PORT`.
## HTTP-сервисы
- `CRANK_ADMIN_BIND` - адрес `admin-api`, например `0.0.0.0:3001`.
- `CRANK_MCP_BIND` - адрес `mcp-server`, например `0.0.0.0:3002`.
- `CRANK_PUBLISH_BIND` - адрес публикации портов в Docker Compose.
- `CRANK_BASE_URL` - публичный URL веб-интерфейса.
Для сервера за reverse proxy обычно подходит:
```env
CRANK_PUBLISH_BIND=127.0.0.1
```
Если reverse proxy работает на другом host:
```env
CRANK_PUBLISH_BIND=0.0.0.0
```
## Авторизация администратора
- `CRANK_SESSION_SECRET` - ключ подписи браузерных сессий.
- `CRANK_PASSWORD_PEPPER` - дополнительный секрет для хэширования паролей.
- `CRANK_SESSION_TTL_HOURS` - срок жизни сессии в часах.
- `CRANK_BOOTSTRAP_ADMIN_EMAIL` - email первого пользователя.
- `CRANK_BOOTSTRAP_ADMIN_PASSWORD` - пароль первого пользователя.
- `CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME` - отображаемое имя первого пользователя.
Первый пользователь создается или обновляется при старте `admin-api`.
## Шифрование секретов
- `CRANK_MASTER_KEY` - ключ шифрования сохраненных секретов.
Этот ключ нужен `admin-api` и `mcp-server`. Если изменить ключ без миграции данных, ранее сохраненные секреты нельзя будет расшифровать.
## Демо-данные
- `CRANK_DEMO_SEED=true` создает пример Frankfurter при старте.
- `CRANK_DEMO_SEED=false` отключает demo seed.
Demo seed идемпотентный: повторный старт не создает дубликаты. В стандартном примере создаются upstream `Frankfurter`, операция `frankfurter_latest_rate`, агент `currency-rates` и пример API-ключа.
## MCP
- `CRANK_MCP_REFRESH_MS` - как часто `mcp-server` обновляет опубликованный каталог инструментов.
- `CRANK_MCP_RATE_LIMIT_RPS` - лимит запросов в секунду.
- `CRANK_MCP_RATE_LIMIT_BURST` - допустимый короткий всплеск запросов.
## Admin API
- `CRANK_ADMIN_RATE_LIMIT_RPS` - лимит запросов в секунду.
- `CRANK_ADMIN_RATE_LIMIT_BURST` - допустимый короткий всплеск запросов.
## Runtime limits
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY`
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW`
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS`
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS`
- `CRANK_LOG_LEVEL`
- `CRANK_MASTER_KEY`
- `CRANK_BASE_URL`
Опционально:
Эти настройки ограничивают параллельное выполнение операций и служебных задач.
- `CRANK_ADMIN_TOKEN`
- `CRANK_DEMO_SEED`
- `CRANK_CACHE_BACKEND`
- `CRANK_CACHE_URL`
- `CRANK_CACHE_DEFAULT_TTL_MS`
## Кэш
Стартовое значение для refresh published tools:
По умолчанию Crank работает без внешнего кэша:
- `CRANK_ADMIN_RATE_LIMIT_RPS=30`
- `CRANK_ADMIN_RATE_LIMIT_BURST=60`
- `CRANK_MCP_REFRESH_MS=5000`
- `CRANK_MCP_RATE_LIMIT_RPS=60`
- `CRANK_MCP_RATE_LIMIT_BURST=120`
```env
CRANK_CACHE_BACKEND=memory
```
Стартовые значения для runtime concurrency limits:
Для Valkey или Redis:
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY=64`
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS=16`
```env
CRANK_CACHE_BACKEND=valkey
CRANK_CACHE_URL=redis://valkey:6379/0
CRANK_CACHE_DEFAULT_TTL_MS=60000
```
## 6. Логирование и трассировка
Внешний кэш используется для служебного краткоживущего состояния: rate limiting, replay guard и опубликованные каталоги MCP-инструментов.
Для MVP нужно использовать:
## Логи
- structured logging через `tracing`;
- correlation id для test runs и runtime execution;
- раздельные стадии ошибок: schema, mapping, adapter, external service.
- `CRANK_LOG_LEVEL` - уровень логирования, например `info`, `debug`, `warn`.
## 7. Таймауты и retries
Пример:
Рекомендуемые стартовые значения:
- default timeout: `10s`
- retry default: `1` attempt, то есть без автоматического повтора
Причина:
- сначала важнее детерминированность и прозрачность;
- aggressive retries могут маскировать реальные ошибки интеграции.
## 8. Режимы запуска
Минимально нужны два режима:
- local development
- demo/deployment
Local development:
- локальное окружение должно иметь доступ к `PostgreSQL`;
- локальный storage;
- app-level auth и bootstrap admin user через `.env`.
- при необходимости UI можно наполнить живыми demo-данными через `CRANK_DEMO_SEED=true`.
Demo/deployment:
- `PostgreSQL`;
- локальный или сетевой storage;
- включенная app-level auth-защита admin-api;
- стабильный `Streamable HTTP` endpoint для MCP.
- containerized runtime через `Docker` и `docker-compose`.
- optional shared cache layer через `Valkey/Redis`.
- registry-backed image rollout через Gitea Container Registry или совместимый registry.
### Cache env
Для optional cache/coordination layer должны быть предусмотрены:
- `CRANK_CACHE_BACKEND`
- `CRANK_CACHE_URL`
- `CRANK_CACHE_DEFAULT_TTL_MS`
Рекомендуемая модель:
- `CRANK_CACHE_BACKEND=memory` по умолчанию;
- `CRANK_CACHE_BACKEND=valkey` или `redis` при наличии внешнего cache store;
- без этих переменных система должна оставаться полностью работоспособной.
### Cache boundaries
В платформе должны существовать два разных cache-контура:
- `platform / coordination cache`
- `response cache`
Первый контур хранит служебное краткоживущее состояние:
- ingress rate limiting;
- replay guard;
- ephemeral coordination state;
- shared snapshots published MCP catalogs between instances;
Второй контур хранит только кэшируемые ответы операций.
Текущий безопасный runtime scope для response cache:
- `REST GET`;
Это не означает автоматическое кэширование всех REST-вызовов. Кэширование
разрешается только для безопасных `GET` operations без upstream auth profile.
Эти контуры не должны смешивать ключи друг с другом.
### Cache key isolation
Базовое правило изоляции:
- разные `workspace` не должны делить одни и те же cache keys;
- разные `agent` внутри одного `workspace` тоже не должны делить одни и те же response cache keys по умолчанию;
- разные `operation` внутри одного `agent` не должны попадать в общий response cache namespace.
Стартовая модель namespace для response cache:
- `workspace + agent + operation + operation version + request fingerprint`
Стартовая модель namespace для platform / coordination cache:
- `workspace + agent + cache scope + logical key`
Это позволяет безопасно использовать один внешний `Valkey/Redis` сразу для нескольких агентов и рабочих областей без взаимного пересечения данных.
### Auth env
Для app-level auth нужны:
- `CRANK_SESSION_SECRET`
- `CRANK_PASSWORD_PEPPER`
- `CRANK_BOOTSTRAP_ADMIN_EMAIL`
- `CRANK_BOOTSTRAP_ADMIN_PASSWORD`
- `CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME`
Для secret store foundation нужен:
- `CRANK_MASTER_KEY`
`CRANK_MASTER_KEY` обязателен и для `admin-api`, и для `mcp-server`, потому что оба приложения
должны уметь резолвить `secret_id` в runtime.
Для опционального demo-seed:
- `CRANK_DEMO_SEED=true`
В deployment workflow больше не используется монолитный `DEPLOY_ENV_FILE`.
`.env` на сервере собирается из OpenBao. В Gitea Actions хранятся только AppRole credentials
`BAO_ADDR`, `BAO_ROLE_ID` и `BAO_SECRET_ID`, а внутри OpenBao ключи проекта
`projects/crank/runtime` совпадают с именами runtime env-переменных. Это значит, что:
- `CRANK_MASTER_KEY` хранится в OpenBao как ключ `CRANK_MASTER_KEY`;
- `CRANK_DEMO_SEED` хранится в OpenBao как ключ `CRANK_DEMO_SEED`;
- и так же для остальных runtime-переменных.
Для БД основной runtime-контракт теперь компонентный:
- `POSTGRES_HOST`
- `POSTGRES_PORT`
- `POSTGRES_DB`
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `POSTGRES_MAX_CONNECTIONS`
- `POSTGRES_MIN_CONNECTIONS`
- `POSTGRES_ACQUIRE_TIMEOUT_MS`
- `POSTGRES_IDLE_TIMEOUT_MS`
- `POSTGRES_MAX_LIFETIME_MS`
Для pool behavior используются явные defaults:
- `POSTGRES_MAX_CONNECTIONS=20`
- `POSTGRES_MIN_CONNECTIONS=2`
- `POSTGRES_ACQUIRE_TIMEOUT_MS=5000`
- `POSTGRES_IDLE_TIMEOUT_MS=600000`
- `POSTGRES_MAX_LIFETIME_MS=1800000`
Для runtime concurrency используются явные defaults:
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY=64`
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS=16`
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS=16`
Для MCP transport ingress throttling используются явные defaults:
- `CRANK_MCP_RATE_LIMIT_RPS=60`
- `CRANK_MCP_RATE_LIMIT_BURST=120`
Для admin-api ingress throttling используются явные defaults:
- `CRANK_ADMIN_RATE_LIMIT_RPS=30`
- `CRANK_ADMIN_RATE_LIMIT_BURST=60`
`CRANK_DATABASE_URL` допускается только как backward-compatible fallback для локальных тестов и
переходного периода, но не как основная deployment-модель.
## 8.1. Delivery artifacts
Для production-like запуска проект должен поставляться с:
- `Dockerfile` для backend приложений;
- `deploy/community/docker-compose.yml` как canonical Community deployment manifest;
- `deploy/community/.env.example` как canonical Community env template;
- optional `Valkey` service как рекомендованный, но не обязательный компонент Community deployment;
- root `docker-compose.yml` и root `.env.example` только как local development convenience files;
- healthcheck endpoints;
- reverse proxy configuration examples.
Подробности вынесены в `docs/deployment.md`.
## 9. Что важно не допустить
- пути к storage, зашитые в код;
- секреты в `.yaml` exports;
- разные конфигурационные модели для local и production без причины;
- смешивание runtime config и business config operation.
## 10. Практический итог
До старта разработки должны быть приняты как минимум такие решения:
- где лежит БД;
- где лежат artifacts;
- как резолвятся `secret_id` и как ротируется `CRANK_MASTER_KEY`;
- на каких bind-address запускаются `admin-api` и `mcp-server`;
- какой transport использует MCP server.
```env
CRANK_LOG_LEVEL=info
```
+33
View File
@@ -0,0 +1,33 @@
# Секреты и авторизация REST API
Crank может вызывать REST API без авторизации или с авторизацией через сохраненный секрет.
## Секреты
Поддерживаемые типы:
- токен;
- логин и пароль;
- значение HTTP-заголовка;
- произвольный JSON.
Секреты шифруются ключом `CRANK_MASTER_KEY`. После создания или ротации значение нельзя прочитать через UI или API.
## Профили авторизации
Профиль авторизации описывает, как применить секрет к REST-запросу:
- `Bearer token`;
- `Basic auth`;
- API key в заголовке;
- API key в query-параметре.
Операция хранит ссылку на профиль авторизации, а не само значение секрета.
## Рекомендации
- Не вставляйте токены в статические заголовки операции.
- Используйте секреты и профили авторизации для всех чувствительных данных.
- Ротируйте секрет при подозрении на утечку.
- Не экспортируйте реальные секреты вместе с YAML-конфигурациями.
+54
View File
@@ -0,0 +1,54 @@
# Веб-интерфейс
Веб-интерфейс нужен для настройки инструментов, агентов и доступа к MCP.
## Операции
Операция описывает один REST endpoint как MCP-инструмент.
В операции задаются:
- имя инструмента;
- описание для AI-агента;
- входная схема;
- REST endpoint;
- правила преобразования входных параметров в REST-запрос;
- правила преобразования REST-ответа в результат инструмента;
- тестовый пример;
- статус публикации.
Черновик можно редактировать и тестировать. MCP-клиенты видят только опубликованные операции, которые привязаны к опубликованному агенту.
## Агенты
Агент - это отдельный MCP endpoint с выбранным набором инструментов.
Рекомендуемый подход:
- группировать инструменты под конкретную задачу;
- не давать одному агенту слишком много инструментов;
- делать названия и описания инструментов однозначными;
- публиковать агента только после проверки операций.
## API ключи
API-ключ выдается на конкретного агента. Ключ позволяет MCP-клиенту:
- открыть MCP-сессию;
- получить список инструментов агента;
- вызвать опубликованный инструмент.
Полное значение ключа показывается только при создании.
## Секреты
Секреты используются для авторизации на конечных REST API.
После сохранения значение шифруется и больше не отображается. Секрет можно ротировать или удалить, если он не используется профилем авторизации.
## Логи и использование
Раздел **Логи** показывает вызовы операций, ошибки маппинга, ошибки REST API и успешные ответы.
Раздел **Использование** показывает количество вызовов, ошибки и задержки по операциям.