UNPKG

@sethdouglasford/claude-flow

Version:

Claude Code Flow - Advanced AI-powered development workflows with SPARC methodology

807 lines 31.5 kB
/** * MCP Integration with Claude-Flow Orchestration System * Provides seamless integration between MCP servers and the broader orchestration components */ import { EventEmitter } from "node:events"; import { SystemEvents } from "../utils/types.js"; import { MCPError } from "../utils/errors.js"; import { MCPServer } from "./server.js"; import { MCPLifecycleManager, LifecycleState } from "./lifecycle-manager.js"; import { MCPPerformanceMonitor } from "./performance-monitor.js"; import { MCPProtocolManager } from "./protocol-manager.js"; /** * MCP Orchestration Integration Manager * Manages the integration between MCP servers and orchestration components */ export class MCPOrchestrationIntegration extends EventEmitter { mcpConfig; orchestrationConfig; components; logger; server; lifecycleManager; performanceMonitor; protocolManager; integrationStatus = new Map(); healthCheckTimer; reconnectTimers = new Map(); defaultConfig = { enabledIntegrations: { orchestrator: true, swarm: true, agents: true, resources: true, memory: true, monitoring: true, terminals: true, }, autoStart: true, healthCheckInterval: 30000, // 30 seconds reconnectAttempts: 3, reconnectDelay: 5000, // 5 seconds enableMetrics: true, enableAlerts: true, }; constructor(mcpConfig, orchestrationConfig, components, logger) { super(); this.mcpConfig = mcpConfig; this.orchestrationConfig = orchestrationConfig; this.components = components; this.logger = logger; this.orchestrationConfig = { ...this.defaultConfig, ...orchestrationConfig }; this.initializeIntegration(); } /** * Start the MCP orchestration integration */ async start() { this.logger.info("Starting MCP orchestration integration"); try { // Initialize protocol manager this.protocolManager = new MCPProtocolManager(this.logger); // Initialize performance monitor if (this.orchestrationConfig.enableMetrics) { this.performanceMonitor = new MCPPerformanceMonitor(this.logger); this.setupPerformanceMonitoring(); } // Create MCP server this.server = new MCPServer(this.mcpConfig, this.components.eventBus || new EventEmitter(), this.logger, this.components.orchestrator, this.components.swarmCoordinator, this.components.agentManager, this.components.resourceManager, this.components.messageBus, this.components.monitor); // Initialize lifecycle manager this.lifecycleManager = new MCPLifecycleManager(this.mcpConfig, this.logger, () => { if (!this.server) { throw new MCPError("MCP server not initialized"); } return this.server; }); // Setup lifecycle event handlers this.setupLifecycleHandlers(); // Register orchestration tools this.registerOrchestrationTools(); // Start the server if (this.orchestrationConfig.autoStart) { await this.lifecycleManager.start(); } // Start health monitoring this.startHealthMonitoring(); // Setup component integrations await this.setupComponentIntegrations(); this.logger.info("MCP orchestration integration started successfully"); this.emit("integrationStarted"); } catch (error) { this.logger.error("Failed to start MCP orchestration integration", error); throw error; } } /** * Stop the MCP orchestration integration */ async stop() { this.logger.info("Stopping MCP orchestration integration"); try { // Stop health monitoring this.stopHealthMonitoring(); // Stop lifecycle manager if (this.lifecycleManager) { await this.lifecycleManager.stop(); } // Stop performance monitor if (this.performanceMonitor) { this.performanceMonitor.stop(); } // Clear reconnect timers for (const timer of this.reconnectTimers.values()) { clearTimeout(timer); } this.reconnectTimers.clear(); this.logger.info("MCP orchestration integration stopped"); this.emit("integrationStopped"); } catch (error) { this.logger.error("Error stopping MCP orchestration integration", error); throw error; } } /** * Destroy the integration and clean up all resources */ destroy() { this.logger.info("Destroying MCP orchestration integration"); // Stop health monitoring this.stopHealthMonitoring(); // Destroy lifecycle manager if (this.lifecycleManager) { this.lifecycleManager.destroy(); } // Stop performance monitor if (this.performanceMonitor) { this.performanceMonitor.stop(); } // Clear reconnect timers for (const timer of this.reconnectTimers.values()) { clearTimeout(timer); } this.reconnectTimers.clear(); // Clear integration status this.integrationStatus.clear(); // Remove all event listeners this.removeAllListeners(); this.logger.info("MCP orchestration integration destroyed"); } /** * Get integration status for all components */ getIntegrationStatus() { return Array.from(this.integrationStatus.values()); } /** * Get status for a specific component */ getComponentStatus(component) { return this.integrationStatus.get(component); } /** * Get MCP server instance */ getServer() { return this.server; } /** * Get lifecycle manager */ getLifecycleManager() { return this.lifecycleManager; } /** * Get performance monitor */ getPerformanceMonitor() { return this.performanceMonitor; } /** * Get protocol manager */ getProtocolManager() { return this.protocolManager; } /** * Force reconnection to a component */ async reconnectComponent(component) { const status = this.integrationStatus.get(component); if (!status?.enabled) { throw new MCPError(`Component ${component} is not enabled`); } this.logger.info("Reconnecting to component", { component }); try { await this.connectComponent(component); this.logger.info("Successfully reconnected to component", { component }); } catch (error) { this.logger.error("Failed to reconnect to component", { component, error }); throw error; } } /** * Enable/disable component integration */ async setComponentEnabled(component, enabled) { const status = this.integrationStatus.get(component); if (!status) { throw new MCPError(`Unknown component: ${component}`); } status.enabled = enabled; if (enabled) { await this.connectComponent(component); } else { await this.disconnectComponent(component); } this.logger.info("Component integration updated", { component, enabled }); this.emit("componentToggled", { component, enabled }); } initializeIntegration() { const components = [ "orchestrator", "swarm", "agents", "resources", "memory", "monitoring", "terminals", ]; for (const component of components) { this.integrationStatus.set(component, { component, enabled: this.orchestrationConfig.enabledIntegrations[component], connected: false, healthy: false, lastCheck: new Date(), }); } } setupLifecycleHandlers() { if (!this.lifecycleManager) return; this.lifecycleManager.on("stateChange", (event) => { this.logger.info("MCP server state changed", { from: event.previousState, to: event.state, error: event.error?.message, }); // Emit to orchestration event bus if (this.components.eventBus) { this.components.eventBus.emit(SystemEvents.SYSTEM_HEALTHCHECK, { status: event.state === LifecycleState.RUNNING ? "healthy" : "unhealthy", component: "mcp-server", timestamp: event.timestamp, }); } this.emit("lifecycleStateChanged", event); }); } setupPerformanceMonitoring() { if (!this.performanceMonitor) return; this.performanceMonitor.on("metricsCollected", (metrics) => { // Forward metrics to orchestration monitor if (this.components.monitor && typeof this.components.monitor.recordMetrics === "function") { this.components.monitor.recordMetrics("mcp", metrics); } this.emit("metricsCollected", metrics); }); this.performanceMonitor.on("alertTriggered", (alert) => { this.logger.warn("MCP performance alert triggered", { alertId: alert.id, ruleName: alert.ruleName, severity: alert.severity, message: alert.message, }); // Forward to orchestration alert system if (this.orchestrationConfig.enableAlerts && this.components.monitor) { if (typeof this.components.monitor.sendAlert === "function") { this.components.monitor.sendAlert({ source: "mcp", severity: alert.severity, message: alert.message, metadata: alert, }); } } this.emit("performanceAlert", alert); }); this.performanceMonitor.on("optimizationSuggestion", (suggestion) => { this.logger.info("MCP optimization suggestion", { type: suggestion.type, priority: suggestion.priority, title: suggestion.title, }); this.emit("optimizationSuggestion", suggestion); }); } registerOrchestrationTools() { if (!this.server) return; // Register orchestrator tools if (this.orchestrationConfig.enabledIntegrations.orchestrator && this.components.orchestrator) { this.registerOrchestratorTools(); } // Register swarm tools if (this.orchestrationConfig.enabledIntegrations.swarm && this.components.swarmCoordinator) { this.registerSwarmTools(); } // Register agent tools if (this.orchestrationConfig.enabledIntegrations.agents && this.components.agentManager) { this.registerAgentTools(); } // Register resource tools if (this.orchestrationConfig.enabledIntegrations.resources && this.components.resourceManager) { this.registerResourceTools(); } // Register memory tools if (this.orchestrationConfig.enabledIntegrations.memory && this.components.memoryManager) { this.registerMemoryTools(); } // Register monitoring tools if (this.orchestrationConfig.enabledIntegrations.monitoring && this.components.monitor) { this.registerMonitoringTools(); } // Register terminal tools if (this.orchestrationConfig.enabledIntegrations.terminals && this.components.terminalManager) { this.registerTerminalTools(); } } registerOrchestratorTools() { const tools = [ { name: "orchestrator/status", description: "Get orchestrator status and metrics", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.orchestrator?.getStatus === "function") { return this.components.orchestrator.getStatus(); } throw new MCPError("Orchestrator status not available"); }, }, { name: "orchestrator/tasks", description: "List all tasks in the orchestrator", inputSchema: { type: "object", properties: { status: { type: "string", enum: ["pending", "running", "completed", "failed"] }, limit: { type: "number", minimum: 1, maximum: 100 }, }, }, handler: async (input) => { const params = input; if (typeof this.components.orchestrator?.listTasks === "function") { return await this.components.orchestrator.listTasks(params); } throw new MCPError("Orchestrator task listing not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } registerSwarmTools() { const tools = [ { name: "swarm/status", description: "Get swarm coordinator status", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.swarmCoordinator?.getStatus === "function") { return this.components.swarmCoordinator.getStatus(); } throw new MCPError("Swarm coordinator status not available"); }, }, { name: "swarm/agents", description: "List active swarm agents", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.swarmCoordinator?.listAgents === "function") { return await this.components.swarmCoordinator.listAgents(); } throw new MCPError("Swarm agent listing not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } registerAgentTools() { const tools = [ { name: "agents/list", description: "List all managed agents", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.agentManager?.listAgents === "function") { return await this.components.agentManager.listAgents(); } throw new MCPError("Agent listing not available"); }, }, { name: "agents/spawn", description: "Spawn a new agent", inputSchema: { type: "object", properties: { profile: { type: "object" }, config: { type: "object" }, }, required: ["profile"], }, handler: async (input) => { const params = input; if (typeof this.components.agentManager?.spawnAgent === "function") { return await this.components.agentManager.spawnAgent(params.profile, params.config); } throw new MCPError("Agent spawning not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } registerResourceTools() { const tools = [ { name: "resources/list", description: "List available resources", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.resourceManager?.listResources === "function") { return await this.components.resourceManager.listResources(); } throw new MCPError("Resource listing not available"); }, }, { name: "resources/status", description: "Get resource manager status", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.resourceManager?.getStatus === "function") { return this.components.resourceManager.getStatus(); } throw new MCPError("Resource manager status not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } registerMemoryTools() { const tools = [ { name: "memory/query", description: "Query memory bank", inputSchema: { type: "object", properties: { query: { type: "string" }, namespace: { type: "string" }, limit: { type: "number" }, }, required: ["query"], }, handler: async (input) => { const params = input; if (typeof this.components.memoryManager?.query === "function") { // Convert to expected type const queryParams = { ...params, type: params.type, startTime: params.startTime ? new Date(params.startTime) : undefined, endTime: params.endTime ? new Date(params.endTime) : undefined, }; return await this.components.memoryManager.query(queryParams); } throw new MCPError("Memory query not available"); }, }, { name: "memory/store", description: "Store data in memory bank", inputSchema: { type: "object", properties: { data: { type: "object" }, namespace: { type: "string" }, tags: { type: "array", items: { type: "string" } }, }, required: ["data"], }, handler: async (input) => { const params = input; if (typeof this.components.memoryManager?.store === "function") { // Convert to expected type with required data field const storeParams = { data: { key: params.key, value: params.value, content: params.content, context: params.context, type: params.type, agentId: params.agentId, sessionId: params.sessionId, parentId: params.parentId, }, namespace: params.namespace, tags: params.tags, }; return await this.components.memoryManager.store(storeParams); } throw new MCPError("Memory storage not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } registerMonitoringTools() { const tools = [ { name: "monitoring/metrics", description: "Get system monitoring metrics", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.monitor?.getMetrics === "function") { return await this.components.monitor.getMetrics(); } throw new MCPError("Monitoring metrics not available"); }, }, { name: "monitoring/alerts", description: "List active alerts", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.monitor?.getAlerts === "function") { return await this.components.monitor.getAlerts(); } throw new MCPError("Alert listing not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } registerTerminalTools() { const tools = [ { name: "terminals/list", description: "List active terminal sessions", inputSchema: { type: "object", properties: {} }, handler: async () => { if (typeof this.components.terminalManager?.listSessions === "function") { return await this.components.terminalManager.listSessions(); } throw new MCPError("Terminal session listing not available"); }, }, { name: "terminals/execute", description: "Execute command in terminal", inputSchema: { type: "object", properties: { command: { type: "string" }, sessionId: { type: "string" }, }, required: ["command"], }, handler: async (input) => { const params = input; if (typeof this.components.terminalManager?.execute === "function") { return await this.components.terminalManager.execute(params.command, params.sessionId); } throw new MCPError("Terminal execution not available"); }, }, ]; for (const tool of tools) { if (!this.server) { throw new MCPError("MCP server not initialized"); } this.server.registerTool(tool); } } async setupComponentIntegrations() { const promises = []; for (const [component, status] of this.integrationStatus.entries()) { if (status.enabled) { promises.push(this.connectComponent(component)); } } await Promise.allSettled(promises); } async connectComponent(component) { const status = this.integrationStatus.get(component); if (!status) return; try { // Component-specific connection logic switch (component) { case "orchestrator": await this.connectOrchestrator(); break; case "swarm": await this.connectSwarmCoordinator(); break; case "agents": await this.connectAgentManager(); break; case "resources": await this.connectResourceManager(); break; case "memory": await this.connectMemoryManager(); break; case "monitoring": await this.connectMonitor(); break; case "terminals": await this.connectTerminalManager(); break; } status.connected = true; status.healthy = true; status.lastCheck = new Date(); status.error = undefined; this.logger.info("Component connected", { component }); this.emit("componentConnected", { component }); } catch (error) { status.connected = false; status.healthy = false; status.error = error instanceof Error ? error.message : "Unknown error"; this.logger.error("Failed to connect component", { component, error }); this.scheduleReconnect(component); } } async disconnectComponent(component) { const status = this.integrationStatus.get(component); if (!status) return; status.connected = false; status.healthy = false; status.lastCheck = new Date(); // Clear any reconnect timers const timer = this.reconnectTimers.get(component); if (timer) { clearTimeout(timer); this.reconnectTimers.delete(component); } this.logger.info("Component disconnected", { component }); this.emit("componentDisconnected", { component }); } scheduleReconnect(component) { const timer = this.reconnectTimers.get(component); if (timer) return; // Already scheduled const reconnectTimer = setTimeout(async () => { this.reconnectTimers.delete(component); try { await this.connectComponent(component); } catch (error) { // Will be handled by connectComponent } }, this.orchestrationConfig.reconnectDelay); this.reconnectTimers.set(component, reconnectTimer); } startHealthMonitoring() { this.healthCheckTimer = setInterval(async () => { await this.performHealthChecks(); }, this.orchestrationConfig.healthCheckInterval); } stopHealthMonitoring() { if (this.healthCheckTimer) { clearInterval(this.healthCheckTimer); this.healthCheckTimer = undefined; } } async performHealthChecks() { for (const [component, status] of this.integrationStatus.entries()) { if (!status.enabled || !status.connected) continue; try { const healthy = await this.checkComponentHealth(component); status.healthy = healthy; status.lastCheck = new Date(); status.error = undefined; } catch (error) { status.healthy = false; status.error = error instanceof Error ? error.message : "Health check failed"; this.logger.warn("Component health check failed", { component, error }); } } } async checkComponentHealth(component) { try { const instance = this.getComponentInstance(component); if (!instance) return false; // Check if the component has a healthCheck method if ("healthCheck" in instance && typeof instance.healthCheck === "function") { const result = await instance.healthCheck(); return result?.healthy !== false; } // Default to true if no health check method return true; } catch (error) { this.logger.warn(`Health check failed for ${component}`, error); return false; } } getComponentInstance(component) { switch (component) { case "orchestrator": return this.components.orchestrator || null; case "swarm": return this.components.swarmCoordinator || null; case "agents": return this.components.agentManager || null; case "resources": return this.components.resourceManager || null; case "memory": return this.components.memoryManager || null; case "monitoring": return this.components.monitor || null; case "terminals": return this.components.terminalManager || null; default: return null; } } // Component-specific connection methods async connectOrchestrator() { if (!this.components.orchestrator) { throw new MCPError("Orchestrator component not available"); } // Add orchestrator-specific connection logic here } async connectSwarmCoordinator() { if (!this.components.swarmCoordinator) { throw new MCPError("Swarm coordinator component not available"); } // Add swarm coordinator-specific connection logic here } async connectAgentManager() { if (!this.components.agentManager) { throw new MCPError("Agent manager component not available"); } // Add agent manager-specific connection logic here } async connectResourceManager() { if (!this.components.resourceManager) { throw new MCPError("Resource manager component not available"); } // Add resource manager-specific connection logic here } async connectMemoryManager() { if (!this.components.memoryManager) { throw new MCPError("Memory manager component not available"); } // Add memory manager-specific connection logic here } async connectMonitor() { if (!this.components.monitor) { throw new MCPError("Monitor component not available"); } // Add monitor-specific connection logic here } async connectTerminalManager() { if (!this.components.terminalManager) { throw new MCPError("Terminal manager component not available"); } // Add terminal manager-specific connection logic here } } //# sourceMappingURL=orchestration-integration.js.map