cyah.ai › Developers › Tools

cyah MCP · developers

Tools reference

All MCP tools for stays, flights and trains: parameters, responses and real examples.

The server has 10 tools in three areas. Every tool takes JSON arguments and returns JSON in structuredContent. Dates are YYYY-MM-DD, prices in EUR for the whole party. Ids and keys (place_id, hotel_id, offer_key) are passed verbatim to the next tool.

Why this reference? An MCP client fetches names and parameters automatically through tools/list, and an LLM can work with that. What is not in the schema is here: how the tools connect, what the response fields mean, examples, and what is different in the sandbox.

Stays

Destination → search hotels → view rooms → booking link. search_destinations also returns airport codes for flights.

search_destinations

Find destinations and airports scope: searchread-only Try it →

Turns a place name into ids: place_id for search_hotels (city, region, country or hotel) and airport IATA codes for search_flights. Always the first step for hotels and flights.

Description for the model (tools/list)

Use this when a place name needs to be turned into ids for a search: cities, regions, countries and hotels for search_hotels (place_id) and airports for search_flights (IATA code). Returns up to 10 matches per type.

Parameters

ParameterTypeDefaultDescription (from the schema)
query requiredstringPlace, hotel or airport name, at least 3 characters
typesstring"hotel,flight"Comma-separated id types to return: hotel, flight. Default both
languagestring"en"en or nl

Key response fields

hotel_places[].place_idId for search_hotels: city:…, destination:…, region:…, country:… or hotel:…
hotel_places[].kindKind of place (city, destination, hotel, …)
airports[].iataIATA code for search_flights
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_destinations",
    "arguments": {
      "query": "Barcelona"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "query": "Barcelona",
  "hotel_places": [
    {
      "kind": "city",
      "name": "Barcelona",
      "country": "Spain",
      "region": "Barcelona & surrounding area",
      "place_id": "city:587"
    },
    {
      "kind": "city",
      "name": "Barcelona",
      "country": "Venezuela",
      "region": "Venezuela",
      "place_id": "city:27658"
    },
    {
      "kind": "destination",
      "name": "Barcelona & surrounding area",
      "country": "Spain",
      "place_id": "destination:1315"
    },
    "… 7 more"
  ],
  "airports": [
    {
      "iata": "BCN",
      "name": "Barcelona–El Prat Josep Tarradellas Airport",
      "city": "Barcelona",
      "country": "Spain"
    },
    {
      "iata": "BLA",
      "name": "General José Antonio Anzoátegui International Airport",
      "city": "Barcelona",
      "country": "Venezuela"
    }
  ],
  "prices_hidden": true
}

search_hotels

Search hotels scope: searchread-only Try it →

Live availability and prices of hotels in a place for the given dates and party. Checks up to 200 hotels with all our suppliers and returns the 10 cheapest or best matching.

Description for the model (tools/list)

Use this when the user wants hotel availability and prices for a place and dates. Needs a place_id from search_destinations (e.g. city:587). Checks up to 200 Youmalou hotels in that place live with all suppliers and returns up to 10 hotels with the cheapest total price for the whole stay and party, board, star rating and cancellation terms. Optionally filtered on star rating (stars). See price_note for what the price includes.

Parameters

ParameterTypeDefaultDescription (from the schema)
place_id requiredstringplace_id from search_destinations, e.g. city:587
check_in requiredstringCheck-in date YYYY-MM-DD
check_out requiredstringCheck-out date YYYY-MM-DD
adultsnumber2Number of adults, 1-9
children_agesstring""Comma-separated ages of children (0-17), empty if none
roomsnumber1Number of rooms, 1-4
sortstring"recommended"price or recommended
max_pricenumber0Maximum total price for the stay in EUR, 0 for no limit
starsstring""Only hotels with this star rating, e.g. '3' or '3,4' (3 includes 3.5). Empty for all ratings; only set it when the user asks for a star rating. With stars the results are sorted by price, cheapest first.
languagestring"en"en or nl

Key response fields

