# Архитектура ## Место в системе ``` ┌────────────────┐ MCP (stdio, JSON-RPC) ┌──────────────────┐ │ MCP-клиент │ ◄──────────────────────► │ omnichannel-configserver-mcp │ │ (AI-ассистент)│ │ (этот сервер) │ └────────────────┘ └────────┬─────────┘ │ HTTP (session) ▼ ┌──────────────────┐ │ config_server │ │ (Flask API/UI) │ └────────┬─────────┘ │ задачи агентам ▼ ┌───────────────────────────┐ │ агенты на хостах │ │ docker-compose / swarm │ └───────────────────────────┘ ``` `omnichannel-configserver-mcp` — тонкий клиент. Он не выполняет команды сам: создаёт задачи через API `config_server`, а те забирают агенты нод. Сервер без состояния — при перезапуске ничего не теряется. ## Модель задач Действия жизненного цикла (`deploy`, `restart`, `down`, `migrate`, `update_front`, релизные операции) асинхронны: 1. Инструмент вызывает API → создаётся задача → возвращается `task_id`. 2. Агент ноды забирает задачу, выполняет `docker-compose`, публикует результат. 3. Клиент опрашивает `get_task` до `completed`/`failed`. Поэтому у инструментов есть параметр `wait`: по умолчанию он выключен (loop ассистента последовательный — не стоит его блокировать), а при `wait=true` ожидание ограничено `task_poll_max_sec` и не считается ошибкой, если время вышло: вернётся текущее состояние задачи. ## Слои модуля ``` main.go каркас lifecycle: --health, -config, stdio internal/configserver/ домен: без зависимостей от MCP config.go разбор/валидация конфига, ${VAR}, merge local session.go HTTP-клиент: cookie-сессия, релогin, ретраи GET manager.go потокобезопасный диспетчер: конфиг, сессии, семафоры api_*.go типизированные вызовы эндпоинтов config_server internal/tools/ MCP-слой: разбор аргументов → вызов домена → текст registry.go toolkit.go patterns.go util.go observe.go configure.go operate.go release.go maintain.go overview.go ``` Правило разделения: домен тестируется без MCP; MCP-слой не содержит бизнес-логики. ## Надёжность - **Сессия:** Flask-cookie хранится в cookie-jar; login ленивый, при `401` выполняется один повторный вход и один повтор запроса. - **Повторы:** только идемпотентные GET (сеть/5xx). Мутации не повторяются. - **Ограничения:** context-deadline на каждый вызов, лимит на размер ответа, обрезка вывода, семафор мутаций на сервер. - **Ошибки:** доменные (4xx/5xx с текстом, ошибки валидации) возвращаются как recoverable — ассистент видит причину и может исправить; инфраструктурные (сеть) — как ошибка протокола. - **Логи:** только в stderr (stdout занят JSON-RPC), с маскированием секретов. ## Логи и наблюдаемость Логи модуля пишутся в stderr; уровень задаётся `--log-level` или `OMNI_LOG_LEVEL` (`debug|info|warn|error`). HTTP-сервер `config_server` — источник данных о задачах и статусах.