Обзор
- адрес
- https://api.rus-mcp.ru/v1
- формат
- JSON в UTF-8; ошибки —
application/problem+json - описание
- OpenAPI 3.1 — /v1/openapi.json, для генерации клиентов
- версия
- v1
Это API платформы, а не протокол MCP. Чтобы подключить сервер к Claude, API не нужен — вот инструкция.
Без ключа открыт только каталог. Всё остальное — с ключом, у которого есть нужное право. Заголовков CORS API не отдаёт: из браузера на чужом сайте запрос не пройдёт, да и ключ в браузере не место — вызывайте API со своего сервера или из скрипта.
Первый запрос
Каталог отвечает без ключа. Для остального создайте ключ в кабинете, раздел «Ключи API», и передавайте его в заголовке Authorization. В примерах ключ берётся из переменной окружения RUSMCP_API_KEY.
# без ключа: поиск в каталоге curl -G https://api.rus-mcp.ru/v1/catalog/servers \ --data-urlencode "q=погода" -d limit=5 # с ключом: ваш аккаунт curl https://api.rus-mcp.ru/v1/me \ -H "Authorization: Bearer $RUSMCP_API_KEY"
import os import httpx api = httpx.Client( base_url="https://api.rus-mcp.ru/v1", headers={"Authorization": f"Bearer {os.environ['RUSMCP_API_KEY']}"}, ) page = api.get("/catalog/servers", params={"q": "погода", "limit": 5}).json() for server in page["data"]: print(server["id"], server["name"], server["tool_count"]) print(api.get("/me").json()["login"])
const res = await fetch("https://api.rus-mcp.ru/v1/me", { headers: { Authorization: `Bearer ${process.env.RUSMCP_API_KEY}` }, }); if (!res.ok) { const problem = await res.json(); // problem+json, см. «Ошибки» throw new Error(`${problem.code}: ${problem.detail}`); } console.log(await res.json());
Авторизация и права
Ключ передаётся в заголовке Authorization: Bearer mcpb_pat_…. Cookie сайта API не принимает.
- Ключ создаётся только в кабинете, через API — нельзя. Для этого нужны подтверждённая почта, пароль и код 2FA, если она включена. Полный ключ показывается один раз.
- Срок жизни — 7, 30, 90, 180 или 365 дней, по умолчанию 90. Ключ можно ограничить своими серверами (до 50) и сетями IP (до 10). Активных ключей — до 25.
- Неверный, просроченный или отозванный ключ, как и запрос не из разрешённой сети, получает
401 invalid_token. Отзыв действует со следующего запроса. - Не хватает права —
403 insufficient_scope, недостающее право названо вdetailи в заголовкеWWW-Authenticate. Что умеет текущий ключ — GET /token.
| Право | Что даёт |
|---|---|
| account:read | Читать профиль |
| saved_servers:read | Видеть «Мои MCP» |
| saved_servers:write | Добавлять и убирать серверы в «Мои MCP» |
| usage:read | Видеть свой расход вызовов |
| notifications:read | Читать уведомления |
| notifications:write | Отмечать уведомления прочитанными |
| servers:read | Видеть свои серверы и статус модерации |
| deployments:read | Видеть сборки и логи |
| deployments:write | Запускать сборки |
| secrets:read | Видеть имена ключей сервера |
| secrets:write | Менять ключи сервера — чувствительное |
| revenue:read | Видеть статистику вызовов и доход |
| pricing:write | Менять цены инструментов — чувствительное |
Списки и страницы
Все списки приходят в одной обёртке. Следующая страница — тот же запрос с cursor, равным next_cursor. Курсор непрозрачный: не разбирайте и не собирайте его сами. Курсор от других фильтров или испорченный — 400 invalid_cursor.
{ "data": [ … ], "has_more": true, "next_cursor": "eyJvIjoyMCwi…" }
limit: в каталоге — до 50 (по умолчанию 20), в уведомлениях — до 100 (по умолчанию 20). Короткие списки — категории, «Мои MCP», ваши серверы, переменные, цены — приходят целиком, с has_more: false.
Ошибки
Ошибки — в формате RFC 9457 (application/problem+json). Ориентируйтесь на code — он не меняется; текст detail может меняться. request_id (он же заголовок Request-Id в каждом ответе) пришлите в поддержку, если нужна помощь с запросом.
HTTP/1.1 403 · Content-Type: application/problem+json { "type": "https://rus-mcp.ru/api-docs.html#errors", "title": "Forbidden", "status": 403, "detail": "This token does not have the 'servers:read' permission.", "code": "insufficient_scope", "request_id": "req_…" }
Ошибка проверки параметров (422 validation_failed) дополнительно содержит errors — список полей: loc, msg, type.
Коды
| code | HTTP | Что случилось |
|---|---|---|
| unauthorized | 401 | Ключа нет, а метод его требует |
| invalid_token | 401 | Ключ неверный, просрочен, отозван или запрос не из разрешённой сети |
| insufficient_scope | 403 | У ключа нет нужного права |
| not_found | 404 | Нет такого сервера или адреса; сервер не ваш или не входит в серверы ключа |
| invalid_cursor | 400 | Курсор от других фильтров или испорчен |
| invalid_category | 400 | Нет такой категории |
| validation_failed | 422 | Параметры или тело не прошли проверку, подробности в errors |
| method_not_allowed | 405 | Метод не поддерживается для этого адреса |
| payload_too_large | 413 | Тело запроса больше 1 МБ |
| rate_limited | 429 | Превышен лимит запросов, см. «Лимиты» |
| too_many_failed_attempts | 429 | Слишком много неудачных попыток входа с этого IP |
| internal_error | 500 | Ошибка на нашей стороне |
Коды методов хостинга и цен
| code | HTTP | Что случилось |
|---|---|---|
| not_deployed | 409 | Сервер не размещён на хостинге rus-mcp.ru |
| build_in_progress | 409 | Сборка уже в очереди или идёт |
| build_not_running | 409 | Нет сборки, которую можно отменить |
| not_rebuildable | 409 | Сервер нельзя пересобрать в текущем состоянии |
| rebuild_removing | 409 | Сервер удаляется |
| rebuild_not_reviewed | 409 | Хостинг для сервера ещё не одобрен |
| rebuild_suspended | 409 | Хостинг сервера приостановлен |
| rebuild_failed | 500 | Пересборку не удалось запустить |
| too_frequent | 429 | Слишком часто: см. Retry-After |
| hosting_busy | 503 | Хостинг занят: см. Retry-After |
| hosting_unavailable | 502, 503 | Хостинг временно недоступен |
| invalid_name | 400 | Имя переменной — заглавные латинские буквы, цифры и «_», с буквы, до 64 символов |
| reserved_name | 400 | Имя занято платформой: PORT и всё на RUSMCP_ |
| too_many | 400 | Больше 32 переменных в одном запросе |
| invalid_value | 400 | Значение пустое, длиннее 4096 символов или с управляющими символами |
| not_hosted | 409 | Цены можно назначать только серверам на хостинге rus-mcp.ru |
| unknown_tool | 400 | У сервера нет такого инструмента |
| invalid_price | 400 | Цена вне диапазона 5–1 000 000 кредитов |
Лимиты
60 запросов в минуту на ключ, 30 — на IP-адрес без ключа. Запас виден в каждом ответе в заголовках RateLimit-Policy и RateLimit: q — сколько запросов в окне, w — окно в секундах, r — сколько осталось, t — через сколько секунд запас восстановится полностью.
RateLimit-Policy: "token";q=60;w=60 RateLimit: "token";r=57;t=3
- Превысили —
429 rate_limitedи заголовокRetry-Afterс числом секунд. - Неудачных попыток авторизации — до 10 в минуту с одного IP, дальше
429 too_many_failed_attempts. - Свои пределы у отдельных методов: лог сервера — не чаще раза в 20 секунд на сервер, пересборка — до 3 в час.
Каталог
Без ключа. Список — только серверы, которые сейчас видны в каталоге; по id отдаётся и скрытый сервер (listed: false).
GET/catalog/serversПоиск по каталогубез ключа
Серверы каталога, сначала недавно проверенные.
| Параметр | Тип | Описание |
|---|---|---|
| q | string | Часть названия сервера, без учёта регистра; 1–120 символов |
| category | string | slug категории из /catalog/categories, до 32 символов; неизвестная — 400 invalid_category |
| limit | integer | 1–50, по умолчанию 20 |
| cursor | string | next_cursor с прошлой страницы |
Ответ — страница CatalogServer. requires_account — серверу нужен аккаунт в стороннем сервисе; source_private — репозиторий закрыт. Пример (значения выдуманы, поля — как в API):
{ "data": [{ "id": 42, "name": "Погода по городам", "tagline": "Текущая погода и прогноз по городу", "description": "…", "category": { "slug": "productivity", "name_ru": "…", "name_en": "…" }, "author_name": "…", "source_url": null, "docs_url": null, "icon_url": null, "is_free": true, "requires_account": false, "source_private": false, "tool_count": 3, "listed": true, "created_at": "2026-09-14T09:12:44Z", "reviewed_at": "2026-09-15T11:03:20Z" }], "has_more": true, "next_cursor": "eyJvIjoyMCwi…" }
GET/catalog/categoriesКатегориибез ключа
Категории каталога: slug, name_ru, name_en.
GET/catalog/servers/{server_id}Сервербез ключа
Один сервер — те же поля, что в списке. Отдаётся и сервер, скрытый из каталога.
GET/catalog/servers/{server_id}/toolsИнструменты серверабез ключа
Для каждого инструмента — name, title, description, input_schema, annotations и price_credits. Ещё credit_usd — цена кредита в долларах (строкой) и paid_live — списываются ли деньги за платные вызовы.
GET/catalog/servers/{server_id}/trustЧто проверил RusMcpбез ключа
Открыт ли исходный код, подтверждён ли репозиторий, результат проверки описаний инструментов; для сервера на хостинге — коммит сборки, дата выкладки и скан образа.
Аккаунт и «Мои MCP»
GET/meВаш профильaccount:read
id, login, email, language, email_verified, created_at.
GET/me/saved-serversСерверы в «Мои MCP»saved_servers:read
Новые сверху, с адресами подключения (url).
POST/me/saved-serversДобавить серверsaved_servers:write
Тело {"server_id": 42}, ответ 204. Повторное добавление ничего не меняет.
DELETE/me/saved-servers/{server_id}Убрать серверsaved_servers:write
Ответ 204. Сервер пропадает из «Моих MCP», ваши вызовы перестают учитываться, а доступ всех подключённых к нему приложений отзывается. Чтобы пользоваться снова — добавьте его и подключите приложения заново.
GET/me/usageВаш расход по серверамusage:read
days — период, 1–90 дней, по умолчанию 30.
GET/me/saved-servers/{server_id}/usageРасход по одному серверуusage:read
Итоги, по инструментам и по дням; days — 1–90.
GET/me/notificationsУведомленияnotifications:read
Новые сверху, страницы не пересекаются, даже если тем временем пришли новые. limit — 1–100, по умолчанию 20; unread_only — только непрочитанные.
POST/me/notifications/readОтметить прочитаннымиnotifications:write
Тело {"ids": [1, 2]} (до 100) или {"all": true}, ответ 204.
Ключ
GET/tokenЧто умеет текущий ключлюбой ключ
Название, префикс, права, серверы, сети IP и срок действия ключа, которым сделан запрос.
DELETE/tokenОтозвать текущий ключлюбой ключ
Ключ, которым сделан запрос, сразу перестаёт работать. Ответ 204. Пригодится, если ключ попал в лог.
Нашли ошибку в документации или не хватает метода? Напишите в группу. Все поля ответов — в openapi.json.