hotels[].hotel_idId for get_hotel_offer and prepare_booking
hotels[].total_priceTotal price for the whole stay and party (EUR)
hotels[].price_per_nightPrice per night
hotels[].board / board_textMeals: RO, BB, HB, FB, AI
hotels[].cancellationrefundable, free_cancellation, free_cancellation_until
price_noteShow this text with the prices
prices_as_ofOnly when the result comes from the cache (max. 15 min)
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_hotels",
    "arguments": {
      "place_id": "city:587",
      "check_in": "2026-12-11",
      "check_out": "2026-12-13",
      "adults": 2,
      "stars": "3",
      "language": "en"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "check_in": "2026-12-11",
  "check_out": "2026-12-13",
  "nights": 2,
  "guests": 2,
  "rooms": 1,
  "hotels_checked": 200,
  "total_found": 100,
  "price_note": "Prices are hidden in this environment (staging / developer sandbox). Production returns live prices in these fields.",
  "hotels": [
    {
      "hotel_id": 221445,
      "name": "Exe Mitre",
      "stars": 3,
      "city": "Barcelona",
      "country": "Spain",
      "currency": "EUR",
      "board": "RO",
      "board_text": "Room Only",
      "cancellation": {
        "refundable": false,
        "free_cancellation": false,
        "free_cancellation_until": null
      },
      "room_options": 56,
      "image_url": "https://staging.mcp.cyah.ai/img/221445.webp?v=1793639698"
    },
    {
      "hotel_id": 222561,
      "name": "HG City Suites Barcelona",
      "stars": 3,
      "city": "Barcelona",
      "country": "Spain",
      "currency": "EUR",
      "board": "RO",
      "board_text": "Room Only",
      "cancellation": {
        "refundable": false,
        "free_cancellation": false,
        "free_cancellation_until": null
      },
      "room_options": 26,
      "image_url": "https://staging.mcp.cyah.ai/img/222561.webp?v=1793639690"
    },
    "… 8 more"
  ],
  "book_on_website": "https://cyah.ai",
  "note": "Checked the first 200 Youmalou hotels in this area.",
  "prices_hidden": true
}

get_hotel_offer

Get hotel rooms and details scope: searchread-only Try it →

All room types and rates of one hotel, with photos, description, facilities and cancellation terms. Use the result to call prepare_booking.

Description for the model (tools/list)

Use this when the user wants the rooms, photos or details of one hotel: description, facilities, room facilities, all hotel photos (image_urls) and every available room type with beds, details, room photos when the supplier has them, and per board the total price and cancellation terms (cheapest supplier). Pass hotel_id from search_hotels; if you no longer know the id, pass hotel_name plus city instead. If the hotel is not in the given city or the name is ambiguous, it returns status not_found_in_city / ambiguous with suggestions (hotels with that name in other cities); show those to the user instead of saying the hotel does not exist.

Parameters

ParameterTypeDefaultDescription (from the schema)
hotel_idstring""hotel_id from search_hotels or search_destinations (e.g. 702885 or hotel:702885). Leave empty if unknown and use hotel_name + city
hotel_namestring""Hotel name as shown to the user. Always pass it; it is used to check the id or to find the hotel
citystring""City of the hotel, used with hotel_name
check_in requiredstringCheck-in date YYYY-MM-DD
check_out requiredstringCheck-out date YYYY-MM-DD
adultsnumber2Number of adults, 1-9
children_agesstring""Comma-separated ages of children (0-17), empty if none
roomsnumber1Number of rooms, 1-4
boardstring""Optional board filter: RO room only, BB breakfast, HB half board, FB full board, AI all inclusive. Empty for all
refundable_onlybooleanfalseOnly rooms that can still be cancelled free of charge
languagestring"en"en or nl

Key response fields

