Skip to main content
Glama
sascodiego

MCP Vibe Coding Knowledge Graph

by sascodiego
RefactoredMCPServer.js18.7 kB
/** * CONTEXT: Refactored MCP Server with modular architecture * REASON: Replace God class with loosely coupled, focused components * CHANGE: Implement Service Locator, Command, and Strategy patterns * PREVENTION: Eliminates nested conditionals, reduces complexity, improves maintainability */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { ServiceLocator } from './ServiceLocator.js'; import { ToolRegistry } from './ToolRegistry.js'; import { ToolExecutor } from './ToolExecutor.js'; import { HealthMonitor } from './HealthMonitor.js'; import { logger } from '../utils/logger.js'; import { config, initializeConfigAsync } from '../utils/config.js'; export class RefactoredMCPServer { constructor(options = {}) { this.options = options; this.config = this.loadConfiguration(options); this.serviceLocator = null; this.toolRegistry = null; this.toolExecutor = null; this.healthMonitor = null; this.server = null; this.initialized = false; } /** * Load configuration using early return pattern */ loadConfiguration(options) { if (options.configInstance) { return options.configInstance; } return config.load(options.config); } /** * Create server with async configuration loading */ static async createAsync(options = {}) { try { const configInstance = await initializeConfigAsync(options.config); const serverOptions = { ...options, configInstance }; const server = new RefactoredMCPServer(serverOptions); logger.info('Server created with async configuration loading', { configPath: options.config || 'default' }); return server; } catch (error) { logger.error('Failed to create server with async config:', error); throw error; } } /** * Initialize server components using dependency injection */ async initialize() { if (this.initialized) { logger.warn('Server already initialized'); return; } try { // Initialize service locator with default services this.serviceLocator = ServiceLocator.createWithDefaults(this.config); // Initialize all services await this.serviceLocator.initializeServices(); // Get core services this.toolRegistry = this.serviceLocator.get('toolRegistry'); this.healthMonitor = this.serviceLocator.get('healthMonitor'); // Initialize tool registry this.toolRegistry.initialize(); // Create tool executor with middleware this.createToolExecutor(); // Create MCP server instance this.createMCPServer(); // Setup MCP request handlers this.setupRequestHandlers(); // Setup error handling this.setupErrorHandling(); // Initialize health monitoring with dependencies this.initializeHealthMonitoring(); this.initialized = true; logger.info('Server components initialized successfully'); } catch (error) { logger.error('Failed to initialize server:', error); throw error; } } /** * Create tool executor with middleware pipeline */ createToolExecutor() { this.toolExecutor = new ToolExecutor(this.serviceLocator); // Add middleware in order of execution this.addExecutionMiddleware(); // Register handlers with tool registry this.registerToolHandlers(); } /** * Add execution middleware using strategy pattern */ addExecutionMiddleware() { // Logging middleware (first to execute, last to complete) this.toolExecutor.addMiddleware( ToolExecutor.createLoggingMiddleware() ); // Metrics middleware this.toolExecutor.addMiddleware( ToolExecutor.createMetricsMiddleware(this.healthMonitor) ); // Validation middleware (if available) const validationSystem = this.serviceLocator.has('validationSystem') ? this.serviceLocator.get('validationSystem') : null; if (validationSystem) { this.toolExecutor.addMiddleware( ToolExecutor.createValidationMiddleware(validationSystem) ); } } /** * Register tool handlers with registry */ registerToolHandlers() { const handlers = { initialization: this.serviceLocator.get('initializationHandler'), context: this.serviceLocator.get('contextHandler'), codeGeneration: this.serviceLocator.get('codeGenerationHandler'), validation: this.serviceLocator.get('validationHandler'), knowledgeGraph: this.serviceLocator.get('knowledgeGraphHandler'), arduino: this.serviceLocator.get('arduinoHandler'), server: this // Special case for server methods }; this.toolRegistry.registerHandlers(handlers); } /** * Create MCP server instance */ createMCPServer() { this.server = new Server( { name: this.config.mcp.serverName, version: this.config.mcp.serverVersion, }, { capabilities: { tools: {}, resources: {}, prompts: {} }, } ); } /** * Setup MCP request handlers using early return pattern */ setupRequestHandlers() { // List tools handler this.server.setRequestHandler(ListToolsRequestSchema, () => { return { tools: this.toolRegistry.getToolDefinitions() }; }); // Call tool handler with simplified logic this.server.setRequestHandler(CallToolRequestSchema, async (request) => { return await this.handleToolCall(request); }); } /** * Handle tool call with clean architecture */ async handleToolCall(request) { const { name: toolName, arguments: args } = request.params; try { // Create execution context const context = { server: this, request, toolName, timestamp: Date.now() }; // Execute command using command pattern const result = await this.toolExecutor.executeCommand(toolName, args, context); return result; } catch (error) { logger.error(`Tool execution failed: ${toolName}`, { error: error.message, toolName, args: this.sanitizeArgsForLogging(args) }); return this.createErrorResponse(toolName, error); } } /** * Create error response with consistent format */ createErrorResponse(toolName, error) { return { content: [ { type: 'text', text: `Error executing ${toolName}: ${error.message}` } ] }; } /** * Initialize health monitoring with proper dependencies */ initializeHealthMonitoring() { const dependencies = { kuzu: this.serviceLocator.has('database') ? this.serviceLocator.get('database') : null, validationSystem: this.serviceLocator.has('validationSystem') ? this.serviceLocator.get('validationSystem') : null, optimizationManager: this.serviceLocator.has('optimizationManager') ? this.serviceLocator.get('optimizationManager') : null }; this.healthMonitor.initialize(dependencies); } /** * Setup error handling with clean separation */ setupErrorHandling() { // Global error handlers process.on('uncaughtException', (error) => { logger.error('Uncaught Exception:', error); this.gracefulShutdown(); }); process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled Rejection at:', promise, 'reason:', reason); }); // MCP server error handling if (this.server) { this.server.onerror = (error) => { logger.error('MCP Server Error:', error); this.healthMonitor.updateMetrics({ errors: 1 }); }; } } /** * Start the server with clean initialization flow */ async start() { const startTime = Date.now(); try { logger.info('Starting Refactored MCP Server', { version: this.config.mcp.serverVersion, environment: process.env.NODE_ENV || 'development' }); // Initialize if not already done if (!this.initialized) { await this.initialize(); } // Connect database await this.connectDatabase(); // Start MCP server transport await this.startTransport(); // Start health monitoring this.healthMonitor.startMonitoring(); const bootTime = Date.now() - startTime; logger.info('Refactored MCP Server started successfully', { bootTime: `${bootTime}ms`, pid: process.pid, components: this.getComponentStatus() }); } catch (error) { logger.error('Failed to start server:', error); throw error; } } /** * Connect to database using service locator */ async connectDatabase() { if (!this.serviceLocator.has('database')) { logger.warn('Database service not available'); return; } const database = this.serviceLocator.get('database'); await database.connect(); logger.info('Database connected successfully', { path: this.config.kuzu.databasePath }); } /** * Start MCP transport */ async startTransport() { const transport = new StdioServerTransport(); await this.server.connect(transport); logger.info('MCP transport connected'); } /** * Get component status for monitoring */ getComponentStatus() { return { serviceLocator: this.serviceLocator ? 'initialized' : 'not initialized', toolRegistry: this.toolRegistry ? 'initialized' : 'not initialized', toolExecutor: this.toolExecutor ? 'initialized' : 'not initialized', healthMonitor: this.healthMonitor ? 'initialized' : 'not initialized', server: this.server ? 'initialized' : 'not initialized' }; } /** * Server-specific methods (called by tool commands) */ async getKGStatistics(args) { if (!this.serviceLocator.has('database')) { throw new Error('Database service not available'); } const database = this.serviceLocator.get('database'); const { includeDetails = false, entityType } = args; try { const basicStats = await this.getBasicKGStats(database); let detailedStats = {}; let entityTypeStats = {}; if (includeDetails) { detailedStats = await this.getDetailedKGStats(database); } if (entityType) { entityTypeStats = await this.getEntityTypeStats(database, entityType); } return { content: [ { type: 'text', text: JSON.stringify({ timestamp: new Date().toISOString(), basicStatistics: basicStats, detailedAnalysis: includeDetails ? detailedStats : null, entityTypeAnalysis: entityType ? entityTypeStats : null, summary: { totalNodes: Object.values(basicStats).reduce((sum, count) => sum + (count || 0), 0), healthStatus: this.assessKGHealth(basicStats), recommendations: this.generateKGRecommendations(basicStats) } }, null, 2) } ] }; } catch (error) { logger.error('Error getting KG statistics:', error); throw error; } } /** * Get basic KG statistics using factory pattern */ async getBasicKGStats(database) { const queries = [ { name: 'codeEntities', query: 'MATCH (e:CodeEntity) RETURN count(e) as count' }, { name: 'patterns', query: 'MATCH (p:Pattern) RETURN count(p) as count' }, { name: 'rules', query: 'MATCH (r:Rule) RETURN count(r) as count' }, { name: 'standards', query: 'MATCH (s:Standard) RETURN count(s) as count' }, { name: 'decisions', query: 'MATCH (d:Decision) RETURN count(d) as count' } ]; const results = await Promise.all( queries.map(async ({ name, query }) => { try { const result = await database.query(query); return [name, result[0]?.count || 0]; } catch (error) { logger.error(`Failed to get ${name} count:`, error); return [name, 0]; } }) ); return Object.fromEntries(results); } /** * Get detailed KG statistics */ async getDetailedKGStats(database) { // Implementation would go here - keeping it simple for now return { entityBreakdown: [], patternStats: [], topFiles: [], ruleBreakdown: [] }; } /** * Get entity type statistics */ async getEntityTypeStats(database, entityType) { // Implementation would go here - keeping it simple for now return { total: 0, avgComplexity: 0, maxComplexity: 0, sampleFiles: [] }; } /** * Assess KG health using strategy pattern */ assessKGHealth(stats) { const healthStrategies = { empty: (stats) => stats.codeEntities === 0, minimal: (stats) => stats.codeEntities < 10, basic: (stats) => stats.patterns === 0, disconnected: (stats) => stats.codeEntities > 0 && Object.keys(stats.relationships || {}).length === 0, healthy: () => true }; for (const [status, check] of Object.entries(healthStrategies)) { if (check(stats)) { return { status, message: this.getHealthMessage(status) }; } } return { status: 'unknown', message: 'Unable to determine health status' }; } /** * Get health message for status */ getHealthMessage(status) { const messages = { empty: 'Knowledge Graph is empty. Run initialization first.', minimal: 'Knowledge Graph has minimal data. Consider analyzing more code.', basic: 'No patterns detected yet. Analysis may need more complex code.', disconnected: 'Entities exist but no relationships found. Run deeper analysis.', healthy: 'Knowledge Graph is well-populated and ready for use.' }; return messages[status] || 'Status message not available'; } /** * Generate KG recommendations */ generateKGRecommendations(stats) { const recommendations = []; const recommendationStrategies = [ { condition: (stats) => stats.codeEntities === 0, recommendation: { type: 'initialization', message: 'Initialize the Knowledge Graph with your codebase', action: 'Run: mcp-vibe-coding init /path/to/codebase' } }, { condition: (stats) => stats.patterns === 0 && stats.codeEntities > 0, recommendation: { type: 'patterns', message: 'No design patterns detected', action: 'Use define_domain_ontology to establish architectural patterns' } } ]; for (const strategy of recommendationStrategies) { if (strategy.condition(stats)) { recommendations.push(strategy.recommendation); } } return recommendations; } /** * Get optimization report */ async getOptimizationReport() { if (!this.serviceLocator.has('optimizationManager')) { return { content: [ { type: 'text', text: JSON.stringify({ error: 'Optimization system not available', status: 'disabled' }, null, 2) } ] }; } try { const optimizationManager = this.serviceLocator.get('optimizationManager'); const report = optimizationManager.getOptimizationReport(); return { content: [ { type: 'text', text: JSON.stringify(report, null, 2) } ] }; } catch (error) { logger.error('Failed to get optimization report:', error); return this.createErrorResponse('get_optimization_report', error); } } /** * Force optimization */ async forceOptimization() { if (!this.serviceLocator.has('optimizationManager')) { return { content: [ { type: 'text', text: JSON.stringify({ error: 'Optimization system not available', status: 'disabled' }, null, 2) } ] }; } try { const startTime = Date.now(); const optimizationManager = this.serviceLocator.get('optimizationManager'); await optimizationManager.forceOptimization(); const duration = Date.now() - startTime; const report = optimizationManager.getOptimizationReport(); return { content: [ { type: 'text', text: JSON.stringify({ success: true, message: 'Optimization completed successfully', duration: `${duration}ms`, report: report }, null, 2) } ] }; } catch (error) { logger.error('Failed to force optimization:', error); return this.createErrorResponse('force_optimization', error); } } /** * Get server health */ async getServerHealth() { try { const healthStatus = await this.healthMonitor.getComprehensiveHealth(); return { content: [ { type: 'text', text: JSON.stringify(healthStatus, null, 2) } ] }; } catch (error) { logger.error('Failed to get server health:', error); return this.createErrorResponse('get_server_health', error); } } /** * Sanitize arguments for logging */ sanitizeArgsForLogging(args) { return ToolExecutor.sanitizeArgsForLogging(args); } /** * Graceful shutdown with proper cleanup */ async gracefulShutdown() { logger.info('Initiating graceful shutdown...'); try { // Stop health monitoring if (this.healthMonitor) { this.healthMonitor.stopMonitoring(); } // Close MCP server if (this.server) { await this.server.close?.(); } // Cleanup all services if (this.serviceLocator) { await this.serviceLocator.cleanup(); } logger.info('Graceful shutdown completed'); process.exit(0); } catch (error) { logger.error('Error during graceful shutdown:', error); process.exit(1); } } /** * Stop the server */ async stop() { await this.gracefulShutdown(); } }

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