通过Aviasales搜索机票、Travelata+Level.Travel搜索旅游团、Sputnik8搜索短途旅行,提供实时价格和预订链接。用于用户询问...
Search tours, hotels, flights, trains, and activities through a single MCP-backed CLI.
bash
python scripts/travel_search.py <command> --input '<JSON object>'
python scripts/travel_search.py describe <command>
python scripts/travel_search.py list-tools
Commands: search-tours, cheapest-tours, search-hotels, get-tour-details, search-flights, flight-calendar, search-trains, search-activities, list-destinations.
Parameters below and in references/usage.md are current. Run describe <command> once per command when you need a field not documented here; never invent fields from memory.
bash
python scripts/travel_search.py search-tours --input '{"departure_city":"Москва","country":"Турция","date_from":"YYYY-MM-DD","date_to":"YYYY-MM-DD","nights_min":7,"nights_max":10,"adults":2,"meal":"AI"}'
python scripts/travel_search.py search-flights --input '{"origin":"MOW","destination":"AYT","depart_date":"YYYY-MM-DD","adults":1}'
python scripts/travel_search.py search-trains --input '{"origin":"Москва","destination":"Сочи","depart_date":"YYYY-MM-DD","sort":"price","limit":5}'
python scripts/travel_search.py search-activities --input '{"city":"Анталья","date_from":"YYYY-MM-DD","date_to":"YYYY-MM-DD","persons":2,"children_allowed":true,"sort":"recommended","limit":5}'
YYYY-MM-DD в примерах — заполнитель. Сначала определите сегодняшнюю дату; если она неизвестна, выполните date +%F. Все даты передавайте в формате YYYY-MM-DD и не раньше сегодняшней, месяц для flight-calendar — в формате YYYY-MM. Если год не назван («15 сентября», «в мае»), имеется в виду ближайший такой день или месяц в будущем.
Treat these as non-negotiable filters — do not silently relax them:
If children are in the party and ages are unknown, ask for ages before presenting bookable family prices. Do not invent ages for pricing.
Budget: never auto-show offers that break a hard budget. Alternatives outside any hard constraint may appear only after explicit user consent, and only in a separate labeled section. Alternatives that satisfy every hard constraint (e.g. other hotels when the named ones do not fit) need no consent.
NeedCommandPackage tour (flight + hotel)search-toursQuick cheapest tours, Travelata onlycheapest-toursHotel only (no flight)search-hotelsFresh price/availability before booking a tourget-tour-detailsFlight optionssearch-flightsFlight price calendar / flexible datesflight-calendarTrain schedule and indicative faressearch-trainsExcursions and activitiessearch-activitiesResolve destinations / directorieslist-destinations
Если город экскурсий не найден, попробуйте ближайший крупный город или туристический центр. search-activities ищет по теме через query («сафари», «острова») и принимает необязательные date_from и date_to в формате YYYY-MM-DD ( date_from ≤ date_to), persons от 1 до 100 и булево children_allowed. Сортировка: recommended (по умолчанию), price, rating или reviews. В каждой записи указан источник provider, единица цены price_unit ( per_person, per_group, per_ticket или unknown) и понятный текст price_text. Сравнивайте цены только при одинаковом price_unit; сортировка price не смешивает разные единицы.
date_from… date_to — окно дат вылета (для search-hotels — заезда) не длиннее 31 дня, то есть до календарного месяца.list-destinations с {"country": "…"} даёт точные названия для resort; resorts_level_travel_only — места, которые есть только у Level.Travel (по ним ищет только он).nights_min и nights_max явно (по умолчанию 7–10) и держите диапазон не шире 5 значений: Level.Travel ищет только nights_min… nights_min +4 (сервер сузит диапазон и добавит примечание), Travelata — весь диапазон. Для более широкого диапазона сделайте несколько поисков по очереди.meal (в cheapest-tours — список meals) передавайте кодом: RO — без питания, BB — завтраки, HB — полупансион, FB — полный пансион, AI — всё включено, UAI — ультра всё включено.search-hotels тоже требует departure_city: передайте домашний город пользователя, а если он неизвестен — «Москва». Город влияет только на доступность предложений.beach_distance_m и beach_line — данные источника; null значит «неизвестно», а не «близко». Рейтинг — по шкале 0–10.more_offers — сколько ещё дат и вариантов у отеля.cheapest-tours — быстрый обзор самых дешёвых туров только из Travelata; для выбранного предложения вызовите get-tour-details с его offer_id.search-flights: return_date ( YYYY-MM-DD) необязателен. Поездку туда-обратно длиннее 30 дней сервер ищет как два перелёта в одну сторону: у элементов есть leg ( outbound или return), итоговая цена — их сумма. Поиск в одну сторону возвращает самый дешёвый вариант на каждую дату — часто это один результат. Цены всегда для эконом-класса, даже если trip_class ≠ 0.price_total_adults — сумма за взрослых. Детские тарифы источник не даёт — так и скажите. one_way_combo — два билета в одну сторону, когда они дешевле туда-обратно. Время в departure_at местное: вылет в 00:55 — это ночь накануне.flight-calendar и дайте ссылку.flight-calendar: month в формате YYYY-MM; цены — за билет в одну сторону.При ошибке CLI завершается с кодом 1 и печатает {"error":true,"category":…,"message":…}; для tool_error в message — текст сервера.
rate_limited — подождите около минуты.search-tours, пока не завершился первый, и не повторяйте его с теми же аргументами. Если результатов мало, расширяйте поиск в рамках жёстких ограничений или с согласия пользователя.date_from = date_to = check-in date, nights_min = nights_max = number of nights. Flexible dates → a date_from… date_to window.price_max for the whole party and the whole stay; convert per-person or per-night budgets first.list-destinations (a district inside a region looks like «Регион: Район»; a resort includes its districts).adults and kids_ages (each child's age).meal, stars_min/ stars_max, beach_distance_max, beach_line_max, center_distance_max). «Первая линия» → beach_line_max 1; «не дальше N м» → beach_distance_max N; «у моря» without a number → beach_distance_max 500 (say so); «в центре» → center_distance_max ≈ 1500; «ровно 4★» → stars_min = stars_max = 4.get-tour-details room names.meal and resort take one value, and meal matches exactly.stars_min = lower bound; if only the lower bound shows up, search the upper bound too.--input as one JSON object (use describe only for a field not documented here).hotels and search the resort where they are (if their resorts are unknown or many, as on atolls, search the country). Properties in different resorts need separate searches. Check that each named_hotels[].hotel really is the property the user meant; a brand may return several ( other_matches). If none fit, run the same search without hotels for alternatives.get-tour-details before booking guidance. The confirmed price may differ from the search price — re-check the budget and say if it changed.named_hotels: fits / does not fit (reason and price) / not found. When nothing fits, say which constraint removed the options and ask before relaxing it.get-tour-details; do not reuse stale offer payloads as live quotes.min_price_rub as confirmed availability.