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
JavaScript
/**
* 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