Skip to main content
Glama
server.ts6.07 kB
/** * Flight search MCP server implementation */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { flightSearchSchema, offerDetailsSchema, multiCityRequestSchema, FlightSearch, OfferDetails, MultiCityRequest } from './models/flightSearch.js'; import { DuffelClient } from './api/duffelClient.js'; import { DuffelStaysClient } from './api/duffelStaysClient.js'; import { staySearchSchema, StaySearch } from './models/staySearch.js'; import { stayReviewSchema, StayReviewRequest } from './models/stayReview.js'; // Create MCP server export const createServer = () => { const server = new McpServer({ name: 'flight-search-mcp', version: '1.0.0' }); // Initialize Duffel clients const flightClient = new DuffelClient(); const staysClient = new DuffelStaysClient(); // Search for flights server.tool( 'search_flights', flightSearchSchema.shape, async (params: FlightSearch) => { try { const slices = []; // Build slices based on flight type if (params.type === 'one_way') { slices.push(flightClient.createSlice( params.origin, params.destination, params.departureDate, params.departureTime, params.arrivalTime )); } else if (params.type === 'round_trip') { if (!params.returnDate) { throw new Error('Return date required for round-trip flights'); } slices.push(flightClient.createSlice( params.origin, params.destination, params.departureDate, params.departureTime, params.arrivalTime )); slices.push(flightClient.createSlice( params.destination, params.origin, params.returnDate, params.departureTime, params.arrivalTime )); } else if (params.type === 'multi_city') { if (!params.additionalStops || params.additionalStops.length === 0) { throw new Error('Additional stops required for multi-city flights'); } // First leg slices.push(flightClient.createSlice( params.origin, params.destination, params.departureDate )); // Additional legs for (const stop of params.additionalStops) { slices.push(flightClient.createSlice( stop.origin, stop.destination, stop.departureDate )); } } // Create the offer request const response = await flightClient.createOfferRequest({ slices, cabin_class: params.cabinClass, adult_count: params.adults, max_connections: params.maxConnections, return_offers: true, supplier_timeout: 15000 // 15 seconds }); // Return formatted response return { content: [ { type: 'text', text: JSON.stringify(response, null, 2) } ] }; } catch (error) { console.error(`Error searching flights: ${error}`); throw error; } } ); // Get offer details server.tool( 'get_offer_details', offerDetailsSchema.shape, async (params: OfferDetails) => { try { const response = await flightClient.getOffer(params.offerId); return { content: [ { type: 'text', text: JSON.stringify(response, null, 2) } ] }; } catch (error) { console.error(`Error getting offer details: ${error}`); throw error; } } ); // Multi-city search server.tool( 'search_multi_city', multiCityRequestSchema.shape, async (params: MultiCityRequest) => { try { const slices = []; // Build slices from segments for (const segment of params.segments) { slices.push(flightClient.createSlice( segment.origin, segment.destination, segment.departureDate )); } // Create the offer request with a longer timeout for multi-city const response = await flightClient.createOfferRequest({ slices, cabin_class: params.cabinClass, adult_count: params.adults, max_connections: params.maxConnections, return_offers: true, supplier_timeout: 30000 // 30 seconds }); return { content: [ { type: 'text', text: JSON.stringify(response, null, 2) } ] }; } catch (error) { console.error(`Error searching multi-city flights: ${error}`); throw error; } } ); // Search for stays (hotels/accommodations) server.tool( 'search_stays', staySearchSchema.shape, async (params: StaySearch) => { try { const response = await staysClient.searchOffers(params); return { content: [ { type: 'text', text: JSON.stringify(response, null, 2) } ] }; } catch (error) { console.error(`Error searching stays: ${error}`); throw error; } } ); // Get stay reviews server.tool( 'get_stay_reviews', stayReviewSchema.shape, async (params: StayReviewRequest) => { try { const response = await staysClient.getStayReviews(params); return { content: [ { type: 'text', text: JSON.stringify(response, null, 2) } ] }; } catch (error) { console.error(`Error fetching stay reviews: ${error}`); throw error; } } ); return server; };

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/clockworked247/flights-mcp-ts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server