rtk-vats

rtk-vats

Enables AI agents to manage Rostelecom Virtual PBX telephony, including contacts, subscribers, call groups, call history, call recordings, numbers and routing, balance, and transparent proxy to any of ~240 endpoints.

Category
Visit Server

README

rtk-vats-api

REST API поверх внутреннего API личного кабинета Виртуальной АТС Ростелеком (cloudpbx.rt.ru/webapi). Позволяет скриптам и AI-агентам управлять телефонией: контакты, абоненты, группы вызовов, история звонков, записи разговоров, номера и маршрутизация, баланс — плюс прозрачный прокси на любой из ~240 эндпоинтов ВАТС.

Вход — по логину и паролю «Ростелеком Паспорта» с подтверждением кодом из SMS; дальше сессия поддерживается автоматически. В комплекте MCP-сервер и готовый скилл, чтобы этим мог пользоваться AI-агент (Claude Code и совместимые).

Неофициальный проект: использует внутреннее API ЛК, которое Ростелеком может изменить без предупреждения. Не аффилирован с ПАО «Ростелеком».

Как это работает

  • Вход — логином и паролем «Ростелеком Паспорта» плюс одноразовый код из SMS (POST /auth/login → POST /auth/code). Дальше сервис живёт сам: JWT ~24 минуты, фоновый keepalive обновляет его по refresh-токену.
  • Сессия хранится в data/session.json (права 600) и переживает рестарт сервиса.
  • Доступ к этому API — по заголовку X-API-Key (значение в .env).

Почему для входа нужен браузерный движок

У доменов, подключённых к «Ростелеком Паспорту», классический POST /webapi/auth (логин + пароль + домен) не работает: собственного пароля в ВАТС у такой учётной записи нет, сервер отвечает «Введенные учетные данные некорректны». Вход идёт по цепочке /webapi/sso → Keycloak passport.rt.ru → SMS-код → возврат в ЛК с токенами.

Страницы Паспорта закрыты антиботом F5: обычный HTTP-клиент получает JS-челлендж вместо формы, а grant_type=password (ROPC) — тот же челлендж. Поэтому шаг логина выполняет настоящий движок (Playwright, Chromium) — только в момент входа, секунд на тридцать. Вся дальнейшая работа идёт обычным httpx без браузера.

Если ставить Chromium на сервер не хочется, есть два пути: scripts/login_helper.py (браузер запускается у вас на машине, токены уходят сервису) или ручной POST /auth/import.

Запуск (разработка)

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/playwright install chromium     # нужен только для /auth/login
cp .env.example .env                      # заполнить PBX_USERNAME/PBX_PASSWORD, API_KEY
.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8010

Документация OpenAPI: http://<host>:8010/docs

Авторизация

KEY="X-API-Key: <ваш API_KEY>"

# 1. Логин и пароль -> на телефон владельца учётки уходит SMS
curl -X POST http://localhost:8010/auth/login -H "$KEY" \
     -H 'Content-Type: application/json' \
     -d '{"username":"lk_1234567890","password":"..."}'
# -> {"status":"code_required","hint":"Мы отправили код на номер +7 ...","seconds_to_enter_code":300}

# 2. Код из SMS
curl -X POST http://localhost:8010/auth/code -H "$KEY" \
     -H 'Content-Type: application/json' -d '{"code":"123456"}'
# -> {"status":"ok","seconds_left":1435,"has_refresh_token":true,"has_fingerprint":true}

# Состояние сессии / принудительное обновление / отмена входа
curl http://localhost:8010/auth/status -H "$KEY"
curl -X POST http://localhost:8010/auth/refresh -H "$KEY"
curl -X POST http://localhost:8010/auth/cancel  -H "$KEY"

Логин и пароль можно не передавать в запросе — тогда берутся PBX_USERNAME / PBX_PASSWORD из .env. Вход по одноразовому коду без пароля: {"by_code": true}.

На ввод кода даётся BROWSER_CODE_TTL секунд (по умолчанию 300): всё это время открытая страница Паспорта ждёт код. Не успели — начните с /auth/login.

Вход без браузера на сервере

# на своей машине (там, где есть playwright); токены уедут на удалённый сервис
python scripts/login_helper.py --api-url http://10.10.0.187:8010 --api-key <KEY>

Ручной импорт токенов (крайний случай)

DevTools (F12) → Application → Local Storage → token, refreshToken. Значение fingerprint в хранилище отсутствует — взять из адресной строки SSO-редиректа (...&fingerprint=...) или выполнить getBrowserFingerprint() в консоли ЛК. Без fingerprint обновление сессии работать не будет.

curl -X POST http://localhost:8010/auth/import -H "$KEY" \
     -H 'Content-Type: application/json' \
     -d '{"token":"<JWT>","refresh_token":"<refreshToken>","fingerprint":"<fp>"}'

Домены без SSO

Если у учётной записи есть собственный пароль в самой ВАТС, работает классический вход: POST /auth/start (логин/пароль/домен из .env) → POST /auth/complete с кодом из SMS.

