259 lines
12 KiB
Markdown
259 lines
12 KiB
Markdown
# Implementation Plan: Mock GDS MCP Server
|
|
|
|
**Branch**: `001-mock-gds-server` | **Date**: 2026-04-11 | **Spec**: [spec.md](./spec.md)
|
|
**Input**: Feature specification from `/specs/001-mock-gds-server/spec.md`
|
|
|
|
## Summary
|
|
|
|
Build a Mock Global Distribution System (GDS) server exposing flight, hotel, and car rental booking operations as Model Context Protocol (MCP) tools via HTTP transport. The server provides realistic mock data for testing travel applications without connecting to real GDS systems, with session-based state management and multi-service booking capabilities.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: Node.js 20 LTS with TypeScript 6.0.2
|
|
**Primary Dependencies**: @modelcontextprotocol/sdk ^1.0.4 (MCP protocol), @modelcontextprotocol/server ^2.0.0-alpha.2 (McpServer), @modelcontextprotocol/express ^2.0.0-alpha.2 (HTTP transport), ioredis ^5.4.1 (Valkey client), Express ^5.2.1, pino ^9.5.0 (structured logging)
|
|
**Storage**: Valkey 8.0+ (Redis-compatible in-memory store with persistence for PNRs and sessions)
|
|
**Testing**: Node.js built-in test runner or Vitest (TBD in Phase 0)
|
|
**Target Platform**: Linux/macOS servers, Docker containers (multi-platform: linux/amd64, linux/arm64)
|
|
**Project Type**: MCP server (HTTP-based tool provider for AI agents and MCP clients)
|
|
**Performance Goals**: Support 100+ concurrent sessions, <200ms p95 response time for search operations, <500ms for booking operations
|
|
**Constraints**: Stateless HTTP transport design (no server-side session affinity required), connection pooling for Valkey, structured logging for observability, all operations deterministic for given inputs
|
|
**Scale/Scope**: 11 MCP tools (search/book/cancel for flights/hotels/cars, plus session management), ~5000 lines of TypeScript, realistic mock data (100+ airports, 20+ airlines, 50+ hotels, 15+ car companies)
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
|
|
|
### I. MCP Protocol Compliance ✅
|
|
- **Status**: COMPLIANT
|
|
- **Evidence**: Using official @modelcontextprotocol/server package with McpServer class, all tools registered via standard API, StreamableHTTPServerTransport for MCP HTTP specification compliance
|
|
- **Validation**: McpServer handles JSON-RPC 2.0 message format automatically, capabilities declared in server initialization, error responses use MCP error structures
|
|
|
|
### II. Mock Data Realism ✅
|
|
- **Status**: COMPLIANT
|
|
- **Evidence**: Mock data uses real IATA airport codes (JFK, LAX, etc.), valid airline codes (AA, DL, UA), realistic pricing ($200-$800 flights, $80-$400 hotels), flight times respect geography and time zones
|
|
- **Implementation**: data/ directory contains realistic airlines, airports, flights, hotels, cars with internally consistent relationships
|
|
|
|
### III. No Real Transactions (Safety Guarantee) ✅
|
|
- **Status**: COMPLIANT
|
|
- **Evidence**: Server is pure mock implementation with no external GDS connections, PNRs generated locally with clear test format, no production API keys accepted
|
|
- **Safety Markers**: Documentation includes "MOCK" and "FOR TESTING ONLY" disclaimers, no real booking system integration
|
|
|
|
### IV. Tool-Based Architecture ✅
|
|
- **Status**: COMPLIANT
|
|
- **Evidence**: 11 MCP tools exposed (searchFlights, bookFlight, searchHotels, bookHotel, searchCars, bookCar, retrieveBooking, cancelBooking, listBookings, getSessionInfo, clearSession)
|
|
- **Implementation**: Each tool registered with description and inputSchema, tools are independently callable, responses deterministic for same inputs
|
|
|
|
### V. Stateful Session Management ✅
|
|
- **Status**: COMPLIANT
|
|
- **Evidence**: Session manager tracks state per session ID, Valkey storage isolates bookings by session, PNRs stored with configurable TTL (default 1 hour)
|
|
- **Implementation**: SessionManager class provides create/get/update/delete operations, state transitions explicit (search → book → confirm)
|
|
|
|
### VI. Observable and Debuggable ✅
|
|
- **Status**: COMPLIANT
|
|
- **Evidence**: Structured logging via pino with configurable levels (INFO, DEBUG, ERROR), all tool calls logged with parameters and results, error messages include actionable guidance
|
|
- **Implementation**: Logger middleware logs all MCP requests, tool execution tracked with duration metrics, health endpoint for server status
|
|
|
|
**Gate Result**: ✅ PASS - All constitutional requirements met
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/001-mock-gds-server/
|
|
├── plan.md # This file (updated with TypeScript details)
|
|
├── research.md # Technology decisions and best practices
|
|
├── data-model.md # Entity definitions and state models
|
|
├── quickstart.md # Getting started guide
|
|
├── contracts/ # MCP tool schemas and API contracts
|
|
│ └── mcp-tools.md # Tool definitions with input/output schemas
|
|
├── spec.md # Feature specification
|
|
└── tasks.md # Implementation task breakdown
|
|
```
|
|
|
|
### Source Code (repository root)
|
|
|
|
```text
|
|
src/ # TypeScript source files
|
|
├── index.ts # Main entry point, tool registration
|
|
├── server.ts # GDSMockServer class (McpServer wrapper)
|
|
├── data/ # Mock data generators
|
|
│ ├── airlines.ts # Airline database and lookups
|
|
│ ├── airports.ts # Airport codes and geography
|
|
│ ├── flights.ts # Flight generation logic
|
|
│ ├── hotels.ts # Hotel data and pricing
|
|
│ ├── cars.ts # Car rental options
|
|
│ └── pnr.ts # PNR generation utilities
|
|
├── session/ # Session and storage management
|
|
│ ├── manager.ts # SessionManager class
|
|
│ ├── storage.ts # ValkeyStorage (Redis client wrapper)
|
|
│ └── valkey-event-store.ts # Event store for MCP resumability
|
|
├── tools/ # MCP tool implementations
|
|
│ ├── flights.ts # searchFlights, bookFlight
|
|
│ ├── hotels.ts # searchHotels, bookHotel
|
|
│ ├── cars.ts # searchCars, bookCar
|
|
│ ├── bookings.ts # retrieveBooking, cancelBooking, listBookings
|
|
│ └── session.ts # getSessionInfo, clearSession
|
|
├── transports/ # HTTP transport layer
|
|
│ ├── http-server.ts # StreamableHTTPServerTransport setup
|
|
│ └── factory.ts # Transport factory
|
|
├── middleware/ # Express middleware
|
|
│ ├── cors.ts # CORS policy (allow all origins)
|
|
│ ├── rate-limit.ts # IP-based rate limiting
|
|
│ ├── logger.ts # Request logging
|
|
│ ├── protocol-version.ts # MCP-Protocol-Version validation
|
|
│ └── message-normalization.ts # Request normalization
|
|
├── utils/ # Shared utilities
|
|
│ ├── errors.ts # Error classes (MCPError, ValidationError, etc.)
|
|
│ └── logger.ts # Pino logger configuration
|
|
└── validation/ # Input validation
|
|
└── validators.ts # Validation helpers
|
|
|
|
dist/ # Compiled JavaScript output (build artifacts)
|
|
├── index.js
|
|
├── server.js
|
|
└── [mirrors src/ structure]
|
|
|
|
tests/ # Test files (TBD)
|
|
├── unit/
|
|
├── integration/
|
|
└── contract/
|
|
|
|
docker/ # Docker configuration
|
|
├── Dockerfile # Multi-platform build
|
|
└── entrypoint.sh # Container startup script
|
|
|
|
tsconfig.json # TypeScript compiler configuration
|
|
package.json # Dependencies and scripts
|
|
```
|
|
|
|
**Structure Decision**: Single Node.js/TypeScript project with clear separation of concerns. Source in `src/` compiled to `dist/` via TypeScript compiler. MCP tools in `tools/`, data generators in `data/`, session management in `session/`, HTTP transport in `transports/`. Middleware chain handles CORS, rate limiting, protocol validation. Valkey for persistent storage. Docker support for containerized deployment.
|
|
|
|
## Complexity Tracking
|
|
|
|
**No constitution violations** - All core principles satisfied without requiring exceptions or workarounds.
|
|
|
|
## Phase 0: Research & Technology Decisions
|
|
|
|
### Technology Stack Rationale
|
|
|
|
#### Node.js 20 LTS + TypeScript
|
|
**Decision**: Use Node.js 20 LTS with TypeScript 6.0.2 for type safety and modern JavaScript features
|
|
**Rationale**:
|
|
- MCP SDK officially supports Node.js with comprehensive TypeScript typings
|
|
- Strong ecosystem for HTTP servers and real-time streaming (SSE)
|
|
- TypeScript provides compile-time type checking reducing runtime errors
|
|
- ES2022 features (top-level await, private fields) improve code quality
|
|
- Active LTS support ensures stability and security updates
|
|
|
|
**Alternatives Considered**:
|
|
- Python with FastAPI: Good MCP support but weaker typing story, slower cold starts
|
|
- Go: Excellent performance but less mature MCP ecosystem
|
|
- Deno: Modern runtime but MCP SDK compatibility uncertain
|
|
|
|
#### MCP SDK Architecture
|
|
**Decision**: Use high-level `McpServer` from `@modelcontextprotocol/server` package
|
|
**Rationale**:
|
|
- Simplified tool registration API: `registerTool(name, config, callback)`
|
|
- Automatic JSON-RPC 2.0 message handling
|
|
- Built-in error handling and protocol validation
|
|
- Recommended approach per MCP SDK examples
|
|
- Reduces boilerplate compared to low-level `Server` class
|
|
|
|
**Implementation**:
|
|
```typescript
|
|
const server = new McpServer(
|
|
{ name: 'gds-mock-mcp', version: '0.1.0' },
|
|
{ capabilities: { tools: {}, logging: {} } }
|
|
);
|
|
server.registerTool('searchFlights', { description, inputSchema }, handler);
|
|
```
|
|
|
|
#### Valkey for State Storage
|
|
**Decision**: Valkey 8.0+ (Redis-compatible) for session and booking storage
|
|
**Rationale**:
|
|
- In-memory performance (<1ms read/write) meets latency requirements
|
|
- TTL support for automatic PNR expiration (1 hour default)
|
|
- Connection pooling via ioredis client
|
|
- Redis protocol compatibility enables ecosystem tooling
|
|
- Optional persistence (RDB/AOF) for development convenience
|
|
|
|
**Alternatives Considered**:
|
|
- In-memory only: Fast but state lost on restart, not suitable for demos
|
|
- PostgreSQL: Overkill for mock data, adds deployment complexity
|
|
- SQLite: File-based but lacks TTL and concurrent access patterns
|
|
|
|
#### HTTP Transport Strategy
|
|
**Decision**: StreamableHTTPServerTransport in stateless mode with Express 5
|
|
**Rationale**:
|
|
- MCP HTTP specification (2025-11-25) mandates HTTP/1.1 + SSE
|
|
- Stateless mode allows horizontal scaling (no session affinity)
|
|
- Express 5 provides modern middleware architecture
|
|
- @modelcontextprotocol/express package simplifies integration
|
|
- Health endpoint (`/health`) for monitoring without MCP overhead
|
|
|
|
**Key Pattern**:
|
|
```typescript
|
|
const transport = new StreamableHTTPServerTransport({
|
|
sessionIdGenerator: undefined // Stateless - clients manage sessions
|
|
});
|
|
await transport.handleRequest(req, res); // Processes MCP messages
|
|
```
|
|
|
|
#### Logging Strategy
|
|
**Decision**: Structured JSON logging via pino with configurable levels
|
|
**Rationale**:
|
|
- Structured logs enable automated analysis and monitoring
|
|
- Pino is fastest Node.js logger (benchmarks show 10x faster than Winston)
|
|
- Log levels (DEBUG, INFO, ERROR) support development and production
|
|
- Tool execution tracking with duration metrics
|
|
- Correlation IDs via session tracking
|
|
|
|
**Output Example**:
|
|
```json
|
|
{
|
|
"level": "INFO",
|
|
"time": "2026-04-11T18:37:43.129Z",
|
|
"service": "gds-mock-mcp",
|
|
"tool": "searchFlights",
|
|
"sessionId": "abc123",
|
|
"duration": 45,
|
|
"msg": "Tool execution completed"
|
|
}
|
|
```
|
|
|
|
### Testing Approach
|
|
**Decision**: Node.js built-in test runner with contract tests for MCP compliance
|
|
**Rationale**:
|
|
- Node.js 20 includes native test runner (no external dependencies)
|
|
- Contract tests validate MCP tool schemas and responses
|
|
- Integration tests cover multi-step workflows (search → book → cancel)
|
|
- Unit tests for data generators and validation logic
|
|
|
|
**Test Categories**:
|
|
1. **Contract Tests**: Verify MCP tool schemas match declared types
|
|
2. **Integration Tests**: End-to-end workflows with Valkey
|
|
3. **Unit Tests**: Data generation, validation, PNR logic
|
|
|
|
### Development Tooling
|
|
**Decision**:
|
|
- `tsx` for development mode with hot reload
|
|
- `tsc` for production builds
|
|
- ESLint + Prettier for code quality
|
|
- Docker multi-platform builds (linux/amd64, linux/arm64)
|
|
|
|
**Scripts**:
|
|
```json
|
|
{
|
|
"dev": "tsx watch src/index.ts --verbose",
|
|
"build": "tsc",
|
|
"start": "node dist/index.js",
|
|
"test": "node --test tests/**/*.test.js"
|
|
}
|
|
```
|
|
|
|
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
|
|-----------|------------|-------------------------------------|
|
|
| [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
|
|
| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |
|