Skip to main content
Glama
sascodiego

MCP Vibe Coding Knowledge Graph

by sascodiego
ToolExecutor.js15.1 kB
/** * CONTEXT: Command pattern implementation for tool execution * REASON: Eliminate large switch statements and nested conditionals in tool execution * CHANGE: Create command objects for each tool with encapsulated execution logic * PREVENTION: Removes complex nested if/else chains and switch statements */ import { logger } from '../utils/logger.js'; /** * Base command class for tool execution */ class ToolCommand { constructor(toolName, serviceLocator) { this.toolName = toolName; this.serviceLocator = serviceLocator; } /** * Execute the command - to be implemented by subclasses */ async execute(args, context = {}) { throw new Error(`Execute method not implemented for tool: ${this.toolName}`); } /** * Validate arguments - to be overridden by subclasses if needed */ validateArgs(args) { return { isValid: true, errors: [] }; } /** * Get required dependencies for this command */ getDependencies() { return []; } } /** * Knowledge Graph Commands */ class DefineDomainOntologyCommand extends ToolCommand { getDependencies() { return ['knowledgeGraphHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('knowledgeGraphHandler'); return await handler.defineDomainOntology(args); } } class UpdateKGFromCodeCommand extends ToolCommand { getDependencies() { return ['knowledgeGraphHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('knowledgeGraphHandler'); return await handler.updateFromCode(args); } } /** * Context Commands */ class QueryContextForTaskCommand extends ToolCommand { getDependencies() { return ['contextHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('contextHandler'); return await handler.queryContextForTask(args); } } class ExtractContextFromCodeCommand extends ToolCommand { getDependencies() { return ['contextHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('contextHandler'); return await handler.extractFromCode(args); } } /** * Code Generation Commands */ class GenerateCodeWithContextCommand extends ToolCommand { getDependencies() { return ['codeGenerationHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('codeGenerationHandler'); return await handler.generateWithContext(args); } } class SuggestRefactoringCommand extends ToolCommand { getDependencies() { return ['codeGenerationHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('codeGenerationHandler'); return await handler.suggestRefactoring(args); } } /** * Validation Commands */ class ValidateAgainstKGCommand extends ToolCommand { getDependencies() { return ['validationHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('validationHandler'); return await handler.validateAgainstKG(args); } } class DetectTechnicalDebtCommand extends ToolCommand { getDependencies() { return ['validationHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('validationHandler'); return await handler.detectTechnicalDebt(args); } } /** * Initialization Commands */ class AnalyzeCodebaseCommand extends ToolCommand { getDependencies() { return ['initializationHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('initializationHandler'); return await handler.analyzeCodebase(args); } } /** * Arduino Commands */ class AnalyzeArduinoSketchCommand extends ToolCommand { getDependencies() { return ['arduinoHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('arduinoHandler'); return await handler.analyzeArduinoSketch(args); } } class ValidateHardwareConfigCommand extends ToolCommand { getDependencies() { return ['arduinoHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('arduinoHandler'); return await handler.validateHardwareConfiguration(args); } } class OptimizeForArduinoCommand extends ToolCommand { getDependencies() { return ['arduinoHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('arduinoHandler'); return await handler.optimizeForArduino(args); } } class GenerateInterruptSafeCodeCommand extends ToolCommand { getDependencies() { return ['arduinoHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('arduinoHandler'); return await handler.generateInterruptSafeCode(args); } } class AnalyzeTimingConstraintsCommand extends ToolCommand { getDependencies() { return ['arduinoHandler']; } async execute(args, context) { const handler = this.serviceLocator.get('arduinoHandler'); return await handler.generateTimingAnalysis(args); } } /** * System Commands */ class GetKGStatisticsCommand extends ToolCommand { getDependencies() { return ['database']; } async execute(args, context) { // This command needs special handling since it's implemented on the server if (context.server && typeof context.server.getKGStatistics === 'function') { return await context.server.getKGStatistics(args); } throw new Error('Server context not available for KG statistics'); } } class GetOptimizationReportCommand extends ToolCommand { getDependencies() { return ['optimizationManager']; } async execute(args, context) { if (context.server && typeof context.server.getOptimizationReport === 'function') { return await context.server.getOptimizationReport(args); } throw new Error('Server context not available for optimization report'); } } class ForceOptimizationCommand extends ToolCommand { getDependencies() { return ['optimizationManager']; } async execute(args, context) { if (context.server && typeof context.server.forceOptimization === 'function') { return await context.server.forceOptimization(args); } throw new Error('Server context not available for force optimization'); } } class GetServerHealthCommand extends ToolCommand { getDependencies() { return ['healthMonitor']; } async execute(args, context) { if (context.server && typeof context.server.getServerHealth === 'function') { return await context.server.getServerHealth(args); } throw new Error('Server context not available for health check'); } } /** * Tool Executor manages command execution using Command pattern */ export class ToolExecutor { constructor(serviceLocator) { this.serviceLocator = serviceLocator; this.commands = new Map(); this.middleware = []; this.setupCommands(); } /** * Setup all available commands using factory pattern */ setupCommands() { const commandFactories = { 'define_domain_ontology': () => new DefineDomainOntologyCommand('define_domain_ontology', this.serviceLocator), 'query_context_for_task': () => new QueryContextForTaskCommand('query_context_for_task', this.serviceLocator), 'generate_code_with_context': () => new GenerateCodeWithContextCommand('generate_code_with_context', this.serviceLocator), 'validate_against_kg': () => new ValidateAgainstKGCommand('validate_against_kg', this.serviceLocator), 'extract_context_from_code': () => new ExtractContextFromCodeCommand('extract_context_from_code', this.serviceLocator), 'detect_technical_debt': () => new DetectTechnicalDebtCommand('detect_technical_debt', this.serviceLocator), 'suggest_refactoring': () => new SuggestRefactoringCommand('suggest_refactoring', this.serviceLocator), 'update_kg_from_code': () => new UpdateKGFromCodeCommand('update_kg_from_code', this.serviceLocator), 'analyze_codebase': () => new AnalyzeCodebaseCommand('analyze_codebase', this.serviceLocator), 'get_kg_statistics': () => new GetKGStatisticsCommand('get_kg_statistics', this.serviceLocator), 'analyze_arduino_sketch': () => new AnalyzeArduinoSketchCommand('analyze_arduino_sketch', this.serviceLocator), 'validate_hardware_config': () => new ValidateHardwareConfigCommand('validate_hardware_config', this.serviceLocator), 'optimize_for_arduino': () => new OptimizeForArduinoCommand('optimize_for_arduino', this.serviceLocator), 'generate_interrupt_safe_code': () => new GenerateInterruptSafeCodeCommand('generate_interrupt_safe_code', this.serviceLocator), 'analyze_timing_constraints': () => new AnalyzeTimingConstraintsCommand('analyze_timing_constraints', this.serviceLocator), 'get_optimization_report': () => new GetOptimizationReportCommand('get_optimization_report', this.serviceLocator), 'force_optimization': () => new ForceOptimizationCommand('force_optimization', this.serviceLocator), 'get_server_health': () => new GetServerHealthCommand('get_server_health', this.serviceLocator) }; // Create and register commands for (const [toolName, factory] of Object.entries(commandFactories)) { this.commands.set(toolName, factory()); } logger.info('Tool executor initialized', { commandCount: this.commands.size }); } /** * Add middleware for command execution */ addMiddleware(middleware) { this.middleware.push(middleware); } /** * Execute a tool command using the command pattern */ async executeCommand(toolName, args, context = {}) { const command = this.getCommand(toolName); if (!command) { throw new Error(`Unknown tool: ${toolName}`); } // Validate dependencies using early return const missingDependencies = this.validateDependencies(command); if (missingDependencies.length > 0) { throw new Error(`Missing dependencies for ${toolName}: ${missingDependencies.join(', ')}`); } // Execute middleware chain const executionContext = { toolName, args, context, command }; return await this.executeWithMiddleware(executionContext); } /** * Get command instance */ getCommand(toolName) { return this.commands.get(toolName); } /** * Validate command dependencies using guard clauses */ validateDependencies(command) { const missingDependencies = []; const requiredDependencies = command.getDependencies(); for (const dependency of requiredDependencies) { if (!this.serviceLocator.has(dependency)) { missingDependencies.push(dependency); } } return missingDependencies; } /** * Execute command with middleware chain */ async executeWithMiddleware(executionContext) { let index = 0; const next = async () => { // If we've reached the end of middleware, execute the actual command if (index >= this.middleware.length) { return await executionContext.command.execute( executionContext.args, executionContext.context ); } const middleware = this.middleware[index++]; return await middleware(executionContext, next); }; return await next(); } /** * Get all available commands */ getAvailableCommands() { return Array.from(this.commands.keys()).sort(); } /** * Check if a command is available */ hasCommand(toolName) { return this.commands.has(toolName); } /** * Get command information */ getCommandInfo(toolName) { const command = this.commands.get(toolName); if (!command) { return null; } return { toolName, dependencies: command.getDependencies(), className: command.constructor.name }; } /** * Get all commands information */ getAllCommandsInfo() { const commandsInfo = []; for (const toolName of this.getAvailableCommands()) { commandsInfo.push(this.getCommandInfo(toolName)); } return commandsInfo; } /** * Create validation middleware */ static createValidationMiddleware(validationSystem) { return async (executionContext, next) => { const { toolName, args } = executionContext; // Skip validation if system not available if (!validationSystem) { return await next(); } // Validate arguments const validation = await validationSystem.validateToolArgs(toolName, args); if (!validation.isValid) { throw new Error(`Validation failed for ${toolName}: ${validation.errors.join(', ')}`); } return await next(); }; } /** * Create logging middleware */ static createLoggingMiddleware() { return async (executionContext, next) => { const { toolName, args } = executionContext; const startTime = Date.now(); logger.info(`Executing command: ${toolName}`, { args: ToolExecutor.sanitizeArgsForLogging(args) }); try { const result = await next(); const duration = Date.now() - startTime; logger.info(`Command completed: ${toolName}`, { duration: `${duration}ms`, success: true }); return result; } catch (error) { const duration = Date.now() - startTime; logger.error(`Command failed: ${toolName}`, { duration: `${duration}ms`, error: error.message }); throw error; } }; } /** * Create metrics middleware */ static createMetricsMiddleware(healthMonitor) { return async (executionContext, next) => { const startTime = Date.now(); try { const result = await next(); const responseTime = Date.now() - startTime; if (healthMonitor) { healthMonitor.updateMetrics({ toolCalls: 1, responseTime: responseTime }); } return result; } catch (error) { const responseTime = Date.now() - startTime; if (healthMonitor) { healthMonitor.updateMetrics({ toolCalls: 1, errors: 1, responseTime: responseTime }); } throw error; } }; } /** * Sanitize arguments for logging */ static sanitizeArgsForLogging(args) { if (!args || typeof args !== 'object') { return args; } const sanitized = { ...args }; // Truncate long strings Object.keys(sanitized).forEach(key => { if (typeof sanitized[key] === 'string' && sanitized[key].length > 200) { sanitized[key] = sanitized[key].substring(0, 200) + '... [truncated]'; } // Remove sensitive data const sensitiveKeys = ['password', 'token', 'secret', 'key']; if (sensitiveKeys.some(sk => key.toLowerCase().includes(sk))) { sanitized[key] = '[REDACTED]'; } }); return sanitized; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sascodiego/KGsMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server