# MCP Tool Contracts: Mock GDS MCP Server **Branch**: `001-mock-gds-server` | **Date**: 2026-04-07 ## Overview This document defines the MCP tool schemas exposed by the Mock GDS MCP server. All tools follow the MCP JSON-RPC 2.0 protocol and include comprehensive JSON Schema validation. ## Tool Categories 1. **Flight Operations**: searchFlights, bookFlight 2. **Hotel Operations**: searchHotels, bookHotel 3. **Car Rental Operations**: searchCars, bookCar 4. **Booking Management**: retrieveBooking, cancelBooking, listBookings --- ## Flight Operations ### searchFlights Search for available flight options. **Tool Name**: `searchFlights` **Description**: Search for flights between two airports on a specific date. Returns mock flight options with realistic pricing, schedules, and availability. **Input Schema**: ```json { "type": "object", "properties": { "origin": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "Origin airport IATA code (3 letters, e.g., 'JFK')" }, "destination": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "Destination airport IATA code (3 letters, e.g., 'LAX')" }, "departureDate": { "type": "string", "format": "date", "description": "Departure date in ISO 8601 format (YYYY-MM-DD)" }, "passengers": { "type": "object", "properties": { "adults": { "type": "integer", "minimum": 1, "maximum": 9, "default": 1 }, "children": { "type": "integer", "minimum": 0, "maximum": 9, "default": 0 }, "infants": { "type": "integer", "minimum": 0, "maximum": 9, "default": 0 } }, "required": ["adults"] }, "cabin": { "type": "string", "enum": ["economy", "premium_economy", "business", "first"], "default": "economy" } }, "required": ["origin", "destination", "departureDate"] } ``` **Example Request**: ```json { "origin": "JFK", "destination": "LAX", "departureDate": "2026-06-15", "passengers": { "adults": 2 }, "cabin": "economy" } ``` --- ### bookFlight Create a flight booking. **Tool Name**: `bookFlight` **Description**: Book one or more flight segments with passenger details. Creates a PNR (Passenger Name Record) with TEST- prefix. **Input Schema**: ```json { "type": "object", "properties": { "flightIds": { "type": "array", "items": { "type": "string" }, "minItems": 1, "description": "Array of flight IDs from search results" }, "passengers": { "type": "array", "minItems": 1, "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["adult", "child", "infant"] }, "firstName": { "type": "string", "minLength": 1, "maxLength": 50 }, "lastName": { "type": "string", "minLength": 1, "maxLength": 50 }, "dateOfBirth": { "type": "string", "format": "date" }, "email": { "type": "string", "format": "email" }, "phone": { "type": "string" }, "frequentFlyerNumber": { "type": "string" } }, "required": ["type", "firstName", "lastName"] } }, "contactEmail": { "type": "string", "format": "email", "description": "Primary contact email" }, "contactPhone": { "type": "string", "description": "Primary contact phone" } }, "required": ["flightIds", "passengers"], "anyOf": [ { "required": ["contactEmail"] }, { "required": ["contactPhone"] } ] } ``` --- ## Hotel Operations ### searchHotels **Tool Name**: `searchHotels` **Description**: Search for hotel properties in a city with check-in/check-out dates. **Input Schema**: ```json { "type": "object", "properties": { "cityCode": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "City IATA code (3 letters, e.g., 'LAX')" }, "checkInDate": { "type": "string", "format": "date" }, "checkOutDate": { "type": "string", "format": "date" }, "guests": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 }, "starRating": { "type": "integer", "minimum": 1, "maximum": 5, "description": "Minimum star rating filter (optional)" } }, "required": ["cityCode", "checkInDate", "checkOutDate"] } ``` --- ### bookHotel **Tool Name**: `bookHotel` **Description**: Book a hotel reservation. Can create a new PNR or add to an existing flight booking. **Input Schema**: ```json { "type": "object", "properties": { "hotelId": { "type": "string" }, "existingPnr": { "type": "string", "pattern": "^TEST-[A-Z0-9]{6}$", "description": "Optional: Add hotel to existing booking" }, "guests": { "type": "array", "minItems": 1, "items": { "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "email": { "type": "string", "format": "email" } }, "required": ["firstName", "lastName"] } }, "specialRequests": { "type": "string" } }, "required": ["hotelId", "guests"] } ``` --- ## Car Rental Operations ### searchCars **Tool Name**: `searchCars` **Description**: Search for car rental options at an airport or city location. **Input Schema**: ```json { "type": "object", "properties": { "pickupLocationCode": { "type": "string", "pattern": "^[A-Z]{3}$" }, "dropoffLocationCode": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "Defaults to pickup location if not specified" }, "pickupDate": { "type": "string", "format": "date-time" }, "dropoffDate": { "type": "string", "format": "date-time" }, "driverAge": { "type": "integer", "minimum": 21, "maximum": 99, "default": 30 } }, "required": ["pickupLocationCode", "pickupDate", "dropoffDate"] } ``` --- ### bookCar **Tool Name**: `bookCar` **Description**: Book a car rental. Can create a new PNR or add to an existing booking. --- ## Booking Management Operations ### retrieveBooking **Tool Name**: `retrieveBooking` **Description**: Fetch complete booking details including all segments. **Input Schema**: ```json { "type": "object", "properties": { "pnr": { "type": "string", "pattern": "^TEST-[A-Z0-9]{6}$" } }, "required": ["pnr"] } ``` --- ### cancelBooking **Tool Name**: `cancelBooking` **Description**: Cancel a confirmed booking. **Input Schema**: ```json { "type": "object", "properties": { "pnr": { "type": "string", "pattern": "^TEST-[A-Z0-9]{6}$" }, "reason": { "type": "string" } }, "required": ["pnr"] } ``` --- ### listBookings **Tool Name**: `listBookings` **Description**: Retrieve a list of all PNRs created in the current MCP session. **Input Schema**: ```json { "type": "object", "properties": { "status": { "type": "string", "enum": ["all", "confirmed", "cancelled"], "default": "all" } } } ``` --- ## Error Responses All tools return standard MCP errors: - **-32602**: Invalid params (validation failure) - **-32603**: Internal error (server error) - **-32001**: Resource not found (invalid PNR, airport code, etc.) - **-32002**: Business logic error (cancelled booking, date in past, etc.) **Error Format**: ```json { "code": -32602, "message": "Invalid airport code 'XYZ': must be a valid 3-letter IATA code", "data": { "field": "origin", "value": "XYZ" } } ``` --- ## MCP Resource Endpoints - `gds://session/current` - Current session metadata - `gds://session/bookings` - List of all bookings - `gds://mock-data/airports` - Mock airport data - `gds://mock-data/airlines` - Mock airline data --- ## Protocol Notes - All tools use JSON-RPC 2.0 over stdio (default) or SSE - Tool schemas validated before execution - Timestamps use ISO 8601 format - Prices in USD cents (integer) - All PNRs prefixed with "TEST-" for safety --- ## Remote Access Endpoints (Added 2026-04-07) The following endpoints are available when running in HTTP/2 remote transport mode. ### Health Check Endpoint **Endpoint**: `GET /health` **Description**: Returns server operational status for monitoring and health checks. This endpoint is unauthenticated and exempt from rate limiting. **Use Cases**: - Load balancer health checks - Monitoring system integration (Prometheus, Datadog, etc.) - Deployment validation - Debugging connection and memory issues **HTTP Method**: GET **Authentication**: None (publicly accessible) **Rate Limiting**: Exempt (not subject to rate limits) **Request**: No body required **Response Schema**: ```json { "type": "object", "properties": { "status": { "type": "string", "enum": ["healthy", "degraded", "unhealthy"], "description": "Overall server health status" }, "uptime": { "type": "integer", "description": "Server uptime in seconds since start" }, "version": { "type": "string", "description": "Server version (from package.json)" }, "connections": { "type": "object", "properties": { "stdio": { "type": "integer", "description": "Active stdio connections (0 or 1)" }, "http": { "type": "integer", "description": "Active HTTP/2 connections" }, "total": { "type": "integer", "description": "Total active connections" } }, "required": ["stdio", "http", "total"] }, "sessions": { "type": "object", "properties": { "active": { "type": "integer", "description": "Sessions with recent activity (within 5 minutes)" }, "total": { "type": "integer", "description": "Total sessions in storage" } }, "required": ["active", "total"] }, "storage": { "type": "object", "properties": { "connected": { "type": "boolean", "description": "Valkey connection status" }, "responseTime": { "type": "number", "description": "Valkey ping response time in milliseconds" } }, "required": ["connected", "responseTime"] }, "memory": { "type": "object", "properties": { "used": { "type": "number", "description": "Process memory used in MB" }, "total": { "type": "number", "description": "Total system memory in MB" }, "percentage": { "type": "number", "description": "Memory usage percentage (0-1)" } }, "required": ["used", "total", "percentage"] }, "timestamp": { "type": "integer", "description": "Health check timestamp (Unix milliseconds)" } }, "required": ["status", "uptime", "version", "connections", "sessions", "storage", "memory", "timestamp"] } ``` **Status Determination**: - **healthy** (200 OK): All systems operational - Storage connected - Memory usage < 80% - Valkey response time < 100ms - **degraded** (200 OK): Some issues but still serving requests - Storage slow (ping 100-500ms) - Memory usage 80-90% - **unhealthy** (503 Service Unavailable): Critical issues - Storage disconnected - Memory usage > 90% - Unable to serve requests **Example Response (Healthy)**: ```json { "status": "healthy", "uptime": 3600, "version": "0.1.0", "connections": { "stdio": 0, "http": 12, "total": 12 }, "sessions": { "active": 8, "total": 15 }, "storage": { "connected": true, "responseTime": 2.5 }, "memory": { "used": 45.2, "total": 8192, "percentage": 0.0055 }, "timestamp": 1712486460000 } ``` **Example Response (Degraded)**: ```json { "status": "degraded", "uptime": 7200, "version": "0.1.0", "connections": { "stdio": 0, "http": 45, "total": 45 }, "sessions": { "active": 42, "total": 50 }, "storage": { "connected": true, "responseTime": 150 }, "memory": { "used": 6553.6, "total": 8192, "percentage": 0.8 }, "timestamp": 1712490060000 } ``` **Example Response (Unhealthy)**: ```json { "status": "unhealthy", "uptime": 10800, "version": "0.1.0", "connections": { "stdio": 0, "http": 0, "total": 0 }, "sessions": { "active": 0, "total": 0 }, "storage": { "connected": false, "responseTime": null }, "memory": { "used": 120, "total": 8192, "percentage": 0.015 }, "timestamp": 1712493660000 } ``` **cURL Example**: ```bash curl -i http://localhost:8080/health ``` **Load Balancer Integration** (Nginx): ```nginx upstream mcp_backend { server mcp-server:3000; health_check interval=10s uri=/health; } ``` **Prometheus Monitoring**: ```yaml scrape_configs: - job_name: 'mcp-server' static_configs: - targets: ['localhost:8080'] metrics_path: '/health' scrape_interval: 30s ``` --- ## Rate Limiting (HTTP Mode Only) When running in HTTP/2 remote mode, all MCP tool endpoints are subject to rate limiting. **Algorithm**: Sliding Window Counter (Hybrid) **Default Limits**: - 100 requests per minute per client IP address - Window size: 60 seconds - Burst tolerance: ~150 requests in worst-case window overlap **Rate Limit Headers** (included in all HTTP responses): ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 45 X-RateLimit-Reset: 1712486520 ``` **Rate Limit Exceeded Response** (429 Too Many Requests): ```json { "error": "Rate limit exceeded", "code": "RATE_LIMIT_EXCEEDED", "limit": 100, "current": 105, "resetAt": "2026-04-07T10:02:00.000Z", "retryAfter": 15 } ``` **HTTP Headers on 429**: ``` HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1712486520 Retry-After: 15 Content-Type: application/json ``` **Exemptions**: - Health check endpoint (`/health`) is exempt from rate limiting - CORS preflight requests (OPTIONS) are exempt **Configuration**: ```bash RATE_LIMIT_ENABLED=true RATE_LIMIT_PER_MINUTE=100 RATE_LIMIT_WINDOW_SECONDS=60 ``` --- ## CORS Headers (HTTP Mode Only) When running in HTTP/2 remote mode, all endpoints support cross-origin requests. **CORS Policy**: Permissive wildcard (`Access-Control-Allow-Origin: *`) **Preflight Request** (OPTIONS): ``` OPTIONS /mcp HTTP/1.1 Origin: https://web-client.example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type, MCP-Session-ID ``` **Preflight Response**: ``` HTTP/1.1 204 No Content Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Content-Type, MCP-Session-ID, X-Requested-With Access-Control-Max-Age: 86400 ``` **Actual Request Headers** (added to all responses): ``` Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: false Access-Control-Expose-Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset ``` **Security Note**: Wildcard CORS is appropriate for development/testing with mock data only. Deploy within private networks (VPN, firewalls) for security. --- ## Transport Mode Configuration **Environment Variables**: ```bash # Transport selection TRANSPORT_MODE=stdio|http|both # Default: stdio # HTTP/2 configuration (when http or both) HTTP_PORT=3000 # Internal port (default: 3000) HTTP_HOST=127.0.0.1 # Bind address (default: 127.0.0.1 for proxy) # External access via reverse proxy # Nginx listens on :8080 (HTTP/2 + TLS) # Proxies to mcp-server:3000 (HTTP/1.1) ``` **Protocol Notes (Updated)**: - stdio mode: JSON-RPC 2.0 over stdin/stdout (local only) - http mode: JSON-RPC 2.0 over SSE via StreamableHTTPServerTransport - HTTP/2: Provided by nginx reverse proxy (terminates HTTP/2, proxies HTTP/1.1) - CORS: Enabled in http mode, wildcard policy - Rate limiting: Enabled in http mode, IP-based tracking - Health checks: Available in http mode at `/health`