search_flights
Search for available flights with real-time pricing and AI-powered price predictions. Get flight options with buy/wait/watch recommendations to optimize travel decisions.
Instructions
Search for available flights on Hopper with real-time pricing and AI-powered price predictions. Returns flight options with buy/wait/watch recommendations.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| origin | Yes | IATA airport code (e.g. JFK, LAX, LHR) | |
| destination | Yes | IATA airport code (e.g. CDG, NRT, SYD) | |
| departure_date | Yes | Departure date in YYYY-MM-DD format | |
| return_date | No | Return date for round trips (YYYY-MM-DD). Omit for one-way. | |
| passengers | No | Number of adult passengers (default: 1) | |
| cabin_class | No | Cabin class (default: economy) |
Implementation Reference
- src/index.ts:114-165 (handler)The searchFlights function implementation, which navigates to Hopper, extracts flight data from the page, and formats it.
async function searchFlights(params: FlightSearchParams): Promise<string> { const page = await session.newPage(); try { const tripType = params.return_date ? "round" : "one-way"; const pax = params.passengers ?? 1; const cabin = params.cabin_class ?? "economy"; const url = `https://www.hopper.com/flights/${params.origin}/${params.destination}` + `?departure=${params.departure_date}` + (params.return_date ? `&return=${params.return_date}` : "") + `&adults=${pax}&cabin=${cabin}&tripType=${tripType}`; await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 }); await page.waitForTimeout(3000); // Extract flight data from rendered page const flights = await page.evaluate(() => { const results: Array<{ id: string; airline: string; departure: string; arrival: string; duration: string; stops: number; price: number; currency: string; prediction: string; }> = []; // Hopper renders flight cards — extract visible data const cards = document.querySelectorAll("[data-testid*='flight'], .flight-card, [class*='FlightResult']"); cards.forEach((card, i) => { const text = card.textContent ?? ""; const priceMatch = text.match(/\$(\d[\d,]*)/); results.push({ id: `flight_${i + 1}`, airline: card.querySelector("[class*='airline'], [class*='carrier']")?.textContent?.trim() ?? "Unknown", departure: card.querySelector("[class*='depart'], [class*='origin']")?.textContent?.trim() ?? "", arrival: card.querySelector("[class*='arriv'], [class*='dest']")?.textContent?.trim() ?? "", duration: card.querySelector("[class*='duration']")?.textContent?.trim() ?? "", stops: (text.match(/nonstop/i) ? 0 : (text.match(/(\d+)\s*stop/)?.[1] ? parseInt(text.match(/(\d+)\s*stop/)![1]) : 1)), price: priceMatch ? parseInt(priceMatch[1].replace(",", "")) : 0, currency: "USD", prediction: text.match(/buy|wait|watch/i)?.[0]?.toLowerCase() ?? "watch", }); }); return results.slice(0, 10); }); // Augment with Hopper's price prediction metadata - src/index.ts:585-615 (registration)The TOOLS array definition where 'search_flights' is registered with its inputSchema.
const TOOLS: Tool[] = [ { name: "search_flights", description: "Search for available flights on Hopper with real-time pricing and AI-powered price predictions. Returns flight options with buy/wait/watch recommendations.", inputSchema: { type: "object", properties: { origin: { type: "string", description: "IATA airport code (e.g. JFK, LAX, LHR)" }, destination: { type: "string", description: "IATA airport code (e.g. CDG, NRT, SYD)" }, departure_date: { type: "string", description: "Departure date in YYYY-MM-DD format" }, return_date: { type: "string", description: "Return date for round trips (YYYY-MM-DD). Omit for one-way." }, passengers: { type: "number", description: "Number of adult passengers (default: 1)" }, cabin_class: { type: "string", enum: ["economy", "premium_economy", "business", "first"], description: "Cabin class (default: economy)", }, }, required: ["origin", "destination", "departure_date"], }, }, { name: "search_hotels", description: "Search for hotels on Hopper with price predictions. Returns hotel options with ratings, amenities, and Hopper's buy/wait recommendation.", inputSchema: { type: "object", properties: { destination: { type: "string", description: "City name or destination (e.g. Paris, New York, Tokyo)" }, check_in: { type: "string", description: "Check-in date in YYYY-MM-DD format" },