Files
gds-mock-mcp/README.md

12 KiB

Mock GDS MCP Server

A Remote MCP (Model Context Protocol) server that simulates Global Distribution System (GDS) functionality for testing and demonstration purposes. Uses MCP 2025-11-25 Streamable HTTP transport (HTTP/1.1 + Server-Sent Events).

⚠️ IMPORTANT SAFETY NOTICE

THIS IS A MOCK SERVER FOR TESTING AND DEMONSTRATION ONLY

  • Does NOT connect to real GDS systems
  • Does NOT process real bookings or transactions
  • Does NOT charge credit cards or process payments
  • All bookings are simulated with TEST- prefixed PNRs
  • Safe for development, testing, and training environments

See SAFETY_DISCLAIMER.md for complete details.


Features

  • Remote MCP Access: HTTP/1.1 + SSE transport per MCP 2025-11-25 specification
  • Flight Operations: Search flights, create bookings, retrieve confirmations
  • Hotel Bookings: Search and book hotels with realistic pricing
  • Car Rentals: Search and book rental cars from major providers
  • Multi-Service Bundling: Combined bookings under single PNR
  • Session Management: Isolated sessions with UUID v4 IDs and TTL
  • Rate Limiting: 100 requests/minute per IP (Valkey-backed)
  • Realistic Mock Data: Valid IATA codes, realistic pricing, professional presentation
  • Docker Ready: Multi-platform container images (amd64/arm64)

Quick Start

Prerequisites

  • Node.js 20+ LTS
  • Docker and Docker Compose (recommended)
  • Valkey 8.0+ or Redis (for storage backend)

Installation

# Clone repository
git clone <repository-url>
cd gds-mock-mcp

# Build and start all services
docker compose up -d

# Verify health
curl http://localhost:3000/health

Option 2: Local Development

# Install dependencies
npm install

# Start Valkey
docker run -d --name valkey -p 6379:6379 valkey/valkey:8-alpine

# Start HTTP server
node src/index.js

Testing the Server

# Check health
curl http://localhost:3000/health

# Initialize MCP session
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-protocol-version: 2025-11-25" \
  -d '{
    "jsonrpc": "2.0",
    "method": "initialize",
    "id": 1,
    "params": {
      "protocolVersion": "2025-11-25",
      "capabilities": {},
      "clientInfo": {"name": "test-client", "version": "1.0.0"}
    }
  }'

Environment Variables:

You can customize deployment with environment variables:

# Custom port
PORT=8080 docker compose up -d

# Change log level
LOG_LEVEL=debug docker compose up -d

# Bind to specific host
HOST=0.0.0.0 docker compose up -d

MCP Tools

The server provides 11 MCP tools for travel booking operations:

Flight Operations

  • searchFlights - Search for available flights
  • bookFlight - Book a flight with passenger details

Hotel Operations

  • searchHotels - Search for hotels by city
  • bookHotel - Book a hotel room

Car Rental Operations

  • searchCars - Search for rental cars
  • bookCar - Book a rental car

Booking Management

  • retrieveBooking - Get booking details by PNR
  • cancelBooking - Cancel an existing booking
  • listBookings - List all bookings in session

Session Management

  • getSessionInfo - Get current session information
  • clearSession - Clear all bookings from session

Usage Examples

Health Check

curl http://localhost:3000/health

1. Initialize MCP Session

First, initialize to get a session ID:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-protocol-version: 2025-11-25" \
  -d '{
    "jsonrpc": "2.0",
    "method": "initialize",
    "id": 1,
    "params": {
      "protocolVersion": "2025-11-25",
      "capabilities": {},
      "clientInfo": {"name": "test-client", "version": "1.0.0"}
    }
  }'

Extract the session ID from the response headers:

< mcp-session-id: 550e8400-e29b-41d4-a716-446655440000

2. List Available Tools

# Use the session ID from step 1
SESSION_ID="550e8400-e29b-41d4-a716-446655440000"

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-protocol-version: 2025-11-25" \
  -H "mcp-session-id: $SESSION_ID" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/list",
    "id": 2,
    "params": {}
  }'

3. Search Flights

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-protocol-version: 2025-11-25" \
  -H "mcp-session-id: $SESSION_ID" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "id": 3,
    "params": {
      "name": "searchFlights",
      "arguments": {
        "origin": "JFK",
        "destination": "LAX",
        "departureDate": "2026-05-01",
        "passengers": 1
      }
    }
  }'

Architecture

Remote MCP Transport

  • Protocol: MCP 2025-11-25 Streamable HTTP
  • Transport: HTTP/1.1 + Server-Sent Events (SSE)
  • Endpoint: /mcp for all MCP operations
  • Session Management: UUID v4 session IDs with 1-hour TTL

Production Deployment

For production use, consider using Nginx as a reverse proxy to add:

  • TLS/SSL encryption (HTTPS)
  • HTTP/2 support for clients
  • Additional rate limiting
  • Request logging

See docker/nginx.conf.example for a sample Nginx configuration.

Usage

MCP Tool: searchFlights

Search for available flights between two airports.

Input:

{
  "origin": "JFK",
  "destination": "LAX",
  "departureDate": "2026-06-15",
  "passengers": { "adults": 2 },
  "cabin": "economy"
}

Output:

