UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

254 lines (253 loc) • 8.39 kB
"use strict"; /** * @moduleName: MCP Transport Abstraction Layer * @version: 2.0.0 * @since: 2025-07-25 * @lastUpdated: 2025-07-25 * @projectSummary: Enhanced MCP Quiz Server - Future-Ready Transport Architecture * @techStack: TypeScript, JSON-RPC 2.0, MCP Protocol, Transport Abstraction * @dependency: None (transport interface definitions) * @interModuleDependency: ../types/mcp-types, core protocol handlers * @requirementsTraceability: * {@link Requirements.REQ_MCP_001} (JSON-RPC 2.0 MCP Protocol) * @briefDescription: Transport abstraction layer to support current and future MCP transport protocols including STDIO, HTTP, SSE, WebSocket, and Streamable HTTP * @methods: Transport interface definitions, factory patterns, protocol adapters * @contributors: GitHub Copilot, Future Transport Design Team * @examples: * - STDIO transport for VS Code integration * - HTTP transport for REST API compatibility * - SSE transport for streaming responses * - Future WebSocket transport support * @vulnerabilitiesAssessment: Transport isolation prevents protocol-specific attacks, standardized error handling across transports */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TransportUtils = exports.TRANSPORT_CAPABILITIES = exports.BaseTransport = exports.TransportType = void 0; /** * Transport types supported by MCP */ var TransportType; (function (TransportType) { TransportType["STDIO"] = "stdio"; TransportType["HTTP"] = "http"; TransportType["SSE"] = "sse"; TransportType["STREAMABLE_HTTP"] = "streamable-http"; TransportType["WEBSOCKET"] = "websocket"; TransportType["GRPC"] = "grpc"; TransportType["CUSTOM"] = "custom"; })(TransportType || (exports.TransportType = TransportType = {})); /** * Abstract base transport class */ class BaseTransport { constructor() { this.events = {}; this.metrics = { messagesReceived: 0, messagesSent: 0, errors: 0, connectionUptime: 0, averageResponseTime: 0, currentConnections: 0, reconnections: 0, }; } onMessage(handler) { this.messageHandler = handler; } async processMessage(request, metadata) { const startTime = Date.now(); try { this.metrics.messagesReceived++; if (!this.messageHandler) { throw new Error('No message handler registered'); } const response = await this.messageHandler(request); // Update metrics const responseTime = Date.now() - startTime; this.metrics.averageResponseTime = (this.metrics.averageResponseTime + responseTime) / 2; return response; } catch (error) { this.metrics.errors++; // Return standardized error response return { jsonrpc: '2.0', id: request.id, error: { code: -32603, message: 'Transport processing error', data: error instanceof Error ? error.message : String(error), }, }; } } getMetrics() { return { ...this.metrics }; } on(event, listener) { this.events[event] = listener; } emit(event, ...args) { const listener = this.events[event]; if (listener) { listener(...args); } } } exports.BaseTransport = BaseTransport; /** * Transport capability definitions for each transport type */ exports.TRANSPORT_CAPABILITIES = { [TransportType.STDIO]: { bidirectional: true, streaming: false, serverSentEvents: false, realTime: true, connectionPersistent: true, authentication: false, compression: false, binaryData: false, multiplexing: false, }, [TransportType.HTTP]: { bidirectional: true, streaming: false, serverSentEvents: false, realTime: false, connectionPersistent: false, authentication: true, compression: true, binaryData: true, multiplexing: false, }, [TransportType.SSE]: { bidirectional: true, streaming: true, serverSentEvents: true, realTime: true, connectionPersistent: true, authentication: true, compression: false, binaryData: false, multiplexing: false, }, [TransportType.STREAMABLE_HTTP]: { bidirectional: true, streaming: true, serverSentEvents: true, realTime: true, connectionPersistent: true, authentication: true, compression: true, binaryData: true, multiplexing: true, }, [TransportType.WEBSOCKET]: { bidirectional: true, streaming: true, serverSentEvents: false, realTime: true, connectionPersistent: true, authentication: true, compression: true, binaryData: true, multiplexing: true, }, [TransportType.GRPC]: { bidirectional: true, streaming: true, serverSentEvents: false, realTime: true, connectionPersistent: true, authentication: true, compression: true, binaryData: true, multiplexing: true, }, [TransportType.CUSTOM]: { bidirectional: true, streaming: true, serverSentEvents: true, realTime: true, connectionPersistent: true, authentication: true, compression: true, binaryData: true, multiplexing: true, }, }; /** * Transport utility functions */ class TransportUtils { /** * Detect optimal transport based on context */ static detectOptimalTransport(context) { var _a, _b, _c; // VS Code environment - prefer STDIO if (context.environment === 'vscode') { return TransportType.STDIO; } // Browser environment - prefer SSE or Streamable HTTP if (context.environment === 'browser') { // Check for Streamable HTTP support if ((_a = context.capabilities) === null || _a === void 0 ? void 0 : _a.includes('streamable-http')) { return TransportType.STREAMABLE_HTTP; } // Fall back to SSE if ((_b = context.capabilities) === null || _b === void 0 ? void 0 : _b.includes('sse')) { return TransportType.SSE; } // Fall back to HTTP return TransportType.HTTP; } // Node.js environment - prefer HTTP or WebSocket if (context.environment === 'node') { if ((_c = context.capabilities) === null || _c === void 0 ? void 0 : _c.includes('websocket')) { return TransportType.WEBSOCKET; } return TransportType.HTTP; } // Default to HTTP for unknown environments return TransportType.HTTP; } /** * Validate transport configuration */ static validateConfig(type, config) { const capabilities = exports.TRANSPORT_CAPABILITIES[type]; // Add validation logic based on transport type and capabilities switch (type) { case TransportType.STDIO: return true; // STDIO has minimal configuration requirements case TransportType.HTTP: case TransportType.SSE: case TransportType.STREAMABLE_HTTP: return !!(config.host || config.path); case TransportType.WEBSOCKET: return !!(config.host && config.port); default: return true; } } /** * Get recommended transport for specific use case */ static getRecommendedTransport(useCase) { switch (useCase) { case 'development': return TransportType.STDIO; case 'production': return TransportType.STREAMABLE_HTTP; case 'streaming': return TransportType.SSE; case 'realtime': return TransportType.WEBSOCKET; default: return TransportType.HTTP; } } } exports.TransportUtils = TransportUtils;