# Quick Start Guide: Mock GDS MCP Server **Branch**: `001-mock-gds-server` | **Date**: 2026-04-07 ## Overview This guide demonstrates how to use the Mock GDS MCP Server for testing travel applications. All examples use mock data with the TEST- prefix for safety. --- ## Installation & Setup ### Prerequisites - Node.js 20 LTS or later - Docker & Docker Compose (for Valkey) - MCP-compatible client ### Running with Docker Compose ```bash # Start the mock GDS server and Valkey docker-compose up -d # View logs docker-compose logs -f gds-mock-mcp # Stop services docker-compose down ``` ### Configuration Create a `.env` file (optional, defaults shown): ```bash # MCP Server MCP_TRANSPORT=stdio MCP_SESSION_TIMEOUT=3600 # Valkey VALKEY_HOST=valkey VALKEY_PORT=6379 VALKEY_PASSWORD= VALKEY_DB=0 # Logging LOG_LEVEL=info LOG_PRETTY=false # Mock Data MOCK_DATA_SEED=fixed MOCK_RESPONSE_DELAY=0 ``` --- ## Basic Workflows ### 1. Search and Book a Flight **Step 1: Search for flights** ```javascript // MCP tool call { "tool": "searchFlights", "arguments": { "origin": "JFK", "destination": "LAX", "departureDate": "2026-06-15", "passengers": { "adults": 1 }, "cabin": "economy" } } // Response { "searchId": "search_abc123", "flights": [ { "id": "flight_1", "flightNumber": "AA123", "airline": { "code": "AA", "name": "American Airlines" }, "departure": { "time": "2026-06-15T08:00:00Z", "airport": "JFK" }, "arrival": { "time": "2026-06-15T11:30:00Z", "airport": "LAX" }, "price": 29900, // $299.00 "seatsAvailable": 45, "status": "available" }, // ... more flights ], "resultCount": 5 } ``` **Step 2: Book the selected flight** ```javascript // MCP tool call { "tool": "bookFlight", "arguments": { "flightIds": ["flight_1"], "passengers": [ { "type": "adult", "firstName": "John", "lastName": "Doe", "email": "john.doe@example.com" } ], "contactEmail": "john.doe@example.com" } } // Response { "pnr": "TEST-A1B2C3", // Note: TEST- prefix for safety "status": "confirmed", "bookingDate": "2026-04-07T16:30:00Z", "passengers": [{ "firstName": "John", "lastName": "Doe" }], "flights": [{ /* flight details */ }], "totalPrice": 29900, "currency": "USD" } ``` --- ### 2. Multi-Service Booking (Flight + Hotel) **Step 1: Book a flight (as above)** Result: `pnr = "TEST-A1B2C3"` **Step 2: Search for hotels** ```javascript { "tool": "searchHotels", "arguments": { "cityCode": "LAX", "checkInDate": "2026-06-15", "checkOutDate": "2026-06-17", "guests": 1 } } // Response { "hotels": [ { "id": "hotel_1", "name": "Marriott Los Angeles Downtown", "starRating": 4, "pricePerNight": 18000, // $180.00 "totalPrice": 36000, // 2 nights "amenities": ["WiFi", "Pool", "Gym", "Parking"] } ] } ``` **Step 3: Add hotel to existing booking** ```javascript { "tool": "bookHotel", "arguments": { "hotelId": "hotel_1", "existingPnr": "TEST-A1B2C3", // Add to flight booking "guests": [ { "firstName": "John", "lastName": "Doe", "email": "john.doe@example.com" } ] } } // Response { "pnr": "TEST-A1B2C3", // Same PNR, now includes hotel "flights": [{ /* flight */ }], "hotels": [{ /* hotel */ }], "totalPrice": 65900 // $299 flight + $360 hotel } ``` --- ### 3. Complete Travel Package (Flight + Hotel + Car) **Step 1-2: Book flight and hotel** (as above) Result: `pnr = "TEST-A1B2C3"` **Step 3: Search for rental cars** ```javascript { "tool": "searchCars", "arguments": { "pickupLocationCode": "LAX", "pickupDate": "2026-06-15T12:00:00Z", "dropoffDate": "2026-06-17T10:00:00Z" } } // Response { "cars": [ { "id": "car_1", "companyName": "Hertz", "vehicleClass": "economy", "vehicleModel": "Toyota Corolla or similar", "dailyRate": 4500, // $45/day "totalPrice": 9000, // 2 days "mileagePolicy": "unlimited" } ] } ``` **Step 4: Add car to booking** ```javascript { "tool": "bookCar", "arguments": { "carId": "car_1", "existingPnr": "TEST-A1B2C3", "driver": { "firstName": "John", "lastName": "Doe", "age": 35 } } } // Response { "pnr": "TEST-A1B2C3", "flights": [{ /* flight */ }], "hotels": [{ /* hotel */ }], "cars": [{ /* car */ }], "totalPrice": 74900 // $299 + $360 + $90 } ``` --- ### 4. Retrieve and Manage Bookings **Retrieve a booking by PNR** ```javascript { "tool": "retrieveBooking", "arguments": { "pnr": "TEST-A1B2C3" } } // Response: Full booking details ``` **List all bookings in session** ```javascript { "tool": "listBookings", "arguments": { "status": "all" } } // Response { "bookings": [ { "pnr": "TEST-A1B2C3", "status": "confirmed", "createdAt": "2026-04-07T16:30:00Z", "passengerCount": 1, "segmentCounts": { "flights": 1, "hotels": 1, "cars": 1 }, "totalPrice": 74900 } ], "totalCount": 1 } ``` **Cancel a booking** ```javascript { "tool": "cancelBooking", "arguments": { "pnr": "TEST-A1B2C3", "reason": "Travel plans changed" } } // Response { "pnr": "TEST-A1B2C3", "status": "cancelled", "cancelledAt": "2026-04-07T17:00:00Z" } ``` --- ## Testing Scenarios ### Concurrent Sessions ```javascript // Session 1 const session1 = createMCPConnection(); const booking1 = await session1.call("bookFlight", { /* ... */ }); // booking1.pnr = "TEST-A1B2C3" // Session 2 (different MCP connection) const session2 = createMCPConnection(); const booking2 = await session2.call("bookFlight", { /* ... */ }); // booking2.pnr = "TEST-X7Y8Z9" // Different PNR // Sessions are isolated - cannot retrieve booking1 from session2 await session2.call("retrieveBooking", { pnr: "TEST-A1B2C3" }); // Error: PNR not found in current session ``` ### Error Handling **Invalid airport code** ```javascript { "tool": "searchFlights", "arguments": { "origin": "ZZZ", // Invalid code "destination": "LAX", "departureDate": "2026-06-15" } } // Error response { "code": -32602, "message": "Invalid airport code 'ZZZ': must be a valid 3-letter IATA code", "data": { "field": "origin", "value": "ZZZ" } } ``` **Date in the past** ```javascript { "tool": "searchFlights", "arguments": { "origin": "JFK", "destination": "LAX", "departureDate": "2020-01-01" // Past date } } // Error response { "code": -32002, "message": "Departure date cannot be in the past", "data": { "field": "departureDate", "value": "2020-01-01" } } ``` **Cancelled booking modification** ```javascript // First cancel await call("cancelBooking", { pnr: "TEST-A1B2C3" }); // Try to add hotel to cancelled booking await call("bookHotel", { hotelId: "hotel_1", existingPnr: "TEST-A1B2C3" }); // Error response { "code": -32002, "message": "Cannot modify cancelled booking TEST-A1B2C3", "data": { "pnr": "TEST-A1B2C3", "status": "cancelled" } } ``` --- ## Integration Testing Example ```javascript // Example integration test (using Node.js test runner) import { test } from 'node:test'; import { strict as assert } from 'node:assert'; import { MCPClient } from './mcp-client.js'; test('complete booking workflow', async (t) => { const client = new MCPClient(); // Search flights const searchResults = await client.call('searchFlights', { origin: 'JFK', destination: 'LAX', departureDate: '2026-06-15', passengers: { adults: 1 } }); assert.ok(searchResults.flights.length > 0); const flight = searchResults.flights[0]; // Book flight const booking = await client.call('bookFlight', { flightIds: [flight.id], passengers: [{ type: 'adult', firstName: 'Test', lastName: 'User', email: 'test@example.com' }], contactEmail: 'test@example.com' }); assert.match(booking.pnr, /^TEST-[A-Z0-9]{6}$/); assert.equal(booking.status, 'confirmed'); // Retrieve booking const retrieved = await client.call('retrieveBooking', { pnr: booking.pnr }); assert.equal(retrieved.pnr, booking.pnr); assert.equal(retrieved.flights.length, 1); // Cancel booking const cancelled = await client.call('cancelBooking', { pnr: booking.pnr }); assert.equal(cancelled.status, 'cancelled'); }); ``` --- ## Mock Data Reference ### Supported Airports Major US: JFK, LAX, ORD, DFW, ATL, MIA, SFO, SEA, BOS, LAS International: LHR, CDG, FRA, NRT, HKG, SYD, DXB ### Supported Airlines - American Airlines (AA) - Delta Air Lines (DL) - United Airlines (UA) - Southwest Airlines (WN) - British Airways (BA) - Virgin Atlantic (VS) - Lufthansa (LH) - Air France (AF) ### Price Ranges - **Flights**: $200-$800 (economy domestic), $800-$2000 (business), $2500+ (first) - **Hotels**: $80-$150 (budget), $150-$300 (mid-range), $300-$800 (luxury) - **Cars**: $35-$50 (economy), $50-$80 (midsize), $100-$150 (luxury) --- ## Troubleshooting ### Server won't start Check Valkey connection: ```bash docker-compose logs valkey ``` ### Session expires Default timeout: 1 hour. Adjust with `MCP_SESSION_TIMEOUT` env var. ### PNR not found Verify you're retrieving from the same session that created the booking. --- ## Next Steps - Explore all available tools in `/contracts/mcp-tools.md` - Review data model in `/data-model.md` - Check technical research in `/research.md` - See implementation tasks in `/tasks.md` (after running `/speckit.tasks`)