UNPKG

il2cpp-dump-analyzer-mcp

Version:

Agentic RAG system for analyzing IL2CPP dump.cs files from Unity games

287 lines 10.8 kB
"use strict"; /** * Transport Factory for IL2CPP MCP Server * Creates and manages different transport types (stdio, HTTP, WebSocket, SSE) */ Object.defineProperty(exports, "__esModule", { value: true }); exports.transportFactory = exports.TransportFactory = void 0; exports.createValidatedTransport = createValidatedTransport; const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const transport_types_1 = require("./transport-types"); const http_transport_1 = require("./http-transport"); /** * Transport factory implementation */ class TransportFactory { constructor() { this.activeTransports = new Map(); } /** * Create a transport instance based on configuration */ async createTransport(config) { const transportId = this.generateTransportId(config); // Check if transport already exists if (this.activeTransports.has(transportId)) { const existing = this.activeTransports.get(transportId); if (existing.transport instanceof http_transport_1.HttpTransport) { return existing.transport.getTransport(); } return existing.transport; } let transport; switch (config.type) { case transport_types_1.TransportType.STDIO: transport = await this.createStdioTransport(config); break; case transport_types_1.TransportType.HTTP: transport = await this.createHttpTransport(config); break; case transport_types_1.TransportType.SSE: transport = await this.createSseTransport(config); break; case transport_types_1.TransportType.WEBSOCKET: throw new Error('WebSocket transport not yet implemented'); default: throw new Error(`Unsupported transport type: ${config.type}`); } // Store the transport this.activeTransports.set(transportId, { transport, config }); // Return the MCP transport interface if (transport instanceof http_transport_1.HttpTransport) { return transport.getTransport(); } return transport; } /** * Create stdio transport */ async createStdioTransport(config) { console.log('📡 Creating stdio transport...'); return new stdio_js_1.StdioServerTransport(); } /** * Create HTTP transport */ async createHttpTransport(config) { console.log(`🌐 Creating HTTP transport on ${config.host}:${config.port}...`); const options = { host: config.host || 'localhost', port: config.port || 3000, enableCors: config.enableCors ?? true, apiKey: config.apiKey, sessionTimeout: config.sessionTimeout || 30 * 60 * 1000, enableLogging: config.enableLogging ?? false, maxRequestSize: config.maxRequestSize || 10 * 1024 * 1024, rateLimitRpm: config.rateLimitRpm || 100, ssl: config.enableSsl ? { enabled: true, certPath: config.sslCertPath, keyPath: config.sslKeyPath } : undefined }; const httpTransport = new http_transport_1.HttpTransport(options); await httpTransport.start(); return httpTransport; } /** * Create SSE transport */ async createSseTransport(config) { console.log(`📡 Creating SSE transport on ${config.host}:${config.port}...`); // SSE transport is implemented as part of the HTTP transport // The StreamableHTTPServerTransport in the MCP SDK handles SSE automatically const options = { host: config.host || 'localhost', port: config.port || 3000, enableCors: config.enableCors ?? true, apiKey: config.apiKey, sessionTimeout: config.sessionTimeout || 30 * 60 * 1000, enableLogging: config.enableLogging ?? false, maxRequestSize: config.maxRequestSize || 10 * 1024 * 1024, rateLimitRpm: config.rateLimitRpm || 100, ssl: config.enableSsl ? { enabled: true, certPath: config.sslCertPath, keyPath: config.sslKeyPath } : undefined }; const httpTransport = new http_transport_1.HttpTransport(options); await httpTransport.start(); console.log('📡 SSE transport ready (via HTTP transport with SSE streaming)'); return httpTransport; } /** * Validate transport configuration */ validateConfig(config) { try { switch (config.type) { case transport_types_1.TransportType.STDIO: // No additional validation needed for stdio return true; case transport_types_1.TransportType.HTTP: case transport_types_1.TransportType.SSE: case transport_types_1.TransportType.WEBSOCKET: // Network transports require host and port if (!config.host || !config.port) { console.error('Network transports require host and port configuration'); return false; } if (config.port < 1 || config.port > 65535) { console.error('Port must be between 1 and 65535'); return false; } // SSL validation if (config.enableSsl) { if (!config.sslCertPath || !config.sslKeyPath) { console.error('SSL certificate and key paths are required when SSL is enabled'); return false; } } return true; default: console.error(`Unsupported transport type: ${config.type}`); return false; } } catch (error) { console.error('Transport configuration validation failed:', error); return false; } } /** * Get supported transport types */ getSupportedTypes() { return [ transport_types_1.TransportType.STDIO, transport_types_1.TransportType.HTTP, transport_types_1.TransportType.SSE // TransportType.WEBSOCKET - Not yet implemented ]; } /** * Get status of all active transports */ getTransportStatuses() { const statuses = []; for (const [transportId, { transport, config }] of this.activeTransports) { const status = { type: config.type, active: true, // Assume active if in the map lastActivity: new Date() }; if (transport instanceof http_transport_1.HttpTransport) { const metrics = transport.getMetrics(); status.connections = metrics.activeConnections; status.address = `${config.enableSsl ? 'https' : 'http'}://${config.host}:${config.port}`; } statuses.push(status); } return statuses; } /** * Get metrics for all active transports */ getTransportMetrics() { const metrics = new Map(); for (const [transportId, { transport, config }] of this.activeTransports) { if (transport instanceof http_transport_1.HttpTransport) { metrics.set(transportId, transport.getMetrics()); } else { // Default metrics for other transport types metrics.set(transportId, { totalRequests: 0, activeConnections: 1, requestsPerMinute: 0, averageResponseTime: 0, errorCount: 0, bytesSent: 0, bytesReceived: 0 }); } } return metrics; } /** * Stop a specific transport */ async stopTransport(transportId) { const transportInfo = this.activeTransports.get(transportId); if (!transportInfo) { throw new Error(`Transport not found: ${transportId}`); } const { transport } = transportInfo; if (transport instanceof http_transport_1.HttpTransport) { await transport.stop(); } else if ('close' in transport) { await transport.close(); } this.activeTransports.delete(transportId); console.log(`🔌 Transport stopped: ${transportId}`); } /** * Stop all active transports */ async stopAllTransports() { const stopPromises = []; for (const transportId of this.activeTransports.keys()) { stopPromises.push(this.stopTransport(transportId)); } await Promise.all(stopPromises); console.log('🔌 All transports stopped'); } /** * Generate a unique transport ID */ generateTransportId(config) { switch (config.type) { case transport_types_1.TransportType.STDIO: return 'stdio'; case transport_types_1.TransportType.HTTP: case transport_types_1.TransportType.SSE: case transport_types_1.TransportType.WEBSOCKET: return `${config.type}-${config.host}-${config.port}`; default: return `${config.type}-${Date.now()}`; } } /** * Get transport by ID */ getTransport(transportId) { const transportInfo = this.activeTransports.get(transportId); return transportInfo ? transportInfo.transport : null; } /** * Check if a transport is active */ isTransportActive(transportId) { return this.activeTransports.has(transportId); } /** * Get transport configuration */ getTransportConfig(transportId) { const transportInfo = this.activeTransports.get(transportId); return transportInfo ? transportInfo.config : null; } } exports.TransportFactory = TransportFactory; /** * Global transport factory instance */ exports.transportFactory = new TransportFactory(); /** * Helper function to create and validate transport */ async function createValidatedTransport(config) { if (!exports.transportFactory.validateConfig(config)) { throw new Error('Invalid transport configuration'); } return await exports.transportFactory.createTransport(config); } //# sourceMappingURL=transport-factory.js.map