UNPKG

@spaik/mcp-server-roi

Version:

MCP server for AI ROI prediction and tracking with Monte Carlo simulations

308 lines 13.3 kB
import { z } from 'zod'; import { SonarBenchmarkService } from './sonar-benchmark-service.js'; import { createLogger } from '../utils/logger.js'; import { structuredLogger, PerformanceTracker } from '../utils/structured-logger.js'; // Validation result schema (same as original) export const ValidationResultSchema = z.object({ isValid: z.boolean(), adjustedInput: z.any(), validationIssues: z.array(z.object({ field: z.string(), originalValue: z.number(), adjustedValue: z.number(), reason: z.string(), severity: z.enum(['warning', 'error', 'info']), industryBenchmark: z.object({ average: z.number(), p25: z.number(), p75: z.number(), source: z.string() }).optional() })), marketInsights: z.array(z.object({ metric: z.string(), dutchMarketValue: z.number(), globalValue: z.number(), trend: z.string(), source: z.string() })), recommendations: z.array(z.string()), citations: z.array(z.object({ url: z.string(), title: z.string() })) }); // Validation thresholds const VALIDATION_THRESHOLDS = { MAX_SAVINGS_MULTIPLIER: 3.0, ADJUSTED_SAVINGS_MULTIPLIER: 2.0, MIN_IMPLEMENTATION_RATIO: 0.5, MAX_ROI_PERCENTAGE: 300, REALISTIC_ROI_RANGE: { min: 15, max: 150 }, MIN_PAYBACK_MONTHS: 6, MAX_PAYBACK_MONTHS: 48, }; /** * Enhanced Dutch Benchmark Validator with parallel API calls */ export class DutchBenchmarkValidatorParallel extends SonarBenchmarkService { dutchLogger = createLogger({ service: 'DutchBenchmarkValidator' }); constructor(apiKey) { super({ apiKey, model: 'sonar-pro' }); } /** * Validate project inputs against Dutch market benchmarks with parallel API calls */ async validateProjectInputs(params, correlationId) { const logger = structuredLogger.createApi('dutch-validator', 'validateProjectInputs', correlationId); const tracker = new PerformanceTracker('dutch-validation.total', logger.correlationId); logger.info('Starting Dutch market validation', { industry: params.industry, useCaseCount: params.useCases.length }); try { // Execute all API calls in parallel tracker.checkpoint('parallel-api-calls-start'); const [benchmarks, marketInsights, industrySpecificData, regulatoryRequirements, competitorAnalysis] = await Promise.all([ // 1. Fetch general benchmarks this.fetchDutchBenchmarks(params.industry, params.useCases) .catch(err => { logger.warn('Failed to fetch benchmarks, using defaults', { error: err.message }); return this.getDefaultBenchmarks(params.industry); }), // 2. Fetch market insights this.fetchDutchMarketInsights(params.industry) .catch(err => { logger.warn('Failed to fetch market insights', { error: err.message }); return []; }), // 3. Fetch industry-specific data this.fetchIndustrySpecificData(params.industry) .catch(err => { logger.warn('Failed to fetch industry data', { error: err.message }); return null; }), // 4. Fetch regulatory requirements (Dutch specific) this.fetchDutchRegulatoryRequirements(params.industry) .catch(err => { logger.warn('Failed to fetch regulatory data', { error: err.message }); return null; }), // 5. Fetch competitor analysis this.fetchCompetitorAnalysis(params.industry, params.useCases) .catch(err => { logger.warn('Failed to fetch competitor analysis', { error: err.message }); return null; }) ]); tracker.checkpoint('parallel-api-calls-complete'); // Merge all data sources const enrichedBenchmarks = { ...benchmarks, industrySpecific: industrySpecificData, regulatory: regulatoryRequirements, competitors: competitorAnalysis }; // Validate components in parallel where possible tracker.checkpoint('parallel-validation-start'); const [useCaseValidations, timelineValidation, costValidation] = await Promise.all([ // Validate all use cases in parallel Promise.all(params.useCases.map((useCase, index) => this.validateUseCaseSavings(useCase, enrichedBenchmarks, params.industry).then(validation => ({ index, validation })))), // Validate timeline this.validateTimeline(params.timelineMonths, params.industry, enrichedBenchmarks), // Validate costs this.validateImplementationCosts(params.implementationCosts, params.industry, enrichedBenchmarks) ]); tracker.checkpoint('parallel-validation-complete'); // Process results const validationIssues = []; const adjustedInput = JSON.parse(JSON.stringify(params)); // Deep clone // Process use case validations for (const { index, validation } of useCaseValidations) { if (validation.needsAdjustment) { validationIssues.push({ field: `use_cases[${index}].monthly_cost_reduction`, originalValue: validation.originalSavings, adjustedValue: validation.adjustedSavings, reason: validation.reason, severity: validation.severity, industryBenchmark: validation.benchmark }); // Adjust the automation percentage const useCase = params.useCases[index]; const currentCost = useCase.current_state.volume_per_month * useCase.current_state.cost_per_transaction; const targetReduction = validation.adjustedSavings / currentCost; adjustedInput.useCases[index].future_state.automation_percentage = Math.min(targetReduction / useCase.future_state.time_reduction_percentage, 1); } } // Process timeline validation if (timelineValidation.needsAdjustment) { validationIssues.push({ field: 'timelineMonths', originalValue: params.timelineMonths, adjustedValue: timelineValidation.adjustedTimeline, reason: timelineValidation.reason, severity: 'warning', industryBenchmark: timelineValidation.benchmark }); adjustedInput.timelineMonths = timelineValidation.adjustedTimeline; } // Process cost validation if (costValidation.issues.length > 0) { validationIssues.push(...costValidation.issues); adjustedInput.implementationCosts = costValidation.adjustedCosts; } // Generate recommendations with all enriched data const recommendations = this.generateEnhancedRecommendations(validationIssues, marketInsights, params.industry, enrichedBenchmarks); tracker.end(true); logger.info('Dutch validation completed', { issueCount: validationIssues.length, errorCount: validationIssues.filter(i => i.severity === 'error').length, adjustmentsMade: validationIssues.filter(i => i.severity === 'warning').length }); return { isValid: validationIssues.filter(i => i.severity === 'error').length === 0, adjustedInput, validationIssues, marketInsights, recommendations, citations: benchmarks.citations || [] }; } catch (error) { tracker.error(error); logger.error('Dutch validation failed', error); throw error; } } /** * Fetch Dutch regulatory requirements */ async fetchDutchRegulatoryRequirements(industry) { const prompt = ` What are the key Dutch regulatory requirements and compliance considerations for AI implementation in the ${industry} industry? Include: - GDPR and Dutch privacy laws - Industry-specific regulations - Labor law considerations - Tax implications Provide as structured JSON. `; try { const response = await this.askSonar(prompt); return this.parseJsonResponse(response.content); } catch (error) { this.dutchLogger.warn('Failed to fetch regulatory requirements', { error }); return null; } } /** * Fetch competitor analysis */ async fetchCompetitorAnalysis(industry, useCases) { const useCaseNames = useCases.map(uc => uc.name).join(', '); const prompt = ` Analyze Dutch companies in the ${industry} industry that have implemented AI for use cases like: ${useCaseNames}. Include: - Success rates and ROI achieved - Implementation timelines - Key challenges faced - Technology stack used Provide as structured JSON with specific examples. `; try { const response = await this.askSonar(prompt); return this.parseJsonResponse(response.content); } catch (error) { this.dutchLogger.warn('Failed to fetch competitor analysis', { error }); return null; } } /** * Fetch industry-specific data */ async fetchIndustrySpecificData(industry) { const prompt = ` Provide detailed Dutch market data for the ${industry} industry including: - Market size and growth rate - AI adoption rate - Average IT budgets as % of revenue - Key technology trends - Major players and their AI initiatives Format as structured JSON with sources. `; try { const response = await this.askSonar(prompt); return this.parseJsonResponse(response.content); } catch (error) { this.dutchLogger.warn('Failed to fetch industry data', { error }); return null; } } /** * Generate enhanced recommendations with all data sources */ generateEnhancedRecommendations(validationIssues, marketInsights, industry, enrichedBenchmarks) { const recommendations = []; // Base recommendations from validation issues const baseRecommendations = this.generateRecommendations(validationIssues, marketInsights, industry); recommendations.push(...baseRecommendations); // Add regulatory recommendations if available if (enrichedBenchmarks.regulatory) { if (enrichedBenchmarks.regulatory.gdprConsiderations) { recommendations.push(`Ensure GDPR compliance: ${enrichedBenchmarks.regulatory.gdprConsiderations}`); } if (enrichedBenchmarks.regulatory.industrySpecific) { recommendations.push(`Industry regulation: ${enrichedBenchmarks.regulatory.industrySpecific}`); } } // Add competitor insights if available if (enrichedBenchmarks.competitors?.successfulImplementations) { recommendations.push(`Consider proven approaches: ${enrichedBenchmarks.competitors.successfulImplementations[0]?.approach || 'Study local success cases'}`); } // Add industry-specific recommendations if (enrichedBenchmarks.industrySpecific?.trends) { recommendations.push(`Align with industry trends: ${enrichedBenchmarks.industrySpecific.trends[0] || 'Monitor market evolution'}`); } return recommendations; } /** * Default benchmarks for fallback */ getDefaultBenchmarks(industry) { return { savings: [{ category: 'general', average: 25, p25: 15, p75: 35, source: 'Industry defaults' }], timeline: { average: 12, min: 6, max: 24, source: 'Industry defaults' }, costs: { averagePercentOfRevenue: 2.5, breakdown: { software: 0.3, development: 0.4, training: 0.1, infrastructure: 0.2 }, source: 'Industry defaults' }, citations: [] }; } } //# sourceMappingURL=dutch-benchmark-validator-parallel.js.map