UNPKG

tryaii-mcp-server

Version:

TryAII MCP Server - 15+ AI models with comparison, cost tracking, and collective intelligence

230 lines 9.57 kB
import { HttpTransport } from '../transports/HttpTransport.js'; import { McpTransport } from '../transports/McpTransport.js'; import { McpProtocolHandler } from '../mcp/McpProtocolHandler.js'; import { sessionManager } from '../services/sessionManager.js'; import { userApiKeyService } from '../services/userApiKeyService.js'; import { databaseService } from '../services/database.js'; import { httpClient } from '../services/httpClient.js'; import { authenticationService } from '../services/AuthenticationService.js'; import { balanceService } from '../services/BalanceService.js'; import { sessionService } from '../services/SessionService.js'; import { config } from '../utils/config.js'; import { logger } from '../utils/logger.js'; export class MultiTransportServer { transports = new Map(); protocolHandler; initialized = false; constructor() { this.protocolHandler = new McpProtocolHandler(sessionManager, userApiKeyService); } async start() { try { logger.info('Starting multi-transport server...'); // Initialize services first await this.initializeServices(); // Start enabled transports if (config.server.modes.http) { await this.startHttpTransport(); } if (config.server.modes.mcp) { await this.startMcpTransport(); } // Validate at least one transport is enabled if (this.transports.size === 0) { throw new Error('No transports enabled. Enable at least one transport mode (HTTP or MCP).'); } this.initialized = true; logger.info('🚀 Multi-transport server started successfully', { modes: config.server.modes, transports: Array.from(this.transports.keys()), transportCount: this.transports.size }); } catch (error) { logger.error('Failed to start multi-transport server', { error }); throw error; } } async initializeServices() { logger.info('Initializing services...'); // Initialize database connection with dual connections logger.info('Initializing enhanced database connections...'); try { await databaseService.connect(); logger.info('✅ Database connections initialized (main + MCP)'); } catch (error) { logger.error('Database connection failed', { error }); if (process.env.NODE_ENV === 'production') { throw error; } logger.warn('Continuing without database in development/test mode'); logger.info('💡 To fix this: Install MongoDB locally or set MAIN_DB_URI and MCP_DB_URI'); } // Initialize our enhanced services if (databaseService.isHealthy()) { try { logger.info('Initializing enhanced authentication service...'); await authenticationService.initialize(); logger.info('✅ Enhanced authentication service initialized'); logger.info('Initializing balance service...'); await balanceService.initialize(); logger.info('✅ Balance service initialized'); logger.info('Initializing session service...'); await sessionService.initialize(); logger.info('✅ Session service initialized'); logger.info('🎉 All enhanced services initialized successfully'); } catch (error) { logger.error('Failed to initialize enhanced services', { error }); throw error; } } else { logger.warn('Skipping enhanced services initialization (database not available)'); } // Initialize MCP client (skip in test mode if executable doesn't exist) const skipMCP = process.env.NODE_ENV === 'test' && (!config.mcp.executablePath || config.mcp.executablePath === '../mcp_tryaii/build/index.js'); // Initialize HTTP client for the new architecture logger.info('Initializing HTTP client...'); try { await httpClient.start(); logger.info('HTTP client initialized successfully'); // Initialize session manager with HTTP client logger.info('Initializing session manager with HTTP client...'); sessionManager.setHttpClient(httpClient); } catch (error) { logger.error('HTTP client initialization failed', { error }); throw error; } // Start session manager logger.info('Starting session manager...'); sessionManager.start(); logger.info('Session manager started successfully'); } async startHttpTransport() { logger.info('Starting HTTP transport...'); const httpTransport = new HttpTransport(); this.transports.set('http', httpTransport); // Set reference to this server in health routes for monitoring const { setMultiTransportServer } = await import('../routes/health.js'); setMultiTransportServer(this); // HTTP transport handles its own routing await httpTransport.start(); logger.info('HTTP transport started successfully'); } async startMcpTransport() { logger.info('Starting MCP transport...'); const mcpTransport = new McpTransport(); this.transports.set('mcp', mcpTransport); // Handle MCP requests mcpTransport.on('request', async (connectionId, request) => { try { const response = await this.protocolHandler.handleRequest(connectionId, request); // Only send response if it's not null (notifications don't need responses) if (response !== null) { await mcpTransport.sendResponse(connectionId, response); } } catch (error) { logger.error('Error processing MCP request', { connectionId, method: request.method, id: request.id, error }); } }); // Handle MCP connection events mcpTransport.on('connection', (connectionId) => { logger.info('New MCP connection', { connectionId }); }); mcpTransport.on('connectionClosed', (connectionId) => { logger.info('MCP connection closed', { connectionId }); this.protocolHandler.removeConnection(connectionId); }); mcpTransport.on('connectionError', (connectionId, error) => { logger.error('MCP connection error', { connectionId, error }); this.protocolHandler.removeConnection(connectionId); }); await mcpTransport.start(); logger.info('MCP transport started successfully'); } async stop() { if (!this.initialized) { logger.info('Multi-transport server not initialized, nothing to stop'); return; } logger.info('Stopping multi-transport server...'); // Stop all transports for (const [name, transport] of this.transports) { logger.info(`Stopping ${name} transport...`); try { await transport.stop(); logger.info(`${name} transport stopped`); } catch (error) { logger.error(`Error stopping ${name} transport`, { error }); } } this.transports.clear(); // Stop services try { // Stop session manager sessionManager.stop(); logger.info('Session manager stopped'); // Stop HTTP client await httpClient.stop(); logger.info('HTTP client stopped'); // Disconnect from database await databaseService.disconnect(); logger.info('Database disconnected'); } catch (error) { logger.error('Error stopping services', { error }); } this.initialized = false; logger.info('Multi-transport server stopped'); } // Health check methods isHealthy() { if (!this.initialized) { return false; } // Check if all enabled transports are healthy for (const transport of this.transports.values()) { if (!transport.isHealthy()) { return false; } } return true; } getStatus() { const transportStatus = {}; for (const [name, transport] of this.transports) { transportStatus[name] = { healthy: transport.isHealthy(), ...(name === 'mcp' && { connections: transport.getConnectionCount(), activeConnections: transport.getConnections() }) }; } return { initialized: this.initialized, healthy: this.isHealthy(), modes: config.server.modes, transports: transportStatus, services: { sessionManager: sessionManager.isRunning(), mcpProtocolHandler: { connections: this.protocolHandler.getConnectionCount() } } }; } } //# sourceMappingURL=MultiTransportServer.js.map