Skip to main content
Glama
README.md16.4 kB
# Duffel MCP Server A Model Context Protocol (MCP) server that enables LLMs to interact with the [Duffel API](https://duffel.com) for searching and booking flights, accommodations, and managing travel bookings. ## Features ### ✈️ Flight Operations - **Search Flights** - Find available flights with pricing, schedules, and airline information - **Get Offer Details** - Retrieve up-to-date pricing and availability for specific offers - **Create Orders** - Book flights with passenger details and payment - **Manage Orders** - View and manage existing bookings ### 🏨 Accommodation (Stays) Operations - **Search Accommodation** - Find available hotels and properties by location and dates - **Get Accommodation Details** - Retrieve detailed property information, amenities, and ratings - **Get Accommodation Rates** - View available rooms, pricing, and rate options - **Create Stays Quote** - Generate a quote to lock in pricing before booking - **Create Stays Booking** - Book accommodations with guest details - **Get Stays Booking** - View and manage accommodation bookings ### 🌍 Supporting Resources - **Search Airports** - Find airports by name, city, or IATA code - **List Airports** - Browse airports with country filtering ### 🎯 Key Capabilities - **300+ Airlines** - Access to major airlines via NDC, GDS, and LCC - **Millions of Properties** - Hotels, resorts, vacation rentals worldwide - **Real-time Data** - Live pricing, availability, and seat selection - **Flexible Search** - One-way, round-trip, multi-city flights; location-based accommodation search - **Smart Responses** - JSON or Markdown formatted output - **Error Handling** - Clear, actionable error messages - **Complete Booking Flow** - From search to confirmation for both flights and accommodations ## Installation ### Prerequisites - Python 3.12 or higher - Duffel API account ([sign up here](https://app.duffel.com/join)) - Duffel API access token - [uv](https://docs.astral.sh/uv/) (fast Python package manager) ### Install uv On macOS with Homebrew: ```bash brew install uv ``` Or via the official installer (macOS/Linux): ```bash curl -LsSf https://astral.sh/uv/install.sh | sh # then restart your shell or source the profile output by the installer ``` ### Project setup 1. Clone or download the server file/repo 2. Create the virtual environment and install dependencies with uv: ```bash uv sync ``` This uses `pyproject.toml` to create `.venv` and install exact versions. 3. Set up environment variable: ```bash export DUFFEL_ACCESS_TOKEN="your_duffel_token_here" ``` Get your token from the [Duffel Dashboard](https://app.duffel.com): - Navigate to: More → Developers → Access Tokens - Create a test token for testing (free, unlimited balance) - Create a live token for production bookings ## Usage ### Running the Server Run with uv (uses the synced virtualenv automatically): ```bash uv run python duffel_mcp.py ``` ### Configuration for Claude Desktop Add to your Claude Desktop config file (`claude_desktop_config.json`): ```json { "mcpServers": { "duffel": { "command": "uv", "args": ["run", "python", "/path/to/duffel_mcp.py"], "env": { "DUFFEL_ACCESS_TOKEN": "your_token_here" } } } } ``` ### Configuration for Other MCP Clients For other MCP clients, follow their specific configuration format, ensuring: - The server is launched with Python 3.12+ - `DUFFEL_ACCESS_TOKEN` environment variable is set - Server communicates via stdio ## Available Tools ### 1. `duffel_search_flights` Search for available flights based on journey requirements. **Parameters**: - `slices` - Journey legs (origin, destination, date) - `passengers` - List of travelers (use `age` for best accuracy) - `cabin_class` - Optional: economy, premium_economy, business, first - `max_connections` - Optional: limit stops (0 = direct flights) - `response_format` - json or markdown **Example**: ```python { "slices": [ { "origin": "JFK", "destination": "LAX", "departure_date": "2025-12-15" }, { "origin": "LAX", "destination": "JFK", "departure_date": "2025-12-22" } ], "passengers": [ {"age": 35}, {"age": 32}, {"age": 8} ], "cabin_class": "economy", "max_connections": 1 } ``` ### 2. `duffel_get_offer` Retrieve current pricing and details for a specific offer. **Parameters**: - `offer_id` - Offer ID from search results - `response_format` - json or markdown **Important**: Always call this before booking to ensure offer is still valid and get current pricing. ### 3. `duffel_create_order` Create a flight booking with passenger details and payment. **Parameters**: - `offer_id` - Offer ID to book - `passengers` - Complete passenger details (name, DOB, contact) - `payments` - Payment information - `response_format` - json or markdown **⚠️ Warning**: This creates real bookings! Use test tokens for development. **Example**: ```python { "offer_id": "off_00009htYpSCXrwaB9DnUm0", "passengers": [ { "id": "pas_00009hj8USM7Ncg31cBCL", "given_name": "John", "family_name": "Smith", "born_on": "1985-03-15", "email": "john.smith@example.com", "phone_number": "+14155551234", "gender": "m", "title": "mr" } ], "payments": [ { "type": "balance", "amount": "520.00", "currency": "USD" } ] } ``` ### 4. `duffel_get_order` Retrieve details for an existing order. **Parameters**: - `order_id` - Order ID from booking - `response_format` - json or markdown ### 5. `duffel_search_airports` Search for airports by name, city, or code. **Parameters**: - `query` - Search term (e.g., "London", "Heathrow", "LHR") - `limit` - Max results (1-100, default: 20) - `response_format` - json or markdown ### 6. `duffel_search_accommodation` Search for available accommodations based on location, dates, and guest requirements. **Parameters**: - `check_in_date` - Check-in date in YYYY-MM-DD format - `check_out_date` - Check-out date in YYYY-MM-DD format - `guests` - Guest information (adult_count, child_count) - `rooms` - Number of rooms needed (default: 1) - `location` - Geographic location (latitude, longitude, radius in km) OR - `accommodation_ids` - Specific accommodation IDs to search - `response_format` - json or markdown **Example**: ```python { "check_in_date": "2025-12-15", "check_out_date": "2025-12-18", "guests": { "adult_count": 2, "child_count": 1 }, "rooms": 1, "location": { "latitude": 51.5074, "longitude": -0.1278, "radius": 10 } } ``` ### 7. `duffel_get_accommodation` Get detailed information for a specific accommodation property. **Parameters**: - `accommodation_id` - Accommodation ID (e.g., "acc_00009htYpSCXrwaB9DnUm0") - `response_format` - json or markdown ### 8. `duffel_get_accommodation_rates` Retrieve available rooms and rates for a search result. **Parameters**: - `search_result_id` - Search result ID from accommodation search - `response_format` - json or markdown **Note**: Use the search_result_id from `duffel_search_accommodation` results. ### 9. `duffel_create_stays_quote` Create a quote to lock in pricing before booking. **Parameters**: - `rate_id` - Rate ID from accommodation rates - `response_format` - json or markdown **Important**: Always create a quote before booking to confirm current pricing. ### 10. `duffel_create_stays_booking` Create an accommodation booking from a quote. **Parameters**: - `quote_id` - Quote ID from stays quote - `guests` - List of guest details (given_name, family_name, email, phone_number) - `special_requests` - Optional: Special requests for the property - `response_format` - json or markdown **⚠️ Warning**: This creates real bookings! Use test tokens for development. **Example**: ```python { "quote_id": "quo_00009htYpSCXrwaB9DnUm0", "guests": [ { "given_name": "John", "family_name": "Smith", "email": "john.smith@example.com", "phone_number": "+14155551234" } ], "special_requests": "Late check-in after 10 PM" } ``` ### 11. `duffel_get_stays_booking` Retrieve details for an existing accommodation booking. **Parameters**: - `booking_id` - Stays booking ID - `response_format` - json or markdown ### 12. `duffel_search_airports` Search for airports by name, city, or code. **Parameters**: - `query` - Search term (e.g., "London", "Heathrow", "LHR") - `limit` - Max results (1-100, default: 20) - `response_format` - json or markdown ### 13. `duffel_list_airports` List airports with optional country filter. **Parameters**: - `country_code` - Optional: ISO country code (e.g., "US", "GB") - `limit` - Results per page (1-200, default: 50) - `response_format` - json or markdown ## Typical Workflows ### Booking a Flight 1. **Search for flights**: ``` Search for round-trip flights from New York to London, departing Dec 15, returning Dec 22, 2 adult passengers, economy class, direct flights only ``` 2. **Get offer details**: ``` Get the latest pricing for offer off_00009htYpSCXrwaB9DnUm0 ``` 3. **Create booking**: ``` Book this offer with passengers: John Smith (john@example.com, +14155551234, DOB 1985-03-15) and Jane Smith (jane@example.com, +14155551235, DOB 1987-07-20). Use balance payment for $1,450.00 USD. ``` ### Booking Accommodation 1. **Search for accommodations**: ``` Find hotels in central London for 2 adults, checking in Dec 15, checking out Dec 18, within 10km of coordinates 51.5074, -0.1278 ``` 2. **Get rates for a property**: ``` Show me the available rooms and rates for search result srs_00009htYpSCXrwaB9DnUm0 ``` 3. **Create a quote**: ``` Create a quote for rate rat_00009htYpSCXrwaB9DnUm0 ``` 4. **Complete booking**: ``` Book this quote quo_00009htYpSCXrwaB9DnUm0 for guest John Smith (john.smith@example.com, +14155551234) with special request: "Late check-in after 10 PM" ``` ### Finding Airports ``` What airports are in the London area? ``` ``` What's the airport code for San Francisco International? ``` ## Best Practices ### ✅ Do's #### For Flights: 1. **Use `age` over `type`** - Provides better accuracy across airlines 2. **Check offer expiry** - Flight offers expire in 15-30 minutes 3. **Verify before booking** - Always retrieve offer for current price 4. **Test mode first** - Use test tokens during development 5. **Handle async responses** - Some bookings return 200/202 with webhook notifications #### For Stays: 1. **Create quote before booking** - Always generate a quote to lock in pricing 2. **Provide accurate coordinates** - Use precise latitude/longitude for location searches 3. **Specify check-in/out dates** - Rates vary significantly by date 4. **Include all guest details** - Complete information ensures smooth check-in 5. **Use search_result_id** - Required to fetch rates for a specific property ### ❌ Don'ts 1. **Don't retry failed bookings** - If booking creation fails, don't retry the same request 2. **Don't cache offers or quotes** - Always fetch fresh data before booking 3. **Don't ignore validation errors** - They guide toward correct usage 4. **Don't use expired offers or quotes** - Check expiry timestamps 5. **Don't skip the quote step** - For stays, always create a quote before booking ## Error Handling The server provides clear, actionable error messages: - **offer_expired** - Perform new search - **offer_no_longer_available** - Select different offer - **price_changed** - Retrieve offer again for updated price - **validation_error** - Check parameter formats and requirements - **payment_declined** - Verify payment details ## Testing ### Test Mode Duffel provides unlimited test balance: 1. Create a **test** access token in dashboard 2. Use `"type": "balance"` for payments 3. Search and book without actual charges 4. Use test airline: "Duffel Airways" ### Manual Testing ```bash # Set test token export DUFFEL_ACCESS_TOKEN="duffel_test_xxx" # Run server with uv uv run python duffel_mcp.py ``` Then interact through your MCP client to test various workflows. ## API Reference For complete Duffel API documentation: - [Getting Started with Flights](https://duffel.com/docs/guides/getting-started-with-flights) - [Getting Started with Stays](https://duffel.com/docs/guides/getting-started-with-stays) - [API Reference](https://duffel.com/docs/api/overview/welcome) - [Response Handling](https://duffel.com/docs/api/overview/response-handling) ## Troubleshooting ### General Issues #### "DUFFEL_ACCESS_TOKEN environment variable not set" Set the environment variable with your Duffel API token. ### Flight-Specific Issues #### "offer_expired" errors Flight offers have short expiry times (15-30 min). Perform a new search. #### "validation_error" on flight booking - Check passenger names match government ID exactly - Verify date format is YYYY-MM-DD - Ensure payment amount matches offer total - Confirm all required fields are provided #### "No flights found" - Verify airport codes are valid IATA codes (use `duffel_search_airports`) - Check dates are in future - Try broader search criteria (more connections, different cabin class) ### Stays-Specific Issues #### "No accommodations found" - Verify latitude/longitude coordinates are valid - Ensure radius is between 1-100 km - Check dates are in future and in YYYY-MM-DD format - Try expanding search radius or different dates #### "No rates available" - The property may be fully booked for your dates - The search_result_id may have expired - perform a new search - Try different check-in/check-out dates #### "quote_expired" or quote errors - Quotes expire after some time - create a new quote - Verify the rate is still available - The rate_id must be from a recent search #### "validation_error" on stays booking - Ensure at least one guest is provided - Verify all guest emails are valid - Check phone numbers include country code (e.g., +1) - Confirm quote_id is correct and not expired ### Webhooks not received - Configure webhook URLs in Duffel Dashboard - Check your email for booking confirmations - Use `duffel_get_order` or `duffel_get_stays_booking` to manually check status ## License This MCP server is provided as-is for integration with Duffel API. See Duffel's terms of service for API usage terms. ## Support - **Duffel Documentation**: https://duffel.com/docs - **Duffel Support**: https://support.duffel.com - **MCP Documentation**: https://modelcontextprotocol.io ## Contributing Contributions welcome! Potential enhancements: - Order modifications and cancellations (flights and stays) - Seat selection tools for flights - Baggage management for flights - Loyalty program integration (flights and stays) - Advanced filtering options (amenities, price ranges) - Accommodation suggestions/autocomplete - Multi-property booking support - Cancellation management for stays ## Code Structure The codebase has been refactored into a modular structure for better maintainability: ``` duffel_mcp/ ├── __init__.py # Package initialization ├── config.py # Configuration and constants ├── server.py # MCP server instance ├── models/ # Pydantic models (flights, stays, airports) ├── api/ # API client and authentication ├── formatters/ # Response formatting utilities └── tools/ # MCP tools (flights, stays, airports) ``` For detailed structure documentation, see [STRUCTURE.md](STRUCTURE.md). **Benefits**: - Clean separation of concerns (models, API, formatters, tools) - Easy to navigate and maintain - Modular testing and extension - Simple to add new features ## Version History - **v0.2.1** - Code Refactoring - Modular code structure for better maintainability - Separated models, API client, formatters, and tools into logical modules - Added STRUCTURE.md architecture documentation - Cleaner imports and organization - **v0.2.0** - Stays API Integration - Accommodation search by location - Get accommodation details and rates - Quote creation for stays - Stays booking creation and management - Complete stays workflow support - Enhanced documentation with stays examples - **v0.1.0** - Initial release - Flight search and booking - Order management - Airport search - Markdown and JSON output formats

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/FortripEngineering/duffel-mcp'

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