rooms[].roomRoom type, pass it verbatim to prepare_booking
rooms[].offers[]Rates: board, total_price, cancellation, pay_at, notes
image_urls / featured_photosHotel photos (featured_photos are checked)
description / rooms_descriptionTexts in the requested language
statusOnly on problems: not_found_in_city, ambiguous or not_found, with suggestions
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_hotel_offer",
    "arguments": {
      "hotel_id": 221445,
      "check_in": "2026-12-11",
      "check_out": "2026-12-13",
      "adults": 2,
      "language": "en"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "hotel_id": 221445,
  "name": "Exe Mitre",
  "stars": 3,
  "city": "Barcelona",
  "country": "Spain",
  "address": "Bertrán 9-15",
  "description": "The hotel is located near to the Parque Güell and the worthwhile attraction of Casa-Museu Gaudí. Links to the public transport network, restaurants and bars are all to be…",
  "rooms_description": "Air conditioning and central heating ensure that rooms maintain comfortable temperatures. Rooms have a double bed or a queen-size bed. Extra beds can be requested. A safe…",
  "facilities": [
    "aircon",
    "reception24",
    "safe",
    "foyer",
    "… 21 more"
  ],
  "room_facilities": [
    "bath",
    "shower",
    "bathtub",
    "… 12 more"
  ],
  "featured_photos": [
    "https://hotelimages.sunhotels.net/HotelInfo/hotelImage.aspx?id=12080981",
    "… 2 more"
  ],
  "image_urls": [
    "https://hotelimages.sunhotels.net/HotelInfo/hotelImage.aspx?id=12081011",
    "https://hotelimages.sunhotels.net/HotelInfo/hotelImage.aspx?id=12081012",
    "… 38 more"
  ],
  "photos_total": 369,
  "check_in": "2026-12-11",
  "check_out": "2026-12-13",
  "nights": 2,
  "price_note": "Prices are hidden in this environment (staging / developer sandbox). Production returns live prices in these fields.",
  "rooms_total": 11,
  "offers_total": 56,
  "rooms": [
    {
      "room": "Double/Twin (2 People)",
      "offers": [
        {
          "board": "RO",
          "board_text": "Room Only",
          "currency": "EUR",
          "cancellation": {
            "refundable": false,
            "free_cancellation": false,
            "free_cancellation_until": null
          },
          "pay_at": "online",
          "notes": "From the date of: 31/10/2012 City Tax direct payment at the hotel [amount hidden] per person and night. (VAT included). From 1 April 2026, the rate will be [amount hidden…"
        },
        {
          "board": "RO",
          "board_text": "Room Only",
          "currency": "EUR",
          "cancellation": {
            "refundable": true,
            "free_cancellation": true,
            "free_cancellation_until": "2026-12-08T10:00:00Z"
          },
          "pay_at": "online",
          "notes": "From the date of: 31/10/2012 City Tax direct payment at the hotel [amount hidden] per person and night. (VAT included). From 1 April 2026, the rate will be [amount hidden…"
        },
        "… 2 more"
      ]
    },
    "… 10 more"
  ],
  "book_on_website": "https://cyah.ai",
  "prices_hidden": true
}

find_hotel

Find a hotel by name scope: searchread-only Try it →

Finds a hotel by name, worldwide or in a city (no prices). Useful when a user names a specific hotel.

Description for the model (tools/list)

Use this when the user names a specific hotel and you need to know where it is or which hotel they mean, or when get_hotel_offer reports the hotel is not in the given city. Searches the hotel database worldwide by name (no prices) and returns matches with hotel_id, city, country and stars; with city, matches in that city are listed separately in in_city.

Parameters

ParameterTypeDefaultDescription (from the schema)
hotel_name requiredstringHotel name as typed by the user
citystring""Optional city the user mentioned; leave empty to search worldwide
languagestring"en"en or nl

Key response fields

