# Архитектура ## 1. Назначение проекта Crank - платформа для публикации внешних API в виде MCP tools без написания отдельного backend-кода под каждую интеграцию. Пользователь конфигурирует интеграции через UI, а система: - хранит и версионирует операции; - группирует их по workspace; - публикует их в составе конкретных agents; - выдает LLM не глобальный каталог tools, а curated toolset на один agent; - собирает продуктовые логи и usage по workspace, agent и operation. ## 2. Переход `As Is -> To Be` ### 2.1. As Is Текущее ядро системы построено вокруг: - глобальной сущности `Operation`; - registry версий операций; - runtime adapters `REST / GraphQL / unary gRPC`; - `admin-api` для CRUD и тестовых вызовов; - `mcp-server`, который публикует tools из published operations. ### 2.2. To Be Целевая архитектура расширяет текущее ядро до модели: - `Workspace` - tenant boundary; - `Operation` - интеграционный контракт; - `Agent` - curated MCP surface; - `Agent key`, `Agent token` и `Membership` - доступ к самой платформе; - `Invocation log` и `Usage rollup` - observability слой. `Operation` остается фундаментом интеграции, но tools больше не публикуются глобально. MCP публикует tools в контексте конкретного `workspace` и конкретного `agent`. ## 3. Ключевые сущности и их роль ### `Workspace` Изолирует: - операции; - secrets; - auth profiles; - agents; - agent keys; - short-lived agent tokens; - logs и usage; - пользователей и роли. ### `Operation` Описывает один вызываемый элемент независимо от протокола: - `name` - `display_name` - `protocol` - `target` - `input_schema` - `input_mapping` - `execution_config` - `security_level` - `output_mapping` - `tool_description` - `status` Принцип: - уровень защиты определяется самой операцией; - агент не может ослабить обязательный режим доступа; - для более чувствительных данных требуется более строгий вид машинного credential. ### `Agent` Является пользовательской MCP-поверхностью для LLM. `Agent`: - принадлежит одному workspace; - имеет `slug`, `display_name`, `description`, `status`; - ссылается на ограниченный набор published operations; - формирует отдельный MCP endpoint; - решает проблему "одному агенту нельзя отдавать 100 tools сразу". При этом `Agent` не определяет чувствительность операции, а только публикует ее в составе MCP-поверхности. ### `Platform access` Отдельный слой, не связанный с upstream auth: - `User` - `UserSession` - `Membership` - `Invitation` - `AgentKey` - `IssuedAgentToken` Принцип: - пользовательская аутентификация и машинная аутентификация разделены; - длинноживущий доступ для вызова MCP tools привязан к конкретному агенту, а не к рабочей области целиком; - в открытой редакции базовый режим строится на статическом ключе агента; - в более защищенных редакциях используются короткоживущие и одноразовые токены; - промежуточная схема с workspace-scoped ключами рассматривается как переходная и подлежит замене. ### `Upstream secrets` Отдельный слой для доступа к внешним системам: - `Secret` - `SecretVersion` - `AuthProfile` Принцип: - секреты принадлежат workspace; - plaintext не хранится в открытом виде; - `AuthProfile` описывает способ применения секрета к upstream request; - runtime резолвит `auth_profile_ref` в реальный header/query/basic auth только в момент вызова. ### `Observability` Отдельный продуктовый слой: - `InvocationLog` - `InvocationEvent` - `UsageRollup` - `LatencyStats` ## 4. Главный принцип проектирования Система строится в три слоя: 1. `Operation` как низкоуровневый интеграционный контракт. 2. `Agent` как curated набор published operations. 3. `Workspace` как граница данных, доступа и observability. Это позволяет: - переиспользовать одну operation в нескольких agents; - ограничивать tool catalog для конкретного LLM-сценария; - изолировать данные команд; - строить logs и usage не глобально, а по tenant boundary. ## 5. Границы целевого продукта ### Входит - `Workspace` как tenant boundary. - Операции `REST`, `GraphQL`, `gRPC`, `WebSocket`, `SOAP`. - Controlled streaming operations поверх `Streamable HTTP`, REST SSE, gRPC server-streaming и WebSocket upstream. - `Agent` и привязка операций к агенту. - Agent-scoped MCP endpoints. - Agent-scoped machine credentials. - Short-lived MCP access tokens. - Workspace-scoped encrypted secrets для upstream access. - Workspace-scoped auth profiles для upstream access. - Product logs и usage aggregates. - Импорт и экспорт operation-конфигураций в `YAML`. - Hot reload опубликованных agents и operations. ### Отложено - GraphQL `subscription`. - gRPC client-streaming и bidirectional streaming. - raw infinite stream passthrough. - полный стек WS-* расширений. - Оркестрация workflow. - Биллинг. - Full RBAC policy engine. - Traffic splitting и deployment orchestration. ## 6. Пользовательские сценарии ### Оператор операций 1. Выбирает workspace. 2. Создает или редактирует operation. 3. При необходимости выбирает или создает upstream secret / auth profile. 4. Выполняет test run. 5. Публикует operation version. 6. Привязывает operation к одному или нескольким agents. ### Оператор агентов 1. Создает agent. 2. Выбирает набор published operations. 3. Публикует agent. 4. Получает MCP endpoint вида `/mcp/v1/{workspace}/{agent}`. ### Администратор workspace 1. Управляет ключами AI-агентов и доверенных клиентов платформы. 2. Управляет пользователями и ролями. 3. Смотрит logs и usage. ## 7. Стратегия по протоколам ### REST - `GET` - `POST` - `PUT` - `PATCH` - `DELETE` - path parameters - query parameters - headers - JSON request body - JSON response body ### GraphQL - `query` - `mutation` - endpoint URL - request headers - operation template - variables mapping ## 8. Open-core граница Crank развивается как open-core продукт. Это означает: - `Community` должна полностью собираться из этого репозитория; - коммерческие возможности не должны храниться здесь как рабочий private code; - различия между редакциями должны отражаться в capability model, API, UI и delivery pipeline. Ключевые продуктовые различия зафиксированы в `docs/product-editions.md`. ## 9. Коммерческий контур Коммерческий контур не должен защищаться "скрытием" уже опубликованного исходного кода. Правильная архитектурная граница выглядит так: - в public repo остается Community runtime и extension seams; - коммерческие реализации поставляются из private repositories или private artifacts; - критичные правила лицензирования, metering и token issuance исполняются на серверной стороне. Практические правила зафиксированы в `docs/commercial-boundaries.md`. - извлечение результата из `data` GraphQL в MCP публикуется как фиксированная операция с предсказуемой структурой ответа. ### gRPC - unary RPC; - bounded server-streaming через `window`, `session` и `async_job` execution modes; - `.proto` и `descriptor set`; - JSON-oriented schema model поверх protobuf; - без client-streaming и bidi. ### WebSocket - upstream-only adapter; - bounded `window`, `session` и `async_job`; - subscribe/unsubscribe messages; - heartbeat и reconnect policy; - не используется как downstream MCP transport. ### SOAP - WSDL-driven request-response integration; - service/port/operation selection; - SOAP envelope и fault normalization; - request-response first; - long-running workflows через `async_job`, если upstream это поддерживает. ### Streaming Платформа поддерживает controlled streaming model: - downstream transport: `Streamable HTTP` с optional SSE; - upstream streaming: REST SSE, gRPC server-streaming и WebSocket; - execution modes: `unary`, `window`, `session`, `async_job`; - никакого raw infinite stream passthrough в MCP client. ## 8. Работа с файлами и автогенерация черновика Поддерживаемые источники: - пример входного `JSON`; - пример выходного `JSON`; - `.proto`; - `descriptor set`. Ожидаемый сценарий: 1. оператор загружает артефакты; 2. система строит черновую схему и mapping; 3. оператор вручную корректирует результат; 4. готовую конфигурацию можно экспортировать в `YAML`. ## 9. Внутренняя модель данных Базовые сущности: - `Workspace` - `Secret` - `SecretVersion` - `Operation` - `OperationVersion` - `Agent` - `AgentVersion` - `AgentOperationBinding` - `StreamSession` - `AsyncJobHandle` - `AuthProfile` - `AgentKey` - `IssuedAgentToken` - `UserSession` - `InvocationLog` - `UsageRollup` ## 10. MCP publishing model Публикация tools строится так: 1. `Operation` проходит versioning и publish. 2. `Agent` собирает curated набор published operations. 3. `MCP server` читает published view конкретного agent. 4. `tools/list` и `tools/call` работают в контексте `workspace + agent`. ## 11. Observability На каждый вызов tool сохраняются: - `workspace_id` - `agent_id` - `operation_id` - `request_id` - `timestamp` - `status` - `duration_ms` - `error_kind` - `request_preview` - `response_preview` Сверху строятся: - logs page; - usage page; - периодические rollups; - latency and error aggregates. ## 12. Модель маппинга Платформе нужен отдельный слой маппинга: - сопоставление поле-в-поле по `JSONPath`; - константы; - значения по умолчанию; - извлечение вложенных полей из ответа.