No description
- Python 90.4%
- Nix 9.6%
Маршрутизатор умел только одну дату — на «маршрут ближе к выходным» модель была вынуждена звать rzd_route по разу на каждый день, что и медленно (перебор хабов на дату), и упирается в потолок итераций хода. Переношу перебор внутрь, как в rzd_search: date_to/weekdays раскрываются в список дат, каждая считается своим изолированным клиентом (RID-механика завязана на cookie-сессию — конкурентно на одном клиенте рвётся), даты идут параллельно с ограничением конкурентности. Ответ сгруппирован по датам с днём недели. Окно капается ≤8 — перебор хабов тяжёлый. Co-Authored-By: Eva |
||
|---|---|---|
| rzd_mcp | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| pyproject.toml | ||
| README.md | ||
rzd-mcp — планировщик поездок по РЖД 🚂
MCP-сервер, которым Ева планирует дорогу по железной дороге: ищет прямые поезда, ловит дни, когда редкий поезд реально ходит, и собирает пересадочные маршруты, когда прямых нет.
Работает поверх неофициального API pass.rzd.ru (тот, что дёргает сам сайт
РЖД). Официального открытого API у РЖД нет — покупку билетов не делаем,
только поиск и планирование; кнопку «купить» Господин жмёт сам на
ticket.rzd.ru.
Инструменты
rzd_stations(query)— станции по части названия и их коды. Для уточнения, если вокзалов несколько.rzd_search(origin, destination, date, date_to?, weekdays?)— прямые поезда.date— YYYY-MM-DD. Перебор дат делает сам сервер, не модель:date_to— искать по всему окну (прямой может ходить не каждый день);weekdays— фильтр дней недели (0=Пн … 6=Вс), напр.[5,6]«ближе к выходным»: окно хоть месяц, проверяются только нужные дни (≤16 запросов). Возвращает поезда, сгруппированные по датам, где они реально есть.
rzd_seats(origin, destination, date, train_number, depart_time)— разбивка мест поезда по вагонам: верхние/нижние (и боковые), с ценами, числом свободных и номерами мест. Номер поезда и время бери изrzd_search. Общий поиск даёт лишь суммарные места по типу вагона — этот инструмент для «нижнее в купе».rzd_route(origin, destination, date, date_to?, weekdays?, budget?, max_transfers?)— маршрут с пересадками, когда прямых нет или они дороже бюджета. Перебирает узловые станции (Москва, СПб, Ростов, Воронеж…), склеивает рейсы по времени (прибытие + запас ≤ отправление) и ранжирует по времени в пути и цене.budget— потолок суммарной цены, руб.date_to/weekdays— как вrzd_search: окно дат перебирается внутри инструмента (даты считаются параллельно, изолированными сессиями), один вызов на «ближе к выходным». Окно капается ≤8 дат — перебор хабов на дату тяжёлый.
Как это устроено
client.py— HTTP-клиент. Станции:/suggester(важно: РЖД матчит только ВЕРХНИЙ регистр, отдаёт широкий список — клиент сам берёт точное/префиксное совпадение по приоритету). Поиск:/timetableдвухшагово через RID (первый запрос отдаёт id, по нему опрашиваем готовый результат).route.py— склейка пересадок через хабы, ранжирование.server.py— MCP-инструменты (FastMCP, транспорт stdio).
Запуск
nix run . # или: nix build && ./result/bin/rzd-mcp
Прокси (если хост не видит pass.rzd.ru напрямую) — через переменную
RZD_PROXY=socks5h://….
Подключение к ядру Евы
MCP-сервер stdio, ядро спавнит его само. В конфиге ядра:
mcp:
servers:
rzd:
command: ["rzd-mcp"]
# env: { RZD_PROXY: "socks5h://127.0.0.1:1080" }
На NixOS — nixosModules.default кладёт пакет в систему и (опционально)
пробрасывает RZD_PROXY; подключение к ядру настраивается в infra.
Ограничения
- Не покупает билеты (авторизация + капча + оплата — вне зоны).
- Перебор диапазона капается (≤16 запросов), чтобы не долбить РЖД.
- Хабы для пересадок — фиксированный список крупных узлов; экзотические стыковки через мелкие станции не строятся.