# openrusrouter-mcp Клиентский MCP-сервер (stdio) для [openrusrouter.ru](https://openrusrouter.ru): каталог моделей с ценами вашего аккаунта, баланс, расход и список API-ключей — прямо из Claude, Cursor, OpenCode или любого другого MCP-агента. Пакет: `@openrusrouter/mcp`, команда: `openrusrouter-mcp`. ## Инструменты Все шесть инструментов — только чтение (помечены `readOnlyHint`), сервер делает только GET-запросы к API площадки. | Инструмент | Что делает | |------------|------------| | `list_models` | Список моделей с фильтрами (модальность, вендор, подстрока, контекст, vision, бесплатные) и сортировкой. Цены — ₽ за 1M токенов с персональной наценкой вашего аккаунта. По умолчанию — только модели, доступные текущему ключу. | | `pick_model` | Подбор моделей под требования (модальность, vision, контекст, потолок цены, ожидаемый объём токенов). Локальный фильтр по ценам каталога, не рекомендация ИИ; только среди моделей, доступных текущему ключу. | | `estimate_cost` | Оценка стоимости запроса по числу токенов: `cost_rub` — по рублёвым ценам аккаунта без скидки за кэш, `cost_usd` — по USD-ценам каталога с ценой кэш-чтения, если модель её объявляет. | | `get_balance` | Текущий баланс аккаунта в рублях и реферальный баланс (decimal-строки). | | `get_usage` | Расход за последние N дней (1–180) с группировкой по дню, модели, ключу или ключу и модели: запросы, токены, сумма в ₽. | | `list_api_keys` | Список API-ключей: префикс, лимит расхода и его окно, израсходовано, разрешённые модели. Полный ключ не выводится никогда; `is_current_key` отмечает ключ, которым работает MCP. | ## Чего тут нет и почему > **Создание, отзыв и правка API-ключей, платежи, промокоды и тикеты через MCP не делаются — и не появятся.** > > MCP-сервер ходит в API тем же Bearer-ключом, что и обычный API-вызов: сервер openrusrouter.ru их не различает. А решение вызвать инструмент принимает ИИ-агент, а не человек, нажавший кнопку, — и агентом можно управлять через содержимое, которое он читает (prompt injection). Поэтому платёжные и ключевые мутации по такому каналу сознательно не допускаются: на площадке они доступны только из браузерной сессии личного кабинета. ## Быстрый старт Нужен Node.js ≥ 20. ### 1. Заведите отдельный ключ под MCP В [личном кабинете](https://openrusrouter.ru) создайте **отдельный** API-ключ специально для MCP: с небольшим лимитом расхода (`spend_limit_rub`) и, по возможности, ограниченным списком моделей (`allowed_models`). Не используйте мастер-ключ без ограничений — почему, см. [Безопасность](#безопасность). ### 2. Подключите сервер к клиенту **Claude Desktop** — `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`, Windows: `%APPDATA%\Claude\claude_desktop_config.json`): ```json { "mcpServers": { "openrusrouter": { "command": "npx", "args": ["-y", "@openrusrouter/mcp"], "env": { "OPENRUSROUTER_API_KEY": "<ваш ключ>" } } } } ``` **Claude Code (CLI):** ```sh claude mcp add openrusrouter -e OPENRUSROUTER_API_KEY=<ваш ключ> -- npx -y @openrusrouter/mcp ``` **Проектный `.mcp.json` (Claude Code) или `.cursor/mcp.json` (Cursor)** — та же форма `mcpServers`: ```json { "mcpServers": { "openrusrouter": { "command": "npx", "args": ["-y", "@openrusrouter/mcp"], "env": { "OPENRUSROUTER_API_KEY": "<ваш ключ>" } } } } ``` Если файл лежит в репозитории, не коммитьте в него ключ: подставляйте его из окружения (`"${OPENRUSROUTER_API_KEY}"` в Claude Code, `"${env:OPENRUSROUTER_API_KEY}"` в Cursor). **OpenCode** — `opencode.json`, блок `mcp`: ```json { "$schema": "https://opencode.ai/config.json", "mcp": { "openrusrouter": { "type": "local", "command": ["npx", "-y", "@openrusrouter/mcp"], "enabled": true, "environment": { "OPENRUSROUTER_API_KEY": "<ваш ключ>" } } } } ``` OpenCode по умолчанию ждёт список инструментов 5 секунд; первый запуск через `npx` скачивает пакет и может не уложиться — тогда добавьте `"timeout": 30000`. ## Переменные окружения | Переменная | Обязательна | Описание | |------------|-------------|----------| | `OPENRUSROUTER_API_KEY` | да | API-ключ из личного кабинета. Без него сервер не стартует. | | `OPENRUSROUTER_BASE_URL` | нет | Адрес API, по умолчанию `https://openrusrouter.ru`. Допускается только `https` (`http` — только для `localhost`/`127.0.0.1`/`::1`), без логина/пароля, query-параметров и фрагмента. | > **Внимание:** ключ уходит в заголовке `Authorization` на `OPENRUSROUTER_BASE_URL`. Переопределив адрес, вы отправляете свой ключ на указанный хост — на свой риск. При нестандартном адресе сервер на старте пишет в stderr, на какой хост будет отправляться ключ. ## Безопасность - **Нет телеметрии.** Сервер обращается только к `OPENRUSROUTER_BASE_URL`. - **Ключ не пишется никуда:** ни в stdout, ни в stderr, ни в сообщения об ошибках, ни в результаты инструментов (`list_api_keys` отдаёт только префиксы). - **В stdout идёт только протокол MCP.** Диагностика — в stderr. - **Кэш каталога — в памяти процесса на 10 минут**, на диск ничего не пишется. - **Отдельный ограниченный ключ.** MCP делает только GET-запросы и платных вызовов моделей не совершает, но ключ в конфиге агента лежит открытым текстом — в файле, который читают другие программы, попадает в бэкапы и легко оказывается в репозитории. Тем же ключом можно ходить в прокси к моделям за ваш счёт. Отдельный ключ с небольшим `spend_limit_rub` и узким `allowed_models` ограничивает ущерб при утечке, и его можно отозвать в кабинете, не трогая остальные интеграции. ## Ограничения - У image-, transcription- и speech-моделей цена за токен не публикуется — они тарифицируются по факту. `estimate_cost` для них возвращает ошибку, а не ноль. - Каталог площадки может содержать модели, недоступные текущему ключу (из-за `allowed_models`). По умолчанию `list_models` их скрывает; `include_disallowed=true` покажет их явно. `pick_model` подбирает только среди доступных. - Оценка стоимости — это оценка: фактическое списание идёт по usage ответа провайдера. ## Разработка ```sh npm ci npm run typecheck npm test npm run build npm run lint npm run gen:types # регенерация типов из живой OpenAPI-спеки ``` ## Лицензия MIT — см. [LICENSE](LICENSE).