fixing jsonSchema validation by using zod
This commit is contained in:
509
README.md
Normal file
509
README.md
Normal file
@@ -0,0 +1,509 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user