# routerai-image-mcp MCP-сервер генерации и редактирования картинок через **RouterAI** (`https://routerai.ru/api/v1`). Даёт любой модели — в том числе той, что рисовать не умеет, но умеет ставить ТЗ другим — инструмент `generate_image`: передал текстовое описание, получил файл с картинкой. ## Зачем Агентные модели (DeepSeek, Qwen, локальные) отлично формулируют ТЗ, но не генерируют изображения. Этот сервер закрывает разрыв: модель вызывает `generate_image(prompt=...)`, сервер ходит в модель генерации картинок (Nano Banana / Gemini Image, FLUX, GPT-Image), кладёт результат файлом и возвращает путь. Модель вставляет этот путь в ответ — клиент показывает картинку. ## Архитектура ``` LLM (agent) ──MCP──▶ routerai-image-mcp ──HTTPS──▶ routerai.ru/api/v1 │ └─▶ файл на диске (~/.hermes/image_cache/mcp-gen/) возвращает: "MEDIA:<путь>" ``` Два бэкенда, выбираются автоматически по id модели: | Backend | Что вызывается | Модели | |---|---|---| | `chat` | `POST /chat/completions` с `modalities: ["image","text"]` | Gemini Image / Nano Banana | | `images` | `POST /images/generations` | FLUX.2, GPT-Image | `chat`-бэкенд дополнительно умеет **image-to-image**: если передать `reference_images`, они уходят в запрос как image_url-части, и модель редактирует присланную картинку (сохранив сюжет) — проверено на «поменяй фон». ## Требования - Python 3.10+ - Пакет `mcp` (`pip install mcp`) — в Hermes он уже есть: `/usr/local/lib/hermes-agent/venv/bin/python` - Ключ RouterAI (см. «Настройка») - Сетевой доступ к `https://routerai.ru` ## Установка ```bash git clone https://git.binom.pw/subochev/routerai-image-mcp cd routerai-image-mcp python3 -m venv .venv .venv/bin/pip install -r requirements.txt ``` Либо без своего venv — использовать интерпретатор Hermes (там `mcp` уже стоит): ```bash /usr/local/lib/hermes-agent/venv/bin/python server.py ``` ## Настройка Ключ ищется в таком порядке: 1. `ROUTERAI_API_KEY` (или `IMAGE_MCP_API_KEY`) в окружении; 2. `~/.hermes/models.yaml` → `models.deepseek.api_key` (если у записи `base_url` содержит `routerai.ru`); 3. любой подходящий `api_key` из `models.yaml`, где `base_url` = routerai.ru. То есть на машине с Hermes, где `models.yaml` уже настроен, **ничего задавать не нужно** — ключ подхватится сам. Явный способ: ```bash export ROUTERAI_API_KEY='sk-...' ``` Переменные окружения сервера: | Переменная | Дефолт | Смысл | |---|---|---| | `ROUTERAI_API_KEY` | — | Ключ RouterAI (иначе берётся из `models.yaml`) | | `ROUTERAI_BASE_URL` | `https://routerai.ru/api/v1` | Базовый URL API | | `IMAGE_MCP_DEFAULT_MODEL` | `google/gemini-3.1-flash-image` | Модель по умолчанию | | `IMAGE_MCP_OUT_DIR` | `~/.hermes/image_cache/mcp-gen` | Куда складывать картинки | | `IMAGE_MCP_TIMEOUT` | `300` | Таймаут запроса, сек | | `MCP_TRANSPORT` | `stdio` | `stdio` или `http` | | `MCP_HOST` / `MCP_PORT` | `0.0.0.0` / `8790` | Только для `http` | ## Запуск ### stdio (обычный режим для локальных клиентов) ```bash python server.py ``` ### HTTP (когда сервер нужен по сети нескольким клиентам) ```bash MCP_TRANSPORT=http MCP_PORT=8790 python server.py ``` Эндпоинт: `http://:8790/mcp` (streamable HTTP). Проверка: ```bash curl -s -X POST http://127.0.0.1:8790/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' # → event: message / data: {... "serverInfo":{"name":"routerai-image"}} ``` ## Подключение к Hermes ```bash hermes mcp add routerai-image \ --command /usr/local/lib/hermes-agent/venv/bin/python \ --args /opt/routerai-image-mcp/server.py ``` На вопрос «Enable all N tools?» ответить `Y`. Проверка: ```bash hermes mcp test routerai-image # ✓ Connected, Tools discovered: 2 → generate_image, list_image_models ``` ⚠️ **Инструменты появляются только в новой сессии** — MCP-серверы подключаются при старте Hermes; в уже идущем диалоге их не будет. Если сервер развёрнут на отдельной машине, вместо stdio удобнее HTTP: ```bash hermes mcp add routerai-image --url http://:8790/mcp ``` ## Подключение к другим клиентам opencode (`~/.config/opencode/config.json`): ```json { "mcp": { "routerai-image": { "type": "local", "command": ["/usr/local/lib/hermes-agent/venv/bin/python", "/opt/routerai-image-mcp/server.py"], "enabled": true } } } ``` Claude Desktop / прочие stdio-клиенты — тот же `command` + `args`. ## Инструменты ### `generate_image` | Аргумент | Тип | Смысл | |---|---|---| | `prompt` | str | ТЗ: сюжет, стиль, свет, композиция, пропорции | | `model` | str | id модели RouterAI (дефолт `google/gemini-3.1-flash-image`) | | `reference_images` | list[str] | Пути к картинкам для правки/референса (image-to-image) | | `out_dir` | str | Куда сложить файл | | `filename` | str | Имя файла (расширение подставится само) | Возвращает текст с абсолютным путём и строкой `MEDIA:<путь>`. **Чтобы клиент показал картинку, модель должна вставить эту строку `MEDIA:<путь>` целиком в свой ответ.** ### `list_image_models` Печатает список поддерживаемых моделей, их бэкенды и дефолт. ## Модели и стоимость | id | Что это | Цена (факт, за картинку) | |---|---|---| | `google/gemini-3.1-flash-image` | Nano Banana 2 — дефолт | ~7.5 ₽ | | `google/gemini-3.1-flash-lite-image` | Nano Banana 2 Lite — самый дешёвый | ~3.7 ₽ | | `google/gemini-2.5-flash-image` | Nano Banana (2.5) | ~4.3 ₽ | | `google/gemini-3-pro-image` | Nano Banana Pro | ~13 ₽ | | `black-forest-labs/flux.2-klein-4b` | FLUX.2 Klein — дешёвый, без правки | — | | `black-forest-labs/flux.2-pro` / `-max` / `-flex` | FLUX.2 Pro/Max/Flex | — | | `openai/gpt-image-1` / `-mini` | GPT Image | — | Ключи без значения — считаются по своему тарифу, проверяйте на `GET https://routerai.ru/api/v1/models` (поле `pricing.image_output`). Gemini-Image дороже других, зато понимает сложные ТЗ и умеет правку по референсу. ## Проверка ```bash # список инструментов по протоколу + генерация /usr/local/lib/hermes-agent/venv/bin/python test_client.py --generate google/gemini-3.1-flash-lite-image # правка существующей картинки по референсу /usr/local/lib/hermes-agent/venv/bin/python test_edit.py /путь/к/картинке.jpg ``` Оба скрипта поднимают сервер по stdio и работают с ним как настоящий MCP-клиент. ## Питфоллы - **`llm.binom.pw` может лежать (502), а `routerai.ru` — работать.** Сервер ходит напрямую в `routerai.ru` и не зависит от Bifrost/llm-proxy. Если у вас всё настроено через роутер и он упал — картинки всё равно будут. - **Путь к интерпретатору.** `python3` из системы может не иметь пакета `mcp`. В Hermes надёжнее указывать его venv: `/usr/local/lib/hermes-agent/venv/bin/python`. - **Картинки нужны модели, а не агенту.** Возвращается путь к файлу, а не base64 в контекст — контекст не забивается мегабайтами. - **Модели, отдающие картинки иначе.** `flux.2-*` и `gpt-image-*` не принимают `modalities` — для них используется `/images/generations`; определяется автоматически по таблице `MODELS` в начале `server.py`. Новая модель из другого семейства — дописать её туда. - **RouterAI отдаёт префикс-мусор перед JSON** на `/images/generations` (переводы строк и пробелы) — парсер ищет первый `{`. - **429/5xx** — сервер сам делает 3 повтора с нарастающей паузой; 403 `model_blocked` означает, что модель не разрешена ключу на роутере. ## Лицензия Apache License 2.0 — см. `LICENSE`.