Files

747 lines
16 KiB
Markdown

# 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`