{
  "search": { "origin": "JFK", "destination": "LAX", "departureDate": "2026-06-15" },
  "results": [
    {
      "id": "flight-0-1234567890",
      "flightNumber": "AA123",
      "airlineCode": "AA",
      "airlineName": "American Airlines",
      "originCode": "JFK",
      "destinationCode": "LAX",
      "departureTime": "2026-06-15T08:00:00",
      "arrivalTime": "2026-06-15T11:30:00",
      "duration": 390,
      "cabin": "economy",
      "price": 29900,
      "seatsAvailable": 15,
      "bookingClass": "Y",
      "status": "available"
    }
  ],
  "resultCount": 5
}

MCP Tool: bookFlight

Create a flight booking.

Input:

{
  "flightId": "flight-0-1234567890",
  "passengers": [
    {
      "firstName": "John",
      "lastName": "Doe",
      "type": "adult",
      "email": "john.doe@example.com"
    }
  ],
  "contactEmail": "john.doe@example.com",
  "flightDetails": { /* full flight object from search */ }
}

Output:

{
  "success": true,
  "pnr": "TEST-A1B2C3",
  "status": "confirmed",
  "message": "Flight booked successfully. PNR: TEST-A1B2C3",
  "booking": {
    "pnr": "TEST-A1B2C3",
    "passengers": [...],
    "flights": [...],
    "totalPrice": 29900,
    "currency": "USD"
  }
}

MCP Tool: retrieveBooking

Retrieve booking details by PNR.

Input:

{
  "pnr": "TEST-A1B2C3"
}

MCP Tool: cancelBooking

Cancel an existing booking.

Input:

{
  "pnr": "TEST-A1B2C3"
}

MCP Tool: listBookings

List all bookings in current session.

Input:

{
  "limit": 10,
  "offset": 0
}

Configuration

Configuration is managed via environment variables. Copy .env.example to .env and customize:

cp .env.example .env

Key Configuration Options

Variable Default Description
LOG_LEVEL info Logging verbosity (silent, error, warn, info, debug, trace)
VALKEY_HOST localhost Valkey/Redis host
VALKEY_PORT 6379 Valkey/Redis port
MCP_SESSION_TIMEOUT 3600 Session timeout in seconds (1 hour)
MOCK_DATA_SEED random Data generation mode (random, fixed, demo)

Architecture

┌─────────────────┐
│  MCP Client     │
│  (CLI/Agent)    │
└────────┬────────┘
         │ stdio
         ▼
┌─────────────────┐
│  GDS Mock MCP   │
│  Server         │
│  (Node.js 20)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Valkey 8.0+    │
│  (Storage)      │
└─────────────────┘

Project Structure

├── src/
│   ├── index.js           # Entry point
│   ├── server.js          # MCP server
│   ├── tools/             # MCP tool handlers
│   │   ├── flights.js     # Flight operations
│   │   └── bookings.js    # Booking management
│   ├── data/              # Mock data generators
│   │   ├── airports.js    # Airport data (100+ airports)
│   │   ├── airlines.js    # Airline data (30+ carriers)
│   │   ├── flights.js     # Flight generator
│   │   └── pnr.js         # PNR generation
│   ├── session/           # Session management
│   │   ├── manager.js     # Session lifecycle
│   │   └── storage.js     # Valkey client
│   ├── validation/        # Input validation
│   └── utils/             # Utilities (logging, errors)
├── docker/
│   ├── Dockerfile         # Multi-stage build
│   └── docker-bake.hcl    # Multi-platform config
├── tests/                 # Test suite
└── specs/                 # Design documents

Development

Running Tests

npm test                  # All tests
npm run test:unit         # Unit tests only
npm run test:integration  # Integration tests only

Code Quality

npm run lint              # Check code style
npm run lint:fix          # Fix code style issues
npm run format            # Format with Prettier
npm run format:check      # Check formatting

Building Docker Images

# Build for all platforms
npm run docker:build

# Or use buildx directly
docker buildx bake -f docker/docker-bake.hcl

# Build for specific platform
docker buildx bake -f docker/docker-bake.hcl amd64
docker buildx bake -f docker/docker-bake.hcl arm64

Troubleshooting

Server Won't Start

Problem: Server exits immediately after starting

Solution:

  1. Check Valkey is running: docker-compose ps valkey
  2. Verify connection: docker-compose logs valkey
  3. Check environment variables: cat .env

Connection Refused

Problem: ECONNREFUSED error connecting to Valkey

Solution:

  1. Ensure Valkey service is healthy: docker-compose ps
  2. Check network connectivity: docker network ls
  3. Verify VALKEY_HOST matches service name in docker-compose

Session Expired Errors

Problem: Session expired errors during testing

Solution:

  1. Increase MCP_SESSION_TIMEOUT in .env
  2. Ensure consistent session ID usage
  3. Check system time synchronization

PNR Not Found

Problem: Booking not found when retrieving by PNR

Solution:

  1. Verify PNR format: TEST-XXXXXX
  2. Confirm session ID matches booking session
  3. Check Valkey data persistence: docker-compose logs valkey

Performance

  • Search Response Time: < 100ms (mock data generation)
  • Booking Creation: < 200ms (Valkey write)
  • Concurrent Sessions: 50+ simultaneous MCP connections
  • Session Capacity: 1000+ bookings per session
  • Memory Footprint: ~50MB (Node.js + dependencies)

Contributing

This is a mock server for testing purposes. Contributions welcome for:

  • Additional airline/airport data
  • Enhanced mock data realism
  • Performance optimizations
  • Bug fixes

License

MIT License - See LICENSE file for details

Support

For issues and questions:

  • GitHub Issues: /issues
  • Documentation: See /specs directory for detailed design docs

Remember: This is a MOCK server. All bookings are simulated. Never use in production systems requiring real GDS connectivity.