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.

233 lines (232 loc) 8.83 kB
"use strict"; /** * @moduleName: Transport Factory - Multi-Protocol Support * @version: 2.0.0 * @since: 2025-07-25 * @lastUpdated: 2025-07-25 * @projectSummary: Enhanced MCP Quiz Server - Transport Factory and Registry * @techStack: TypeScript, Factory Pattern, Transport Abstraction, MCP Protocol * @dependency: All transport implementations * @interModuleDependency: ./transport-abstraction, ./stdio-transport, ./sse-transport, ./http-transport * @requirementsTraceability: * {@link Requirements.REQ_MCP_001} (JSON-RPC 2.0 MCP Protocol) * @briefDescription: Factory and registry for creating and managing multiple transport protocols * @methods: createTransport, detectTransport, registerTransport, getAvailableTransports * @contributors: GitHub Copilot, Transport Architecture Team * @examples: * - Auto-detect transport based on environment * - Create multiple transports for hybrid deployments * - Register custom transport protocols * @vulnerabilitiesAssessment: Transport validation, configuration security, protocol isolation */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TransportAutoDetection = exports.getDefaultTransport = exports.getSupportedTransports = exports.detectTransport = exports.createTransport = exports.transportFactory = exports.MCPTransportFactory = void 0; const stdio_transport_1 = require("./stdio-transport"); const transport_abstraction_1 = require("./transport-abstraction"); /** * Comprehensive transport factory implementation */ class MCPTransportFactory { constructor() { this.registrations = new Map(); this.registerBuiltInTransports(); } /** * Create a transport instance */ createTransport(type, config) { const registration = this.registrations.get(type); if (!registration) { throw new Error(`Transport type '${type}' is not registered`); } if (!registration.supported) { throw new Error(`Transport type '${type}' is not supported in this environment`); } // Validate configuration if (config && !transport_abstraction_1.TransportUtils.validateConfig(type, config)) { throw new Error(`Invalid configuration for transport type '${type}'`); } try { return new registration.constructor(config); } catch (error) { throw new Error(`Failed to create transport '${type}': ${error}`); } } /** * Get all supported transport types */ getSupportedTransports() { return Array.from(this.registrations.values()) .filter(reg => reg.supported) .map(reg => reg.type); } /** * Detect optimal transport for given context */ detectTransport(context) { const optimalType = transport_abstraction_1.TransportUtils.detectOptimalTransport(context); // Verify the detected transport is supported const registration = this.registrations.get(optimalType); if (registration && registration.supported) { return optimalType; } // Fall back to first available transport const fallback = this.getSupportedTransports()[0]; return fallback || null; } /** * Register a custom transport */ registerTransport(type, constructor, description, isDefault = false) { this.registrations.set(type, { type, constructor, description, isDefault, supported: true, }); console.log(`🔌 Registered transport: ${type} - ${description}`); } /** * Get available transports with metadata */ getAvailableTransports() { return Array.from(this.registrations.values()).map(reg => ({ type: reg.type, description: reg.description, isDefault: reg.isDefault, supported: reg.supported, })); } /** * Check if a transport type is supported */ isSupported(type) { const registration = this.registrations.get(type); return registration ? registration.supported : false; } /** * Get default transport for current environment */ getDefaultTransport() { // Check for explicitly marked default for (const [type, registration] of this.registrations) { if (registration.isDefault && registration.supported) { return type; } } // Fall back to first supported transport const supported = this.getSupportedTransports(); return supported.length > 0 ? supported[0] : null; } /** * Create multiple transports for hybrid deployment */ createMultipleTransports(configs) { const transports = []; for (const { type, config } of configs) { try { const transport = this.createTransport(type, config); transports.push(transport); } catch (error) { console.error(`Failed to create transport ${type}:`, error); } } return transports; } /** * Register built-in transport implementations */ registerBuiltInTransports() { // STDIO Transport (VS Code, local development) this.registrations.set(transport_abstraction_1.TransportType.STDIO, { type: transport_abstraction_1.TransportType.STDIO, constructor: stdio_transport_1.StdioTransport, description: 'Standard Input/Output transport for VS Code integration', isDefault: this.isNodeEnvironment() && !this.isBrowserEnvironment(), supported: this.isNodeEnvironment(), }); console.log(`🏭 Registered ${this.registrations.size} transport types`); } /** * Environment detection helpers */ isNodeEnvironment() { return (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.node === 'string'); } isBrowserEnvironment() { return typeof window !== 'undefined' && typeof document !== 'undefined'; } } exports.MCPTransportFactory = MCPTransportFactory; /** * Global transport factory instance */ exports.transportFactory = new MCPTransportFactory(); /** * Convenience functions */ const createTransport = (type, config) => exports.transportFactory.createTransport(type, config); exports.createTransport = createTransport; const detectTransport = (context) => exports.transportFactory.detectTransport(context); exports.detectTransport = detectTransport; const getSupportedTransports = () => exports.transportFactory.getSupportedTransports(); exports.getSupportedTransports = getSupportedTransports; const getDefaultTransport = () => exports.transportFactory.getDefaultTransport(); exports.getDefaultTransport = getDefaultTransport; /** * Auto-detection utility */ class TransportAutoDetection { /** * Detect environment and return optimal transport configuration */ static detectEnvironment() { let environment = 'unknown'; // Detect VS Code environment if (typeof process !== 'undefined' && process.env.VSCODE_PID) { environment = 'vscode'; } // Detect Node.js environment else if (typeof process !== 'undefined' && process.versions && process.versions.node) { environment = 'node'; } // Detect browser environment else if (typeof window !== 'undefined') { environment = 'browser'; } const context = { environment, capabilities: [], }; return { environment, recommendedTransport: exports.transportFactory.detectTransport(context), availableTransports: exports.transportFactory.getSupportedTransports(), }; } /** * Create transport for current environment with optimal configuration */ static createOptimalTransport(config) { const detection = this.detectEnvironment(); if (!detection.recommendedTransport) { console.warn('⚠️ No suitable transport detected for current environment'); return null; } try { const transport = exports.transportFactory.createTransport(detection.recommendedTransport, config); console.log(`🎯 Created optimal transport: ${detection.recommendedTransport} for ${detection.environment} environment`); return transport; } catch (error) { console.error('❌ Failed to create optimal transport:', error); return null; } } } exports.TransportAutoDetection = TransportAutoDetection;