{"schemaVersion":"2025-06-18","serverInfo":{"name":"onward-ticket-mcp","version":"0.1.0","title":"OnwardTicket.us MCP Server","description":"Quote, place, and look up onward-ticket orders. Read-only blog search for agent grounding.","documentation":"https://onwardticket.us/agents","homepage":"https://onwardticket.us/","contactEmail":"contact@onwardticket.us"},"transport":{"type":"streamable-http","url":"https://onwardticket.us/api/mcp"},"transports":[{"type":"streamable-http","url":"https://onwardticket.us/api/mcp"},{"type":"sse","url":"https://onwardticket.us/api/mcp/sse","messagesUrl":"https://onwardticket.us/api/mcp/messages"}],"capabilities":{"tools":{"listChanged":false},"resources":{"listChanged":false,"subscribe":false},"prompts":{"listChanged":false},"logging":{}},"tools":[{"name":"list_services","description":"List the onward-ticket service offering (flight-itinerary) with its current base price in USD, description, supported routes, and add-ons. No arguments required.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"quote_order","description":"Compute a price quote for a service. Returns total, per-line breakdown, and currency. Does NOT create an order — call this before asking the user to commit to checkout.","inputSchema":{"type":"object","properties":{"serviceKey":{"type":"string","description":"Service identifier. Onward sells flight itineraries only, so this is always 'flight-itinerary'. Use list_services to confirm.","enum":["flight-itinerary"]},"flightRoute":{"type":"string","description":"For flight-itinerary only — 'oneway' (default), 'return', or 'multicity'. Per traveler: one-way is the base price; return is base + the return surcharge; multicity is priced PER LEG with NO base fee (e.g. $9 x legs) — pass `legs`.","enum":["oneway","return","multicity"]},"urgency":{"type":"string","description":"Speed tier — '' or omitted = standard (14h delivery), 'urgent' (8h), 'superfast' (2h). Add-on cost varies by service.","enum":["","urgent","superfast"]},"travelers":{"type":"integer","description":"Number of travelers, 1-9. Default 1.","minimum":1,"maximum":9},"legs":{"type":"integer","description":"Multi-city only (required for multicity): number of flight legs, 2 or more. Multi-city is priced PER LEG per traveler with no base fee.","minimum":1,"maximum":20},"couponCode":{"type":"string","description":"Optional discount code. Validated server-side; an invalid code returns an error rather than silently ignoring it."},"currency":{"type":"string","description":"ISO 4217 currency code (3 letters, uppercase). Default 'USD'. Falls back to USD if no override exists for this service+currency.","pattern":"^[A-Z]{3}$"}},"required":["serviceKey"],"additionalProperties":false}},{"name":"place_order","description":"Create a pending order and return a Stripe Checkout URL. Agent should display the URL to the user — payment happens in the user's browser. Returns the URL, expected total in major units, currency, and an order/cart reference id. Re-derives the price server-side; agent-supplied prices are ignored.","inputSchema":{"type":"object","properties":{"serviceKey":{"type":"string","description":"Service identifier. Onward sells flight itineraries only, so this is always 'flight-itinerary'. Use list_services to confirm.","enum":["flight-itinerary"]},"email":{"type":"string","description":"Booking email — receipts and the booking PDF are sent here after payment. Required."},"flightRoute":{"type":"string","description":"For flight-itinerary only — 'oneway' (default), 'return', or 'multicity'. Per traveler: one-way is the base price; return is base + the return surcharge; multicity is priced PER LEG with NO base fee (e.g. $9 x legs) — pass `legs`.","enum":["oneway","return","multicity"]},"urgency":{"type":"string","description":"Speed tier — '' or omitted = standard (14h delivery), 'urgent' (8h), 'superfast' (2h). Add-on cost varies by service.","enum":["","urgent","superfast"]},"travelers":{"type":"integer","description":"Number of travelers, 1-9. Default 1.","minimum":1,"maximum":9},"legs":{"type":"integer","description":"Multi-city only (required for multicity): number of flight legs, 2 or more. Multi-city is priced PER LEG per traveler with no base fee.","minimum":1,"maximum":20},"currency":{"type":"string","description":"ISO 4217 currency code (3 letters, uppercase). Default 'USD'. Falls back to USD if no override exists for this service+currency.","pattern":"^[A-Z]{3}$"},"couponCode":{"type":"string","description":"Optional discount code. Validated server-side; an invalid code returns an error rather than silently ignoring it."},"fromIata":{"type":"string","description":"Departure airport IATA code (3 uppercase letters). Flight only.","pattern":"^[A-Z]{3}$"},"toIata":{"type":"string","description":"Arrival airport IATA code (3 uppercase letters). Flight only.","pattern":"^[A-Z]{3}$"},"departureDate":{"type":"string","description":"Outbound date in ISO YYYY-MM-DD."},"returnDate":{"type":"string","description":"Return date in ISO YYYY-MM-DD. Round-trip flights only."},"name":{"type":"string","description":"Primary traveler full name. Max 120 chars. Ignored when travelerDetails is supplied."},"travelerDetails":{"type":"array","description":"Per-traveler identity, one entry per traveler, in order. REQUIRED when travelers > 1 — the booking document names each passenger, so an order for N travelers cannot be fulfilled with fewer than N names. For a single traveler this may be omitted and `name` used instead.","maxItems":9,"items":{"type":"object","properties":{"salutation":{"type":"string","description":"Canonical English salutation. Adults: 'Mr.', 'Ms.', 'Mrs.', 'Dr.'. Children and infants: 'Master', 'Miss' — 'Mr.' does not apply to a two-year-old and the airline convention for under-12s is Master/Miss, which is what the operator transcribes. Stored as-is regardless of the conversation language; admin operates in English.","enum":["Mr.","Ms.","Mrs.","Dr.","Master","Miss"]},"firstName":{"type":"string","description":"Given name. Required."},"middleName":{"type":"string","description":"Middle name, optional."},"lastName":{"type":"string","description":"Family name. Required."},"type":{"type":"string","description":"Passenger type. Optional and ADDITIVE — omitting it is valid and is how every order placed before this field existed is stored. Does NOT affect price: adults, children and infants are charged identically, and the quote depends only on the traveler COUNT. Supply it so the operator making the airline booking can tell which passenger is the infant.","enum":["adult","child","infant"]}},"required":["firstName","lastName"],"additionalProperties":false}},"phone":{"type":"string","description":"Contact phone in E.164 form (for WhatsApp updates / urgent contact). Max 40 chars."}},"required":["serviceKey","email"],"additionalProperties":false}},{"name":"lookup_order","description":"Look up a placed order by its order number (e.g. OT-12345) and the booking email. Returns status, service, amount, currency, and the customer-facing tracking URL. Both arguments are required — they jointly act as the credential.","inputSchema":{"type":"object","properties":{"orderId":{"type":"string","description":"Order number printed on the receipt, e.g. OT-12345. The alias `orderNumber` is also accepted."},"orderNumber":{"type":"string","description":"Alias for `orderId`. Either may be supplied; supply only one."},"email":{"type":"string","description":"Email address used at checkout. Must match the order."}},"required":["email","orderId"],"additionalProperties":false}},{"name":"search_blogs","description":"Full-text search the public blog index. Returns up to `limit` matching posts (default 5, max 20) with title, excerpt, slug, and absolute URL — agents use this to ground answers about onward-ticket / visa-policy / travel-document questions.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Free-text search query — matched against title and excerpt."},"limit":{"type":"integer","description":"Max results, default 5, max 20.","minimum":1,"maximum":20}},"required":["query"],"additionalProperties":false}},{"name":"get_blog_post","description":"Fetch the full body of a published blog post by slug, returned as agent-ingestible markdown (NOT HTML). Includes title, date, author, hero image URL, and the converted body.","inputSchema":{"type":"object","properties":{"slug":{"type":"string","description":"URL slug of the post, e.g. \"visa-policy-thailand-2026\"."}},"required":["slug"],"additionalProperties":false}}]}