in_city[]Matches in the given city
matches[]Other matches worldwide: hotel_id, city, country, stars, photo
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "find_hotel",
    "arguments": {
      "hotel_name": "Hotel Arts",
      "city": "Barcelona"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "hotel_name": "Hotel Arts",
  "city": "Barcelona",
  "in_city": [
    {
      "hotel_id": 219476,
      "name": "Arts Barcelona",
      "stars": 5,
      "city": "Barcelona",
      "country": "Spain",
      "photo": "https://i.travelapi.com/lodging/1000000/10000/3800/3780/a5fdbdb1_y.jpg",
      "photos": [
        "https://i.travelapi.com/lodging/1000000/10000/3800/3780/a5fdbdb1_y.jpg",
        "… 2 more"
      ]
    },
    "… 1 more"
  ],
  "matches": [
    {
      "hotel_id": 203804,
      "name": "Hotel Arts",
      "stars": 4,
      "city": "Sankt Leon-Rot",
      "country": "Germany",
      "photo": "https://i.travelapi.com/lodging/25000000/24310000/24300600/24300526/de42d2a0_y.jpg",
      "photos": [
        "https://i.travelapi.com/lodging/25000000/24310000/24300600/24300526/de42d2a0_y.jpg",
        "… 2 more"
      ]
    },
    {
      "hotel_id": 81794,
      "name": "Hotel Arts",
      "stars": 3,
      "city": "Calgary",
      "country": "Canada",
      "photo": "https://images.dnatatravel.com/ei/3/2/5/8/2/8/0.jpg"
    },
    "… 8 more"
  ],
  "prices_hidden": true
}

prepare_booking

Prepare a hotel booking scope: booking Try it →

Re-checks the chosen room rate and returns a booking_url: the secure cyah.ai booking page where the guest enters their details and pays.

Description for the model (tools/list)

Use this when the user wants to book (reserve and pay for) a specific room that get_hotel_offer returned. Pass the same hotel_id, dates and guests, plus the room type exactly as in rooms[].room and the board and free_cancellation of the chosen offer. Returns booking_url: a secure booking page where the guest enters name and e-mail and pays with Stripe; show it as a Markdown link. Never ask for card details in the chat.

Parameters

ParameterTypeDefaultDescription (from the schema)
hotel_id requiredstringhotel_id from get_hotel_offer
hotel_namestring""Hotel name, used to check the id
citystring""City of the hotel
check_in requiredstringCheck-in date YYYY-MM-DD
check_out requiredstringCheck-out date YYYY-MM-DD
adultsnumber2Number of adults, 1-9
children_agesstring""Comma-separated ages of children (0-17), empty if none
roomsnumber1Number of rooms, 1-4
room requiredstringRoom type exactly as in get_hotel_offer rooms[].room
boardstring""board of the chosen offer (e.g. BB, RO) or its board_text when board is empty
free_cancellationstring""'true' or 'false' as in the chosen offer's cancellation.free_cancellation; empty if not chosen
languagestring"en"en or nl

Key response fields

booking_urlLink to the booking page; show it as a link, the guest pays there
total_price / cancellationRe-checked price and terms
test_modetrue in the sandbox
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "prepare_booking",
    "arguments": {
      "hotel_id": "221445",
      "hotel_name": "Exe Mitre",
      "city": "Barcelona",
      "check_in": "2026-12-11",
      "check_out": "2026-12-13",
      "adults": 2,
      "room": "Double/Twin (2 People)",
      "board": "RO",
      "free_cancellation": "false",
      "language": "en"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "booking_url": "https://cyah.ai/en/book/?t=221445-20261211-20261213-2-x-1-RO-0-en-s-f77bb3be.pacaWjIqnZzp",
  "hotel": "Exe Mitre",
  "room": "Double/Twin (2 People)",
  "board": "RO",
  "board_text": "Room Only",
  "check_in": "2026-12-11",
  "check_out": "2026-12-13",
  "nights": 2,
  "currency": "EUR",
  "cancellation": {
    "refundable": false,
    "free_cancellation": false,
    "free_cancellation_until": null
  },
  "test_mode": true,
  "note": "Show booking_url as a Markdown link (e.g. [Boek en betaal](url)).Never ask for card details in the chat.",
  "prices_hidden": true
}

Flights

Airport codes from search_destinations (or known IATA codes) → search_flights → prepare_flight_booking.

search_flights

Search flights scope: searchread-only Try it →

Searches flights with several suppliers at the same time, including directly with airlines (NDC): one-way or return, cabin class and maximum stops. Every offer has an offer_key.

Description for the model (tools/list)

Use this when the user wants flight offers between two airports. Needs IATA codes (from search_destinations when unknown). Searches several flight suppliers at the same time (one-way or return, cabin class, maximum stops) and returns up to 10 offers sorted by total price for all passengers. Each offer has provider, offer_key and bookable; pass offer_key to prepare_flight_booking when the user wants to book.

