Files

134 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).