510 lines
12 KiB
Markdown
510 lines
12 KiB
Markdown
# 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](./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
|
|
|
|
#### Option 1: Docker Deployment (Recommended)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
curl http://localhost:3000/health
|
|
```
|
|
|
|
### 1. Initialize MCP Session
|
|
|
|
First, initialize to get a session ID:
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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:**
|
|
```json
|
|
{
|
|
"origin": "JFK",
|
|
"destination": "LAX",
|
|
"departureDate": "2026-06-15",
|
|
"passengers": { "adults": 2 },
|
|
"cabin": "economy"
|
|
}
|
|
```
|
|
|
|
**Output:**
|
|
```json
|
|
{
|
|
"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:**
|
|
```json
|
|
{
|
|
"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:**
|
|
```json
|
|
{
|
|
"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:**
|
|
```json
|
|
{
|
|
"pnr": "TEST-A1B2C3"
|
|
}
|
|
```
|
|
|
|
### MCP Tool: cancelBooking
|
|
|
|
Cancel an existing booking.
|
|
|
|
**Input:**
|
|
```json
|
|
{
|
|
"pnr": "TEST-A1B2C3"
|
|
}
|
|
```
|
|
|
|
### MCP Tool: listBookings
|
|
|
|
List all bookings in current session.
|
|
|
|
**Input:**
|
|
```json
|
|
{
|
|
"limit": 10,
|
|
"offset": 0
|
|
}
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Configuration is managed via environment variables. Copy `.env.example` to `.env` and customize:
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
npm test # All tests
|
|
npm run test:unit # Unit tests only
|
|
npm run test:integration # Integration tests only
|
|
```
|
|
|
|
### Code Quality
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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: <repository-url>/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.
|