Parameters

ParameterTypeDefaultDescription (from the schema)
origin requiredstringIATA code of the departure airport, e.g. AMS
destination requiredstringIATA code of the arrival airport, e.g. BCN
departure_date requiredstringOutbound date YYYY-MM-DD
return_datestring""Return date YYYY-MM-DD, empty for one-way
adultsnumber1Adults, 1-9
childrennumber0Children aged 2-11
infantsnumber0Infants under 2
cabinstring"any"economy, premium_economy, business, first or any
max_stopsnumber-1Maximum stops 0-2, -1 for no limit

Key response fields

offers[].offer_keyKey for prepare_flight_booking (copy verbatim)
offers[].bookableOnly bookable offers can go to prepare_flight_booking
offers[].legs[]Per direction: times, duration, stops, flight numbers, baggage
offers[].expires_atUntil when the offer is valid
price_noteShow this text with the prices
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_flights",
    "arguments": {
      "origin": "AMS",
      "destination": "BCN",
      "departure_date": "2026-12-11",
      "return_date": "2026-12-13",
      "adults": 1
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "route": "AMS-BCN",
  "departure_date": "2026-12-11",
  "return_date": "2026-12-13",
  "total_found": 246,
  "offers": [
    {
      "airline": "Transavia Holland",
      "currency": "EUR",
      "legs": [
        {
          "origin": "AMS",
          "destination": "BCN",
          "departure": "2026-12-11T14:40",
          "arrival": "2026-12-11T16:55",
          "duration": "PT2H15M",
          "stops": 0,
          "carriers": [
            "Transavia Holland"
          ],
          "flight_numbers": [
            "HV5133"
          ],
          "fare": "Basic",
          "checked_bags": 0,
          "cabin_bags": 0
        },
        {
          "origin": "BCN",
          "destination": "AMS",
          "departure": "2026-12-13T14:20",
          "arrival": "2026-12-13T16:50",
          "duration": "PT2H30M",
          "stops": 0,
          "carriers": [
            "Transavia Holland"
          ],
          "flight_numbers": [
            "HV5132"
          ],
          "fare": "Basic",
          "checked_bags": 0,
          "cabin_bags": 0
        }
      ],
      "expires_at": "2026-11-02T18:32:08.598778Z",
      "conditions": {
        "refund": null,
        "change": null
      },
      "offer_key": "FDs-AMSBCN-20261211-20261213-100-x-dbcc721a~034qipKrhEZ4D6JHMQLTZQ",
      "bookable": true,
      "passport_required": false
    },
    {
      "airline": "British Airways",
      "currency": "EUR",
      "legs": [
        {
          "origin": "AMS",
          "destination": "BCN",
          "departure": "2026-12-11T07:44",
          "arrival": "2026-12-11T09:58",
          "duration": "PT2H14M",
          "stops": 0,
          "carriers": [
            "British Airways"
          ],
          "flight_numbers": [
            "BA1516"
          ],
          "fare": "Basic",
          "checked_bags": 1,
          "cabin_bags": 1
        },
        {
          "origin": "BCN",
          "destination": "AMS",
          "departure": "2026-12-13T09:17",
          "arrival": "2026-12-13T11:31",
          "duration": "PT2H14M",
          "stops": 0,
          "carriers": [
            "British Airways"
          ],
          "flight_numbers": [
            "BA1516"
          ],
          "fare": "Basic",
          "checked_bags": 1,
          "cabin_bags": 1
        }
      ],
      "expires_at": "2026-11-02T18:02:08.436163Z",
      "conditions": {
        "refund": {
          "allowed": true,
          "penalty": 20,
          "currency": "EUR"
        },
        "change": {
          "allowed": false,
          "penalty": null,
          "currency": null
        }
      },
      "offer_key": "FDs-AMSBCN-20261211-20261213-100-x-24842e57~034qipKaLRYVWzU43m5crQ",
      "bookable": true,
      "passport_required": false
    },
    "… 8 more"
  ],
  "price_note": "Prices are hidden in this environment (staging / developer sandbox). Production returns live prices in these fields.",
  "booking": "Bookable offers (bookable true) can be booked with prepare_flight_booking(offer_key).",
  "prices_hidden": true
}

prepare_flight_booking

Prepare a flight booking scope: booking Try it →

Checks that the flight offer is still available and returns a booking_url where the traveller enters passenger details, picks seats and extras, and pays.

Description for the model (tools/list)

Use this when the user wants to book a specific flight offer from search_flights. Pass its offer_key exactly as returned. Checks that the offer is still available and returns booking_url: a secure booking page where the traveller enters the passenger details and pays with Stripe; show it as a Markdown link. Never ask for passport, passenger or card details in the chat.

Parameters

ParameterTypeDefaultDescription (from the schema)
offer_key requiredstringoffer_key of the chosen offer from search_flights, copied exactly
languagestring"en"en or nl

Key response fields

booking_urlLink to the booking page (passengers, seats, extras, payment)
total_price / legsRe-checked price and itinerary
documents_requiredtrue when the airline needs passport details (on the booking page)
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "prepare_flight_booking",
    "arguments": {
      "offer_key": "FDs-AMSBCN-20261211-20261213-100-x-dbcc721a~034qipKrhEZ4D6JHMQLTZQ",
      "language": "en"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "booking_url": "https://cyah.ai/en/book/?t=FDs-AMSBCN-20261211-20261213-100-x-dbcc721a~034qipKrhEZ4D6JHMQLTZQ",
  "kind": "flight",
  "offer_key": "FDs-AMSBCN-20261211-20261213-100-x-dbcc721a~034qipKrhEZ4D6JHMQLTZQ",
  "route": "AMS-BCN",
  "origin": "AMS",
  "destination": "BCN",
  "departure_date": "2026-12-11",
  "return_date": "2026-12-13",
  "adults": 1,
  "children": 0,
  "infants": 0,
  "passengers": [
    "adult"
  ],
  "cabin": "any",
  "language": "en",
  "test_mode": true,
  "dry_run": false,
  "airline": "Transavia Holland",
  "legs": [
    {
      "origin": "AMS",
      "destination": "BCN",
      "departure": "2026-12-11T14:40",
      "arrival": "2026-12-11T16:55",
      "duration": "PT2H15M",
      "stops": 0,
      "carriers": [
        "Transavia Holland"
      ],
      "flight_numbers": [
        "HV5133"
      ],
      "fare": "Basic",
      "checked_bags": 0,
      "cabin_bags": 0
    },
    {
      "origin": "BCN",
      "destination": "AMS",
      "departure": "2026-12-13T14:20",
      "arrival": "2026-12-13T16:50",
      "duration": "PT2H30M",
      "stops": 0,
      "carriers": [
        "Transavia Holland"
      ],
      "flight_numbers": [
        "HV5132"
      ],
      "fare": "Basic",
      "checked_bags": 0,
      "cabin_bags": 0
    }
  ],
  "currency": "EUR",
  "conditions": {
    "refund": null,
    "change": null
  },
  "expires_at": "2026-11-02T18:33:19.380651Z",
  "documents_required": false,
  "note": "Show booking_url as a Markdown link (e.g. [Boek en betaal](url)).Never ask for passport or card details in the chat.",
  "prices_hidden": true
}

Trains

Place names can go straight into search_trains; search_train_stations only when in doubt. Return trip = two booking links or one cart.

search_train_stations

Search train stations scope: searchread-only Try it →

Finds train stations and city codes (e.g. FR:paris). Only needed when a place name is ambiguous; search_trains also accepts plain names.

Description for the model (tools/list)

Use this to find station or city codes for a place name (e.g. Paris, Amsterdam Centraal, Keulen). Returns codes like FR:paris (a city: all its stations) or NL:amsterdam_centraal (one station). search_trains also accepts plain names, so only call this when the place is ambiguous.

Parameters

ParameterTypeDefaultDescription (from the schema)
query requiredstringCity or station name, e.g. Paris or Brussel-Zuid
limitnumber10Maximum results, 1-20

Key response fields

results[].codeCode for search_trains, e.g. FR:paris (city) or NL:amsterdam_centraal (station)
results[].typecity or station
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_train_stations",
    "arguments": {
      "query": "Brussels",
      "limit": 4
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "query": "Brussels",
  "results": [
    {
      "code": "BE:brussels",
      "type": "city",
      "name": "Bruxelles",
      "local_name": "Brussels",
      "country": "Belgium"
    },
    {
      "code": "BE:bruxelles_nord",
      "type": "station",
      "name": "Bruxelles-Nord",
      "country": "Belgium"
    },
    {
      "code": "BE:brussels_midi",
      "type": "station",
      "name": "Bruxelles/Brussels-Midi",
      "local_name": "Bruxelles-Midi",
      "country": "Belgium"
    },
    "… 1 more"
  ],
  "note": "Use code as origin/destination in search_trains. A city code covers all stations of that city.",
  "prices_hidden": true
}

search_trains

Search trains scope: searchread-only Try it →

Live train journeys in Europe (Eurostar, DB, SNCF, Trenitalia, NS International and more), one-way or return, with the cheapest fare per comfort class.

Description for the model (tools/list)

Use this when the user wants train journeys or train tickets in Europe. Searches live (Eurostar, DB, SNCF, Trenitalia, SNCB, OBB, SBB and more), one-way or return. origin and destination can be a city or station name or a code from search_train_stations. Returns per direction up to 8 journeys from the requested time onwards with times, duration, changes, trains and the cheapest price per comfort class (Standard/Comfort/Premier) for all travellers together. Every fare has an offer_key for prepare_train_booking.

Parameters

ParameterTypeDefaultDescription (from the schema)
origin requiredstringDeparture city or station, name or code, e.g. Amsterdam or NL:amsterdam
destination requiredstringArrival city or station, name or code, e.g. Paris or FR:paris
departure_date requiredstringOutbound date YYYY-MM-DD
departure_timestring"08:00"Earliest departure time HH:MM (local time)
return_datestring""Return date YYYY-MM-DD, empty for one-way
return_timestring"08:00"Earliest return departure time HH:MM
adultsnumber1Adults (18+), 0-9
children_agesstring""Ages of children/youths 0-17, comma separated, e.g. '8,12'; empty if none
direct_onlybooleanfalseOnly direct trains without changes

Key response fields

legs[].journeys[]Per direction up to 8 journeys: times, duration, changes, trains
legs[].journeys[].fares[]Cheapest fare per comfort class with offer_key, flexibility and terms
cheapest_totalCheapest total (return = outbound + return)
suppliers_missingCarriers that did not answer this time
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_trains",
    "arguments": {
      "origin": "Amsterdam",
      "destination": "Brussels",
      "departure_date": "2026-12-11",
      "departure_time": "09:00",
      "adults": 1
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "route": "Amsterdam - Bruxelles",
  "origin": {
    "code": "NL:amsterdam",
    "type": "city",
    "name": "Amsterdam",
    "country": "Netherlands"
  },
  "destination": {
    "code": "BE:brussels",
    "type": "city",
    "name": "Bruxelles",
    "local_name": "Brussels",
    "country": "Belgium"
  },
  "departure_date": "2026-12-11",
  "return_date": null,
  "travellers": {
    "adults": 1,
    "children_ages": []
  },
  "currency": "EUR",
  "legs": [
    {
      "direction": "outbound",
      "origin": "Amsterdam",
      "destination": "Bruxelles",
      "searched_from": "2026-12-11T09:00:00",
      "journeys": [
        {
          "departure": "2026-12-11T09:03:00",
          "arrival": "2026-12-11T11:11:00",
          "duration": "2h08m",
          "changes": 0,
          "from_station": "Amsterdam Zuid",
          "to_station": "Bruxelles/Brussels-Midi",
          "trains": [
            {
              "train": "Eurocity Direct 9524",
              "carrier": "Eurocity Direct",
              "from": "Amsterdam Zuid",
              "to": "Bruxelles/Brussels-Midi",
              "departure": "2026-12-11T09:03:00",
              "arrival": "2026-12-11T11:11:00"
            }
          ],
          "fares": [
            {
              "comfort": "Standard",
              "fare": "Saver",
              "offer_key": "Rs-NL:amsterdam-BE:brussels-202612110900-30-0903-8b73c668-S",
              "class": "2nd class",
              "flexibility": "Semi Flex",
              "refundable": "WITH_CONDITION",
              "exchangeable": "NO"
            },
            {
              "comfort": "Comfort",
              "fare": "Saver",
              "offer_key": "Rs-NL:amsterdam-BE:brussels-202612110900-30-0903-8b73c668-C",
              "class": "1st class",
              "flexibility": "Semi Flex",
              "refundable": "WITH_CONDITION",
              "exchangeable": "NO"
            }
          ]
        },
        "… 7 more"
      ]
    }
  ],
  "price_note": "Prices are hidden in this environment (staging / developer sandbox). Production returns live prices in these fields.",
  "booking": "Each fare has an offer_key: pass it to prepare_train_booking when the user wants to book (one key per direction; a return trip = two bookings, or add both to the cart).",
  "seat_note": "Fares with seat_choice let the traveller pick a seat preference (e.g. window or aisle) on the booking page; the carrier tries to honour it but does not guarantee it. An e…",
  "suppliers_missing": [
    "EUROPEANSLEEPER, DBAHN"
  ],
  "prices_hidden": true
}

