trip
Search Trip.com through the trip MCP tools and present the results as compact deal cards. Use search_flights for cheap flights and fare calendars on a route, search_hotels for hotel recommendations wi
SKILL.mdskills/trip/SKILL.md
GitHubTrip.com deals
The trip MCP server searches Trip.com and returns normalized results. This skill owns routing, parameter collection and presentation; the tools own retrieval, validation and normalization. Results come with partner tracking already applied to every link.
When the session also provides a booking skill for the request (such as flight-booking or accommodation-booking), that skill decides default dates and occupancy, when to ask, how many searches to run and whether to relax an empty one, the conversation mode, which result to book and how to confirm; pass its chosen values explicitly and use this skill only for tool arguments, errors and result presentation. Otherwise follow the defaults and booking rules below.
| User intent | Tool | Key arguments |
|---|---|---|
| Flights, fares, cheap tickets on a route | search_flights |
departCityCode, startDate, optional arrivalCityCode |
| Hotels and other stays | search_hotels |
cityName, country, latitude, longitude |
| Attraction tickets | search_attractions |
productType: "ticket", cityName |
| Day tours, local experiences | search_attractions |
productType: "play_experience", cityName |
| Airport transfers, pickup, pocket Wi-Fi, SIM cards | search_attractions |
productType: "play_travel_tool", cityName; pass excludeSim: false when the user wants SIM cards |
| Show the chosen results as Trip.com cards | show_results |
requestIds of the searches to show (see Result cards) |
The tools only search: they book nothing and take no payment or personal details, and every result links to Trip.com. When the user only wants options, stop at the results; the user books on Trip.com. When the user asks you to book or pay, this skill does not restrict it. Book only a result the user has chosen; if they have not chosen one, show the results and ask which to book. Open that result's link and continue there with the available browser and payment workflows, following their confirmation and data-handling rules. The booking page reprices: before submitting traveller details or paying, tell the user the page's final price (noting any difference from the card or their budget), the flight or room being booked and its change and cancellation terms.
Language
- Infer the reply language from the current user request without asking and pass it as
languageon every call, so a language change takes effect immediately. - For Simplified Chinese pass
zh-CN; the tool queries the backend withzh-HKcontent unlesslocaleis given. For other languages use the matching BCP 47 code, such asen-USorja-JP. If the language cannot be inferred, usezh-HK. - Write surrounding prose and template labels in the reply language. Preserve returned product titles, route titles and promotion text verbatim.
- Pass
currencyon every call: it sets the returned prices and the currency the Trip.com booking page settles in. Use the currency the user names or will pay in (for example, the only currency their payment method supports); otherwise the currency of the user's country or region;USDwhen neither is known.
Results and errors
Every tool returns JSON. A success is { requestId, deals, ... }; a failure is { requestId, error: { code, message, retryable, fields? }, deals: [] }.
- Explain
error.messagein the reply language without exposingerror.code,requestId, field paths or raw JSON. Suggest retrying later only whenretryableis true; otherwise ask for the corrected input, usingerror.fieldsto name only the values that need correction. trip_api_not_configuredmeans the Trip.com service is not available in this environment yet; say so plainly and do not retry.tool_disabledmeans this kind of Trip.com search is switched off for now; say it is temporarily unavailable and do not retry it.- A success with an empty
dealslist means nothing matched, not that the service failed. Do not callshow_results. Say no Trip.com results matched and suggest relaxing the most restrictive condition the user set (non-stop, airline, cabin, price, free cancellation, distance, dates); search again only if the user agrees. - Never expose tool names, arguments, city codes, internal IDs or raw JSON to the user, except in mock mode below.
- Mock mode. A result with a
debugobject comes from sample data, not Trip.com. Start the reply with one line> 🧪 Debug (mock): {debug.note}translated into the reply language, then handle the result as usual: render the cards with the normal templates (keep the[MOCK]titles), or explainerroras above. Only whendebug.trip_requestis present, end with the heading "Trip request (debug)" anddebug.trip_requestas a fenced JSON block. Never present mock results as real offers or prices, and never book one. - Result cards. Searches never show cards. A search with deals returns its
requestIdandcard_ready: true. First check the results answer the request (for hotels, that they are near the intended place; if they are clearly elsewhere, check the coordinates and search again, ignoring the wrong results). Then callshow_resultsonce with therequestIdof the searches to show, normally the last good search. SeveralrequestIds from the same tool, such as flight searches per arrival code, are merged into one card; call it once per tool when the user asked for different kinds of deals. Never show results you replaced with a new search, and never callshow_resultstwice for the same results. - After
show_resultsreturnscard_shown: true, the user sees the deals as Trip.com cards (a horizontally scrollable row with image, price and a Book link). Do not repeat them as markdown cards or lists. Reply with at most two short sentences: the useful selection sentence from the display rules and, for hotels, the note that the final total, room type, payment terms and cancellation deadline are confirmed on the Trip.com room page. AnOVERVIEWflight search replaces the selection sentence with its route overview (see Flights). Refer to deals by their exact titles. - If
show_resultsfails withresults_not_found, search again once and show the newrequestId. For any other failure, or results you chose not to show, render every deal individually with its product template and the compact-card rules. Do not rewrite titles, replace them with labels such as "Option 1", or summarize several deals into a list. - Render prices, currencies and savings exactly as returned. Never calculate, convert or invent a price, discount or saving, and never add a per-night, per-person, tax, fee or round-trip basis the result does not state.
- Make one search per request unless a rule below says otherwise; do not make extra searches to fill cards or the selection sentence.
Trip timing
Apply these rules whenever flights and a stay are planned together, or a stay length is judged from flight times.
- A hotel night runs from the afternoon check-in (usually 14:00–15:00) to the next morning's checkout (usually 11:00–12:00), in the hotel's local time. Count a stay in hotel nights (check-out date minus check-in date), never in calendar days spent at the destination.
- A flight landing after midnight still needs the room from the night before: the check-in date is the day before the landing date (landing 00:55 on 10 Oct means checking in on 9 Oct). Tell the user the room is booked from the night of arrival so it is held for a late check-in. Such an arrival gives the same number of nights as an evening arrival on the previous day; never reject it as a night short.
- "3 days 2 nights" means two hotel nights between the outbound arrival and the return departure. A late-evening or after-midnight arrival and a return departing after the morning checkout both fit it.
- Flight times are local at each airport;
+1marks arrival on the next local day. Do not convert time zones when matching flights to a stay. - When pairing flights with a hotel search, derive
checkInandcheckOutfrom the flight times with these rules, and state the check-in date whenever it differs from the landing date.
Flights
Search Trip.com flight options for a route from a recent fare cache: each result is one bookable itinerary with times, airports, duration and price. Results come in Trip.com's recommended order, not sorted by price: keep that order and do not call a result the cheapest unless the returned prices show it.
- Pass both departure and arrival three-letter codes; they must differ. Each code is a city or metro area by default (
SHA= all Shanghai airports); setdepartureType/arrivalTypetoAIRPORTwhen the user names an exact airport (AIRPORT: SHA= Hongqiao,AIRPORT: PVG= Pudong). A code with theCITYtype must be a city or metro-area code: many airport codes differ from their city's code (BakuBAK, notGYD; TokyoTYO, notNRT/HND; SapporoSPK, notCTS; Xi'anSIA, notXIY), so use the city code, or keep the airport code and set its type toAIRPORT. A destination is required: if the user gives none, ask for it. - If the destination maps to several city codes, call
search_flightsonce per arrival code concurrently and merge the deals before rendering; show them with oneshow_resultscall listing everyrequestId. startDateandendDatebound the departure date (at most 7 days counting both,endDatedefaults tostartDate);endDateis never a return date. For round trips passtripType: RTandreturnStartDate(optionalreturnEndDate, also at most 7 days).returnStartDatecannot be earlier than the last departure date: for "any day next week, back two days later", search each departure date with its own return date instead of overlapping ranges. Split a departure window longer than 7 days into several searches.- If Trip.com rejects a code (
INVALID_REQUESTnamingdepartCityCode/arrivalCityCode) and the code is not the main airport's own IATA code, search once more with that airport code and theAIRPORTtype (Casablanca:CMN, notCAS). If it already is, Trip.com does not cover that airport: say so and offer a nearby hub. Never retry the same code with the other type. - Passengers default to 1 adult, 0 children, 0 infants; pass the actual counts when known (adults plus children at most 9, infants at most adults).
limitis 1 to 20, default 5. classTypeisOVERVIEWunless the user states a cabin preference. Users rarely name a cabin up front but would still take a business or first class seat they did not know was on sale, so do not default to economy. PassY(economy),W(premium economy),C(business) orF(first) only when the user names or clearly implies that cabin.CandFboth return business and first class;cabinsgives per cabin how many deals Trip.comfound, how many fly that cabin onallLegs, and how many werereturned.isDirectOnly: truereturns non-stop flights only; omit it to allow connections. Red-eye filtering is not available.airlineCodefilters both directions.- After a
CorFsearch, answer for both cabins even if the user named one: whether the requested cabin covers every leg, some legs or none, and the other cabin's lowest price (or itsfoundcount when none was returned). - An
OVERVIEWsearch returns flight counts for economy, business/first and mixed-cabin itineraries, plus a few picked deals;limitdoes not apply. Counts cover Trip.com's first results: say "at least" whenatLeastis true, and never "none" for a category withatLeast: true. Do not say cabins incabinsNotSearchedhave no seats. - After an
OVERVIEWsearch, start the reply with the route overview: dates and route; non-stop, connecting and business/first counts (say plainly when there are none; mention mixed-cabin options if any); then the lowest fare, a notable non-stop and the lowest business/first fare, each with flight, stops and price. For example: "Singapore to Wuhan on 23–24 Oct: 5 non-stop and 9 connecting flights, plus 3 business class options. The lowest is Scoot TR120 non-stop at SGD 208; for more comfort, MU2578 in business class is SGD 995."
Card fields: required title, departureDate, tripType, bookingLinks, currentPrice, currency, priceBasis, journeys; optional returnDate, discountLabel, airlineName, flightNumbers, cabinLabel, nonstopLabel, originalPrice, savingsAmount, cacheUpdatedAt. Each journey carries its departure and arrival airports, local times, duration and connection count. Keep flights without a discount or original price, and never borrow facts from another result.
priceBasis: ADULT_UNIT_PRICEmeans the price is per adult, not the total for every passenger and not proof of taxes included.- Prices are cached. Flight cards already carry the note that fares change often and the booking page shows the final price, so do not repeat it after
show_resultssucceeds. When flights are rendered as text instead, add that note as one short sentence in the reply language; with theCACHED_FARESwarning it is mandatory. The Book link opens booking and repricing; it does not reserve a seat. - For the link use
bookingLinks.online, otherwisebookingLinks.h5; keep the URL intact.
✈️ **{title}** · {departure_summary} · {trip_type_label}
**{currency} {currentPrice}** {price_basis_label} · 🏷️ **{discount_summary}**
{original_price_label} ~~{currency} {originalPrice}~~ · {savings_summary}
{airlineName} {flightNumbers} · {times_and_duration} · {nonstopLabel} · {cabinLabel} · [{view_details_label}]({booking_link})
- Keep the route and actual departure date (and return date for round trips) on the first line; retain the year when needed to avoid ambiguity. Translate
OW/RTinto a one-way / round-trip label and the per-adult basis into the reply language. - Use the returned
discountLabelas{discount_summary}; if absent, omit the offer and icon. If neither reference price nor savings is present, omit the whole third line. - Bold only the route title, current price and returned discount. Join
flightNumbersin their returned order with,.{times_and_duration}is the outbound departure and arrival time (mark a next-day arrival) and duration. A missing non-stop label does not establish a connection. The link label should mean "View flight". - In the selection sentence, identify a choice by route, departure date and time, adding airline or flight numbers only to distinguish otherwise identical choices.
Hotels
Search and recommend Trip.com hotels. Read references/hotel-search.md before applying any optional filter, sort or page control.
Destination
destinationType, cityName and the country are required on every search. Choose the type from what scopes the stay:
CITY: the user wants a hotel anywhere in the city, or only names the city. Pass the city incityName; no coordinates and noname. Trip.com ranks the whole city, which recommends better than a point at the city centre.HOTEL: the user names a specific hotel. Pass its name innameas the user wrote it or as officially spelled, and its city incityName; no coordinates.POI: the user wants to stay near a specific place (a station, airport terminal, landmark, venue, address or district). Pass the place'slatitude/longitudeand its name inname, which labels the distance texts. Keep that place; never broaden it to the city or replace it with a nearby peer.
For POI coordinates, pass WGS84 decimal degrees (the GPS system used by OpenStreetMap and Wikipedia) everywhere, including mainland China, Hong Kong and Macau; the tool converts them where Trip.com needs another system. Use coordinates you know precisely for well-known places; otherwise look the place up first (for example with a web search) and take the point from a WGS84 source. Never use points from Amap (Gaode), Baidu, Tencent Maps or Google Maps inside mainland China, which are shifted by several hundred metres. Never invent, approximate or reuse another place's coordinates.
- Put the containing city in
cityNameso results stay within it, and pass the country or region ascountryName(any language, e.g.Japan,中国,Hong Kong) orcountryCode(e.g.JP,CN,HK; prefer the name, and useUK, notGB). It also disambiguates cities such as Sydney or London. distanceKmand the distance sorts only work withPOI; for "near X" requests, searchPOIat X.- Trip.com knows cities, not every resort area, beach town or neighbourhood. For places such as Seminyak, Uluwatu or Zahara de los Atunes, search
POIwith the place's coordinates andname, and put the city or region Trip.com lists them under incityName(Bali; Barbate or Cádiz). If aCITYsearch returnsDESTINATION_NOT_FOUND, retry this way once. - If the city, place or hotel is missing or ambiguous, ask one focused clarification question. Never guess IDs or child ages.
Stay and filters
- Dates use
YYYY-MM-DD; check-out must be later than check-in. Always pass bothcheckInandcheckOut: when the user gives no dates, use tomorrow and the following day in the user's local date. The tool's own fallback runs on the server clock and can be off by a day. roomCountandadultsare positive integers with adults not below rooms; defaults are 1 room and 2 adults. Every child needs an age from 0 through 17 inchildAges. Do not convert twin beds into two rooms or a bed count.- Trip.com cannot filter by number of beds, bathrooms or homestay bedrooms; say so when asked and point the user to the room details on the booking page. Pass
mealsas one value unless the user accepts alternatives, and never combine a meal with its own variants (BREAKFASTwithONE_BREAKFAST). sortOrdermatters only forPRICE(ASC= cheapest first, the default); every other sort has a fixed direction.- Omit optional filters and sort the user did not request, and do not silently drop unsupported or conflicting ones. The default
pageSizeis 5; pass another value from 1 through 20 only when the user asks. OmitpageIndexfor the first page.
Conversation modes
Use progressive by default and keep the selected mode for later hotel searches in the conversation.
progressive: search as soon as the destination is usable, including any supported values already supplied. After the results ask at most one concise follow-up about a relevant unresolved or invalid preference.confirm-first: preview the destination (city, place or hotel), dates, occupancy, filters, sort and page size, recommending tomorrow, the following day, 1 room, 2 adults, no children and no optional filters where the user said nothing. Search after the user confirms or corrects it in one reply.
When the user switches modes, apply the new mode immediately. If they only ask to compare modes, explain the timing trade-off and ask which to use without searching.
At the first actual hotel search in a conversation, show one natural-language example of a richer search following references/hotel-query-examples.md: after the results when searching now (first stating any default dates and occupancy used), or after the question when a clarification blocks the search. Show it once per conversation, never on refinements, pagination, retries or language changes, and not when the user wants results only.
Pagination
Fetch one page per search. When the user asks for more, repeat the confirmed query with pageIndex incremented (an initial query without an index is page 1) and the same pageSize. Stop when a page returns nothing or the cumulative count reaches pagination.totalCount.
Hotel cards
A success also contains searchContext, appliedFilters, pagination, optional sort and warnings. Deal fields: required product_type, title, category_label, deeplink; optional star, star_type, rating, rating_scale, rating_label, review_count, address, destination_city, relative_position, availability_status, availability_text, price, discount, promotion_label.
**{title}**
💰 **{current_price_label} {price.currency} {price.display_price}** · {original_price_label} ~~{price.currency} {price.original_price}~~ · 🏷️ **{discount_summary}** · **{savings_summary}** · [{view_details_label}]({deeplink})
{star_description} · {rating}/{rating_scale} {rating_label} · {review_count_label} · {availability_summary}
📍 {address}{relative_position_separator}{relative_position}
price.display_priceis the current displayed price andprice.original_pricethe displayed comparison price;price.savings_amountis the saving against it. Ifdisplay_priceis absent, keep the link and any offer without inventing a price.- A
discount.ratiobetween 0 and 1 gives{discount_summary}as the localized equivalent of{discount.percent}% off, without recomputing it. Otherwise usepromotion_labelverbatim, or omit the offer and icon. Never infer a discount from labels, promotion text or the price difference. - Interpret
starwithstar_type:STARis a star rating andDIAMONDa diamond rating; for any other type, includingDOT, omit{star_description}. Renderratingagainstrating_scaleonly when both are present; never assume a 10-point scale. - For
AVAILABLE, say the hotel is currently bookable and include anyavailability_textonce. For another status, say so and do not present the hotel as a primary recommendation. An absent status is unknown. - Use
address, falling back todestination_city; add the relative-position separator only when both location fragments exist. - Hotel prices are tax-inclusive by default: the total for the stay, or per night when the user set a budget;
appliedFilters.priceDisplaystates which. Whenever a hotel price appears in text, give its basis (total for N nights, or per night) and whether taxes are included; never present a pre-tax or nightly price as the amount to pay. Use pre-tax prices only when the user asks for them, and say so. - After the cards, state once that the final tax-inclusive total, room type, payment terms and any free-cancellation deadline must be confirmed on the Trip.com room page. The search returns hotel-level prices; filters such as payment type or breakfast do not establish the terms of a specific room rate.
- Treat
warningsas diagnostics; mention one only when it materially changes a requested filter.
Attraction tickets, experiences and travel services
search_attractions searches Trip.com's discounted product pool in a city. Pass the destination city name in the user's language or English, never a code or numeric ID, and add its country as countryName whenever the city name could exist in more than one country (countryCode only as a fallback). limit defaults to 3. SIM-card products are excluded unless excludeSim is false. Sold-out items are excluded and results are sorted by discount strength.
Card fields: required product_type, title, category_label, current_price, currency, deeplink; optional original_price, savings_amount, discount_label, valid_until, promo_tag, destination_city, redemption_note.
**{title}** · {category_label}
💰 **{currency} {current_price}** · {original_price_label} ~~{currency} {original_price}~~ · 🏷️ **{discount_summary}** · **{savings_summary}** · [{view_details_label}]({deeplink})
📍 {destination_city}
{promo_tag} · {valid_until_label} {valid_until}
- Use the returned
discount_labelas{discount_summary}, falling back topromo_tagwhen it describes an actual offer; if neither is present, omit the offer and icon. Do not repeat apromo_tagalready used as the offer; keep distinct promotion and validity text in normal weight and omit an empty line. - Append
redemption_noteto the destination line only when it adds information beyond the title (ignoring whitespace, line wrapping and Markdown decoration). - Translate
valid_until_label,original_price_labelandview_details_labelinto the reply language.