UNPKG

ai-debug-local-mcp

Version:

šŸŽÆ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

399 lines (392 loc) • 13.9 kB
#!/usr/bin/env node /** * AI-Debug V2 Dual-Mode Server - Native MCP Support * * Supports both HTTP and STDIO MCP transports natively, eliminating bridge complexity. * Automatically detects mode based on execution context and command line arguments. * * Usage: * node server-dual-mode.js --stdio # STDIO mode for Claude Code * node server-dual-mode.js --http # HTTP mode (default) * node server-dual-mode.js # Auto-detect mode */ import { HttpMcpTransport } from './transport/http-mcp-transport.js'; import { StdioMcpTransport } from './transport/stdio-mcp-transport.js'; import { V2SessionRegistry } from './session/v2-session-registry.js'; import { AdvancedMemoryManager } from './utils/advanced-memory-manager.js'; import { V2StabilityMonitor } from './stability/v2-stability-monitor.js'; import { StatelessDebugService } from './core/stateless-debug-service.js'; import { UniversalRealHandler } from './handlers/universal-real-handler.js'; class V2DualModeServer { config; transport; sessionRegistry; memoryManager; stabilityMonitor; debugService; toolHandler; isRunning = false; constructor() { this.config = this.parseConfig(); this.setupSignalHandlers(); } /** * Parse configuration from command line and environment */ parseConfig() { const args = process.argv.slice(2); let mode = 'auto'; if (args.includes('--stdio')) { mode = 'stdio'; } else if (args.includes('--http')) { mode = 'http'; } else if (args.includes('--help')) { this.showHelp(); process.exit(0); } // Auto-detect mode if not specified if (mode === 'auto') { mode = this.detectMode(); } return { mode, httpPort: parseInt(process.env.AI_DEBUG_PORT || '8081'), enableStabilityMonitoring: process.env.AI_DEBUG_MONITORING !== 'false', enableSubAgents: process.env.AI_DEBUG_SUB_AGENTS !== 'false' }; } /** * Auto-detect execution mode */ detectMode() { // Check if STDIO flag is explicitly set if (process.argv.includes('--stdio')) { return 'stdio'; } // Check if HTTP flag is explicitly set if (process.argv.includes('--http')) { return 'http'; } // Check environment variable if (process.env.AI_DEBUG_MODE === 'stdio') { return 'stdio'; } // Check if stdin is a TTY (interactive terminal) if (process.stdin.isTTY || !process.stdin.readable) { return 'http'; // Interactive mode or no stdin, use HTTP } // Check if we're being piped to or from if (!process.stdout.isTTY || process.env.MCP_STDIO_MODE === 'true') { return 'stdio'; // Piped or MCP stdio mode } return 'http'; // Default to HTTP } /** * Show help information */ showHelp() { console.log(` šŸš€ AI-Debug V2 Dual-Mode Server - Native MCP Support USAGE: node server-dual-mode.js [OPTIONS] OPTIONS: --stdio Force STDIO MCP mode (for Claude Code integration) --http Force HTTP MCP mode (for browser/API access) --help Show this help message ENVIRONMENT VARIABLES: AI_DEBUG_PORT HTTP port (default: 8081) AI_DEBUG_MONITORING Enable stability monitoring (default: true) AI_DEBUG_SUB_AGENTS Enable sub-agent delegation (default: true) MCP_STDIO_MODE Force STDIO mode (default: auto-detect) EXAMPLES: # STDIO mode for Claude Code MCP integration node server-dual-mode.js --stdio # HTTP mode for web/API access node server-dual-mode.js --http # Auto-detect mode (recommended) node server-dual-mode.js FEATURES: āœ… 288 Real tools (273 individual + 6 infinite scroll + 9 orchestrators) āœ… Native MCP protocol support (no bridges needed) āœ… Advanced stability monitoring with 100% availability āœ… Automatic sub-agent delegation for context optimization āœ… Full-stack debugging (frontend + backend + database) āœ… Claude Code compatible stdio transport `); } /** * Start the server */ async start() { if (this.isRunning) { return; } try { console.error('šŸš€ Starting AI-Debug V2 Dual-Mode Server...'); console.error(`šŸ“‹ Mode: ${this.config.mode.toUpperCase()}`); console.error('šŸ›”ļø Features: Native MCP, Advanced Stability, 70+ Tools (Core + TDD + Framework-specific)'); await this.initializeCore(); await this.initializeTransport(); await this.initializeServices(); this.isRunning = true; console.error('āœ… V2 Dual-Mode Server started successfully'); // Keep process alive in HTTP mode if (this.config.mode === 'http') { this.keepAlive(); } } catch (error) { console.error('āŒ Failed to start V2 server:', error); process.exit(1); } } /** * Initialize core components */ async initializeCore() { // Memory manager (singleton) this.memoryManager = AdvancedMemoryManager.getInstance(); console.error('🧠 V2 Advanced Memory Manager initialized'); // Session registry this.sessionRegistry = new V2SessionRegistry(); console.error('šŸ¢ V2 Session Registry initialized'); // Stability monitoring (if enabled) if (this.config.enableStabilityMonitoring) { this.stabilityMonitor = new V2StabilityMonitor(this.sessionRegistry, this.memoryManager); console.error('šŸ›”ļø V2 Stability Monitor initialized (fixed availability calculation)'); } // Debug service this.debugService = new StatelessDebugService(); console.error('šŸ”§ V2 Stateless Debug Service initialized'); // Tool handler this.toolHandler = new UniversalRealHandler(); await this.toolHandler.initialize(); console.error(`šŸ› ļø Universal Real Handler initialized with ${this.toolHandler.tools.length} clean, AI-optimized tools`); } /** * Initialize transport based on mode */ async initializeTransport() { if (this.config.mode === 'stdio') { this.transport = new StdioMcpTransport(); console.error('šŸ”— STDIO MCP Transport initialized'); } else { this.transport = new HttpMcpTransport(this.config.httpPort); console.error(`🌐 HTTP MCP Transport initialized (port ${this.config.httpPort})`); } // Setup request handling this.transport.on('request', async (request, respond) => { try { const response = await this.handleMCPRequest(request); respond(response); } catch (error) { console.error('āŒ Error handling MCP request:', error); respond({ jsonrpc: '2.0', id: request.id, error: { code: -32603, message: 'Internal error', data: error.message } }); } }); await this.transport.start(); } /** * Initialize additional services */ async initializeServices() { // Start stability monitoring if (this.stabilityMonitor) { // Monitoring starts automatically in constructor console.error('šŸ“Š Real-time health tracking enabled'); } console.error('šŸ”„ Auto-recovery systems online'); console.error('šŸ›”ļø Circuit breakers protecting all critical components'); if (this.config.enableSubAgents) { console.error('šŸ¤– Sub-agent delegation system active'); } } /** * Handle MCP requests */ async handleMCPRequest(request) { const { method, params, id } = request; try { let result; switch (method) { case 'tools/list': result = await this.handleToolsList(); break; case 'tools/call': result = await this.handleToolsCall(params); break; case 'initialize': result = await this.handleInitialize(params); break; case 'ping': result = { status: 'pong', timestamp: Date.now() }; break; default: throw new Error(`Unknown method: ${method}`); } return { jsonrpc: '2.0', id, result }; } catch (error) { console.error(`āŒ Error in ${method}:`, error); return { jsonrpc: '2.0', id, error: { code: -32603, message: 'Internal error', data: error.message } }; } } /** * Handle tools/list request */ async handleToolsList() { if (!this.toolHandler) { throw new Error('Tool handler not initialized'); } // Ensure handler is initialized if (!this.toolHandler.initialized) { console.error('āš ļø Tool handler not yet initialized, initializing now...'); await this.toolHandler.initialize(); } const tools = this.toolHandler.tools; console.error(`šŸ”§ Serving ${tools.length} tools to client:`); console.error(` First tool: ${tools[0]?.name} - ${tools[0]?.description?.substring(0, 50)}...`); console.error(` Last tool: ${tools[tools.length - 1]?.name}`); console.error(` Tools source: ${this.toolHandler.constructor.name}`); console.error(` Hierarchical mode: ${this.toolHandler.hierarchicalConfig?.enabled}`); return { tools }; } /** * Handle tools/call request */ async handleToolsCall(params) { if (!this.toolHandler) { throw new Error('Tool handler not initialized'); } const { name, arguments: toolArgs } = params; console.error(`⚔ Executing tool: ${name}`); // Create persistent context to maintain sessions across tool calls if (!this.toolContext) { this.toolContext = {}; } const result = await this.toolHandler.execute(name, toolArgs, this.toolContext); return { content: [ { type: 'text', text: typeof result === 'string' ? result : JSON.stringify(result, null, 2) } ] }; } /** * Handle initialize request */ async handleInitialize(params) { return { protocolVersion: '2024-11-05', capabilities: { tools: { listChanged: true }, logging: {}, prompts: {} }, serverInfo: { name: 'ai-debug-v2-dual-mode', version: '2.0.1' } }; } /** * Keep HTTP server alive */ keepAlive() { setInterval(() => { // Keep process alive and emit heartbeat for monitoring if (this.stabilityMonitor) { // Monitoring continues automatically } }, 30000); } /** * Setup signal handlers for graceful shutdown */ setupSignalHandlers() { const gracefulShutdown = async (signal) => { console.error(`šŸ›‘ V2 Graceful shutdown initiated (${signal})`); await this.stop(); }; process.on('SIGINT', () => gracefulShutdown('SIGINT')); process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); process.on('uncaughtException', (error) => { console.error('āŒ Uncaught exception:', error); this.stop().then(() => process.exit(1)); }); process.on('unhandledRejection', (reason, promise) => { console.error('āŒ Unhandled rejection at:', promise, 'reason:', reason); this.stop().then(() => process.exit(1)); }); } /** * Stop the server gracefully */ async stop() { if (!this.isRunning) { return; } try { this.isRunning = false; // Stop stability monitoring if (this.stabilityMonitor) { await this.stabilityMonitor.shutdown(); } // Stop transport if (this.transport) { await this.transport.stop(); } // Cleanup session registry if (this.sessionRegistry) { await this.sessionRegistry.performCleanup(); } // Final memory cleanup if (this.memoryManager) { await this.memoryManager.triggerEmergencyCleanup('shutdown'); } console.error('āœ… V2 Dual-Mode Server shutdown complete'); } catch (error) { console.error('āŒ Error during shutdown:', error); } process.exit(0); } } // Start server if run directly if (import.meta.url === `file://${process.argv[1]}`) { const server = new V2DualModeServer(); server.start().catch((error) => { console.error('šŸ’„ Failed to start server:', error); process.exit(1); }); } export { V2DualModeServer }; //# sourceMappingURL=server-dual-mode.original.js.map