prepare_train_booking

Prepare train booking scope: booking Try it →

Re-checks the chosen train journey and returns a booking_url (names and birth dates, seat preference, payment). For a return trip: one call per direction.

Description for the model (tools/list)

Use this when the user wants to book a train journey from search_trains. Pass the offer_key of the chosen fare (one direction; for a return trip call it for the outbound and the return fare). Checks the train again and returns booking_url (booking page: traveller names and birth dates, payment with Stripe; it also has a cart to pay hotel, flight and train together) plus a summary.

Parameters

ParameterTypeDefaultDescription (from the schema)
offer_key requiredstringoffer_key of the chosen fare from search_trains, copied exactly
languagestring"nl"nl or en

Key response fields

booking_urlLink to the booking page (names, birth dates, seat preference, payment)
conditionsFare conditions of the carrier
seat_preferencesPossible seat preferences (window, aisle, …)
Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "prepare_train_booking",
    "arguments": {
      "offer_key": "Rs-NL:amsterdam-BE:brussels-202612110900-30-0903-8b73c668-S",
      "language": "en"
    }
  }
}
structuredContent (real sandbox response, shortened, without prices)
{
  "booking_url": "https://cyah.ai/en/book/?t=Rs-NL:amsterdam-BE:brussels-202612110900-30-0903-8b73c668-S",
  "kind": "train",
  "offer_key": "Rs-NL:amsterdam-BE:brussels-202612110900-30-0903-8b73c668-S",
  "route": "Amsterdam - Bruxelles",
  "origin": "Amsterdam",
  "destination": "Bruxelles",
  "date": "2026-12-11",
  "travellers": 1,
  "ages": [
    30
  ],
  "comfort": "STANDARD",
  "language": "en",
  "test_mode": true,
  "dry_run": true,
  "departure": "2026-12-11T09:03:00",
  "arrival": "2026-12-11T11:11:00",
  "duration": "2h08m",
  "from_station": "Amsterdam Zuid",
  "to_station": "Bruxelles/Brussels-Midi",
  "changes": 0,
  "trains": [
    "Eurocity Direct 9524"
  ],
  "fare": "Saver",
  "class": "2nd class",
  "flexibility": "Semi Flex",
  "conditions": "Only valid on the chosen cross-border EuroCity Direct train and date of travel. For other trains on your selected itinerary, no train binding applies. Not valid on EuroCi…",
  "currency": "EUR",
  "seat_preferences": [],
  "note": "Show booking_url as a Markdown link (e.g. [Boek en betaal](url)).The page also has a cart to pay several trips (hotel, flight, train) at once.",
  "prices_hidden": true
}