Эндпоинты

Удобные (типизированные)

Метод и путь Что делает Эндпоинт ВАТС
GET /contacts Группы контактов с контактами GET /domain/contacts
POST /contacts Создать контакт POST /domain/contacts
PUT/DELETE /contacts/{id} Изменить/удалить контакт PUT/DELETE /domain/contacts/{id}
POST /contacts/groups Создать группу POST /domain/contacts/group
PUT/DELETE /contacts/groups/{id} Изменить/удалить группу PUT/DELETE /domain/contacts/group/{id}
GET /contacts/users Абоненты домена (номера, PIN) GET /domain/contacts/users
GET/POST /users, PUT/DELETE /users/{id} Абоненты домена /domain/users*
GET/POST /groups, GET/PUT/DELETE /groups/{id} Группы вызовов /domain/groups*
GET /calls?... История звонков (query пробрасывается) GET /domain/call_history
GET /calls/stat Статистика звонков GET /domain/call_history/stat
GET /calls/{id}/protocol Протокол звонка GET /domain/call_history/{id}/protocol
GET /calls/{id}/record Запись разговора (audio/*) GET /domain/call_history/{id}/record
GET /numbers Номера и маршрутизация GET /domain/numbers
GET /balance Баланс лицевого счёта GET /domain/payments/balance
GET /settings Настройки домена GET /domain/settings

Прозрачный прокси

Любой эндпоинт ВАТС доступен через ANY /proxy/{path} → /webapi/{path} (query, тело и метод пробрасываются; бинарные ответы отдаются как есть):

curl http://localhost:8010/proxy/domain/payments/balance -H "$KEY"
curl -X POST http://localhost:8010/proxy/callcenter/reports/by_calls \
     -H "$KEY" -H 'Content-Type: application/json' -d '{"date_from":"2026-08-01"}'

Карта эндпоинтов ВАТС (auth, domain/, callcenter/, user/*, meetings, ivr …) — в исходнике ЛК lk_new/assets/index-*.js (грепать callApi("/...).

Тесты

.venv/bin/python -m pytest -q

Моки через respx, реальных запросов к ВАТС нет.

Навык для нейросетей

MCP-сервер (mcp_server/)

MCP-сервер rtk-vats (stdio) с типизированными инструментами vats_* — подключается к любому агенту с поддержкой MCP (Kimi Code, Claude Code/Desktop, Cursor). Ходит в этот REST API по HTTP, поэтому запускается на машине агента:

{
  "mcpServers": {
    "rtk-vats": {
      "command": "/path/to/rtk-vats-api/.venv/bin/python",
      "args": ["-m", "mcp_server.server"],
      "cwd": "/path/to/rtk-vats-api",
      "env": {
        "VATS_API_URL": "http://10.10.0.187:8010",
        "VATS_API_KEY": "<тот же API_KEY>"
      }
    }
  }
}

Инструменты: vats_auth_login/code/status/refresh/cancel, vats_contacts_*, vats_domain_users, vats_users_list, vats_groups_list, vats_calls_history, vats_call_protocol, vats_call_record (скачивает в VATS_DOWNLOAD_DIR, по умолчанию ./downloads), vats_balance, vats_numbers, vats_settings, vats_proxy (любой эндпоинт ВАТС).

SKILL.md (skills/rtk-vats/)

Готовый скилл для CLI-агентов (Claude Code / Kimi Code и совместимых): флоу входа (логин/пароль → SMS), эндпоинты, правила безопасности и справочник references/pbx-setup.md по настройке АТС (абоненты, группы, IVR, расписания). Установка — скопировать или сделать symlink skills/rtk-vats/ в каталог скиллов агента (проектный .kimi/skills/, .claude/skills/ или пользовательский).

Деплой (Docker)

cp .env.example .env      # заполнить PBX_USERNAME/PBX_PASSWORD, API_KEY
docker compose up -d --build
docker compose logs -f

Образ по умолчанию включает Chromium для входа через Паспорт. Лёгкий вариант без него — docker build --build-arg WITH_BROWSER=0 -t rtk-vats-api:slim .; тогда вход выполняется снаружи (scripts/login_helper.py) или через /auth/import.

⚠️ Порт 8010 держать в локальной сети или за VPN и не публиковать в интернет: за ним живая сессия вашей АТС. Ключ API_KEY — единственная защита самого сервиса.

Безопасность

  • Пароль, SMS-коды и токены не логируются; .env и data/ в .gitignore.
  • PBX_VERIFY_SSL=false — только для машин за корпоративным MITM-прокси (иначе цепочка сертификата не сходится). На сервере оставить true.
  • Второй фактор не обходится: SMS-код вводит человек, один раз на сессию.
  • Незавершённая попытка входа закрывается по таймауту — браузер не остаётся висеть.

Если РТК поменяет API

Точка правки одна: app/pbx_client.py (авторизация/refresh) + соответствующий роутер в app/routers/. Прокси /proxy/* продолжит работать, пока не изменится сама схема путей.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured