UNPKG

defect-inspection-tools-mcp-server

Version:

Defect inspection tools server handling defect detection, analysis, and reporting with AI/ML capabilities for quality control

262 lines 11.1 kB
import { ValidationMiddleware } from './validation-middleware.js'; import { SanitizationMiddleware } from './sanitization-middleware.js'; import { ErrorHandler } from './error-handler.js'; import { logger } from '../utils/logger.js'; export class MiddlewareManager { constructor() { } static getInstance() { if (!MiddlewareManager.instance) { MiddlewareManager.instance = new MiddlewareManager(); } return MiddlewareManager.instance; } // Main middleware execution pipeline async processToolCall(toolName, arguments_, userId) { const requestId = ErrorHandler.generateRequestId(); const startTime = Date.now(); try { // Create error context for the entire request const errorContext = ErrorHandler.createErrorContext(toolName, arguments_, userId, requestId); logger.info(`Processing tool call: ${toolName}`, { toolName, requestId, userId, argumentKeys: Object.keys(arguments_) }); // Step 1: Input validation const validationResult = await this.validateInput(toolName, arguments_, errorContext); if (!validationResult.success) { return validationResult; } // Step 2: Sanitization const sanitizedArgs = await this.sanitizeInput(validationResult.sanitizedArgs, errorContext); // Step 3: Final validation of sanitized arguments const finalValidation = await this.validateSanitizedInput(toolName, sanitizedArgs, errorContext); if (!finalValidation.success) { return finalValidation; } const processingTime = Date.now() - startTime; logger.info(`Middleware processing completed for ${toolName}`, { toolName, requestId, processingTime, userId }); return { success: true, sanitizedArgs: finalValidation.sanitizedArgs, requestId }; } catch (error) { logger.error('Middleware processing failed', { toolName, requestId, error: SanitizationMiddleware.sanitizeForLogging(error), userId }); const errorContext = ErrorHandler.createErrorContext(toolName, arguments_, userId, requestId); const standardError = ErrorHandler.handleError(error, errorContext); return { success: false, error: standardError, requestId }; } } // Process tool response through middleware async processToolResponse(toolName, response, requestId) { try { logger.debug(`Processing tool response for ${toolName}`, { toolName, requestId, responseType: typeof response }); // Sanitize the response const sanitizedResponse = SanitizationMiddleware.sanitizeToolResponse(response); logger.debug(`Tool response processed successfully for ${toolName}`, { toolName, requestId }); return sanitizedResponse; } catch (error) { logger.error('Tool response processing failed', { toolName, requestId, error: SanitizationMiddleware.sanitizeForLogging(error) }); const errorContext = ErrorHandler.createErrorContext(toolName, {}, undefined, requestId); const standardError = ErrorHandler.handleError(error, errorContext); return ErrorHandler.formatErrorForToolResponse(standardError); } } // Execute tool with full middleware protection async executeToolWithMiddleware(toolName, arguments_, toolFunction, userId) { const middlewareResult = await this.processToolCall(toolName, arguments_, userId); if (!middlewareResult.success) { throw new Error(`Middleware validation failed: ${middlewareResult.error?.message}`); } const errorContext = ErrorHandler.createErrorContext(toolName, arguments_, userId, middlewareResult.requestId); try { // Execute the tool function with retry and timeout const result = await ErrorHandler.executeWithRetry(() => ErrorHandler.executeWithTimeout(() => toolFunction(middlewareResult.sanitizedArgs), 30000, // 30 second timeout errorContext), errorContext); // Process the response through middleware const processedResult = await this.processToolResponse(toolName, result, middlewareResult.requestId); return processedResult; } catch (error) { logger.error(`Tool execution failed for ${toolName}`, { toolName, requestId: middlewareResult.requestId, error: SanitizationMiddleware.sanitizeForLogging(error), userId }); const standardError = ErrorHandler.handleError(error, errorContext); throw new Error(standardError.message); } } // Private helper methods async validateInput(toolName, arguments_, errorContext) { try { const validationResult = ValidationMiddleware.validateInput(toolName, arguments_); if (!validationResult.isValid) { logger.warn(`Validation failed for ${toolName}`, { toolName, requestId: errorContext.requestId, errors: validationResult.errors }); const standardError = ErrorHandler.handleError(new Error(`Validation failed: ${validationResult.errors.map(e => e.message).join(', ')}`), errorContext); return { success: false, error: standardError, requestId: errorContext.requestId }; } return { success: true, sanitizedArgs: validationResult.sanitizedArgs, requestId: errorContext.requestId }; } catch (error) { logger.error('Input validation error', { toolName, requestId: errorContext.requestId, error: SanitizationMiddleware.sanitizeForLogging(error) }); const standardError = ErrorHandler.handleError(error, errorContext); return { success: false, error: standardError, requestId: errorContext.requestId }; } } async sanitizeInput(arguments_, errorContext) { try { const sanitizedArgs = SanitizationMiddleware.sanitizeToolArguments(arguments_); logger.debug('Input sanitization completed', { toolName: errorContext.toolName, requestId: errorContext.requestId, originalKeys: Object.keys(arguments_), sanitizedKeys: Object.keys(sanitizedArgs) }); return sanitizedArgs; } catch (error) { logger.error('Input sanitization failed', { toolName: errorContext.toolName, requestId: errorContext.requestId, error: SanitizationMiddleware.sanitizeForLogging(error) }); throw error; } } async validateSanitizedInput(toolName, sanitizedArgs, errorContext) { try { // Perform a final validation on the sanitized arguments const finalValidation = ValidationMiddleware.validateInput(toolName, sanitizedArgs); if (!finalValidation.isValid) { logger.warn(`Final validation failed for ${toolName}`, { toolName, requestId: errorContext.requestId, errors: finalValidation.errors }); const standardError = ErrorHandler.handleError(new Error(`Final validation failed: ${finalValidation.errors.map(e => e.message).join(', ')}`), errorContext); return { success: false, error: standardError, requestId: errorContext.requestId }; } return { success: true, sanitizedArgs: finalValidation.sanitizedArgs, requestId: errorContext.requestId }; } catch (error) { logger.error('Final validation error', { toolName, requestId: errorContext.requestId, error: SanitizationMiddleware.sanitizeForLogging(error) }); const standardError = ErrorHandler.handleError(error, errorContext); return { success: false, error: standardError, requestId: errorContext.requestId }; } } // Health check for middleware components async healthCheck() { const components = { validation: true, sanitization: true, errorHandler: true }; try { // Test validation const testValidation = ValidationMiddleware.validateInput('test', {}); components.validation = testValidation !== undefined; } catch (error) { components.validation = false; logger.error('Validation component health check failed', { error }); } try { // Test sanitization const testSanitization = SanitizationMiddleware.sanitizeToolArguments({}); components.sanitization = testSanitization !== undefined; } catch (error) { components.sanitization = false; logger.error('Sanitization component health check failed', { error }); } try { // Test error handler const testError = ErrorHandler.generateRequestId(); components.errorHandler = testError !== undefined; } catch (error) { components.errorHandler = false; logger.error('Error handler component health check failed', { error }); } const healthyCount = Object.values(components).filter(Boolean).length; const status = healthyCount === 3 ? 'healthy' : healthyCount === 2 ? 'degraded' : 'unhealthy'; return { status, components, timestamp: new Date() }; } } // Export middleware components for direct use if needed export { ValidationMiddleware, SanitizationMiddleware, ErrorHandler }; // Export default instance export const middlewareManager = MiddlewareManager.getInstance(); //# sourceMappingURL=index.js.map