{"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 / hotel / visa-essentials 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 three onward-ticket service offerings (flight-itinerary, hotel-reservation, visa-essentials) with current base prices in USD, descriptions, 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 — one of 'flight-itinerary', 'hotel-reservation', 'visa-essentials'. Use list_services to discover available keys.","enum":["flight-itinerary","hotel-reservation","visa-essentials"]},"flightRoute":{"type":"string","description":"For flight-itinerary only — 'oneway' (default), 'return', or 'multicity'. Adds the corresponding route surcharge per traveler; for multicity the surcharge is PER LEG — pass `legs`.","enum":["oneway","return","multicity"]},"urgency":{"type":"string","description":"Speed tier — '' or omitted = standard (4h delivery), 'urgent' (30min), 'superfast' (5min). Add-on cost varies by service.","enum":["","urgent","superfast"]},"travelers":{"type":"integer","description":"Number of travelers, 1-7. Default 1.","minimum":1,"maximum":7},"legs":{"type":"integer","description":"Multi-city only: number of flight legs. The multi-city surcharge is charged PER LEG. Default 1.","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 — one of 'flight-itinerary', 'hotel-reservation', 'visa-essentials'. Use list_services to discover available keys.","enum":["flight-itinerary","hotel-reservation","visa-essentials"]},"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'. Adds the corresponding route surcharge per traveler; for multicity the surcharge is PER LEG — pass `legs`.","enum":["oneway","return","multicity"]},"urgency":{"type":"string","description":"Speed tier — '' or omitted = standard (4h delivery), 'urgent' (30min), 'superfast' (5min). Add-on cost varies by service.","enum":["","urgent","superfast"]},"travelers":{"type":"integer","description":"Number of travelers, 1-7. Default 1.","minimum":1,"maximum":7},"legs":{"type":"integer","description":"Multi-city only: number of flight legs. The multi-city surcharge is charged PER LEG. Default 1.","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":10,"items":{"type":"object","properties":{"salutation":{"type":"string","description":"Canonical English salutation — one of 'Mr.', 'Ms.', 'Mrs.', 'Dr.'. Stored as-is regardless of the conversation language; admin operates in English.","enum":["Mr.","Ms.","Mrs.","Dr."]},"firstName":{"type":"string","description":"Given name. Required."},"middleName":{"type":"string","description":"Middle name, optional."},"lastName":{"type":"string","description":"Family name. Required."}},"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}}]}