@spaik/mcp-server-roi
Version:
MCP server for AI ROI prediction and tracking with Monte Carlo simulations
339 lines • 15.4 kB
JavaScript
import { z } from 'zod';
import { createLogger } from '../utils/logger.js';
/**
* Response Transformer Service
*
* Transforms raw tool outputs into semantic-rich, multi-layered responses
* optimized for AI agent consumption.
*/
// Schema for transformed responses
export const TransformedResponseSchema = z.object({
executive_summary: z.object({
headline: z.string(),
confidence: z.enum(['low', 'medium', 'high']),
key_insight: z.string(),
primary_metric: z.string().optional()
}),
insights: z.object({
primary: z.array(z.string()).describe('Top 3-5 key insights'),
risks: z.array(z.string()).describe('Key risk factors'),
opportunities: z.array(z.string()).describe('Growth opportunities'),
patterns: z.array(z.string()).optional().describe('Detected patterns across data')
}),
recommendations: z.object({
next_action: z.string(),
timeline: z.string(),
success_criteria: z.string(),
prerequisites: z.array(z.string()).optional(),
alternatives: z.array(z.object({
action: z.string(),
tradeoff: z.string()
})).optional()
}),
narrative: z.object({
context: z.string().describe('Business context and background'),
analysis: z.string().describe('Detailed analysis narrative'),
conclusion: z.string().describe('Summary and next steps')
}).optional(),
detailed_analysis: z.any().describe('Original detailed data'),
metadata: z.object({
confidence_score: z.number().min(0).max(1),
data_quality: z.enum(['low', 'medium', 'high']),
assumptions_impact: z.enum(['low', 'medium', 'high']),
generated_at: z.string().datetime(),
response_version: z.string().default('2.0'),
tool_name: z.string(),
processing_time_ms: z.number().optional()
})
});
export class ResponseTransformer {
logger = createLogger({ component: 'ResponseTransformer' });
/**
* Transform predict_roi tool response
*/
async transformPredictROI(response) {
const startTime = Date.now();
try {
const { summary, financial_metrics, use_cases, metadata } = response;
// Generate executive summary
const executiveSummary = this.generateExecutiveSummary(summary);
// Extract insights
const insights = this.extractROIInsights(summary, financial_metrics, use_cases);
// Generate recommendations
const recommendations = this.generateROIRecommendations(summary, use_cases, insights.primary);
// Create narrative (optional for now)
const narrative = this.generateROINarrative(summary, insights);
// Calculate metadata
const responseMetadata = this.calculateMetadata('predict_roi', metadata, startTime);
return {
executive_summary: executiveSummary,
insights,
recommendations,
narrative,
detailed_analysis: response,
metadata: responseMetadata
};
}
catch (error) {
this.logger.error('Failed to transform predict_roi response', error);
throw error;
}
}
/**
* Transform compare_projects tool response
*/
async transformCompareProjects(response) {
const startTime = Date.now();
try {
const { projects, rankings, insights, recommendations } = response;
// Generate executive summary
const executiveSummary = this.generateComparativeExecutiveSummary(projects, rankings, insights);
// Enhance existing insights
const enhancedInsights = this.enhanceComparativeInsights(insights, projects);
// Structure recommendations
const structuredRecommendations = this.structureComparativeRecommendations(recommendations, insights);
// Generate narrative
const narrative = this.generateComparativeNarrative(projects, rankings);
// Calculate metadata
const responseMetadata = this.calculateMetadata('compare_projects', response.metadata, startTime);
return {
executive_summary: executiveSummary,
insights: enhancedInsights,
recommendations: structuredRecommendations,
narrative,
detailed_analysis: response,
metadata: responseMetadata
};
}
catch (error) {
this.logger.error('Failed to transform compare_projects response', error);
throw error;
}
}
// Private helper methods
generateExecutiveSummary(summary) {
const roi = summary.expected_roi;
const payback = summary.payback_period_months;
let confidence = 'medium';
let headline = '';
if (roi > 200 && payback < 12) {
confidence = 'high';
headline = `Exceptional ROI opportunity with ${roi.toFixed(0)}% return in ${payback} months`;
}
else if (roi > 100 && payback < 18) {
confidence = 'high';
headline = `Strong ROI potential of ${roi.toFixed(0)}% with ${payback}-month payback`;
}
else if (roi > 50) {
confidence = 'medium';
headline = `Solid investment case with ${roi.toFixed(0)}% ROI over 5 years`;
}
else {
confidence = 'low';
headline = `Moderate returns expected with ${roi.toFixed(0)}% ROI`;
}
const key_insight = this.generateKeyInsight(summary, payback);
const primary_metric = `$${(summary.net_present_value / 1000).toFixed(0)}K NPV`;
return { headline, confidence, key_insight, primary_metric };
}
generateKeyInsight(summary, payback) {
if (payback <= 6) {
return 'Rapid payback enables quick reinvestment in additional AI initiatives';
}
else if (payback <= 12) {
return 'Sub-year payback provides strong business case for immediate implementation';
}
else if (payback <= 24) {
return 'Investment timeline aligns well with typical enterprise planning cycles';
}
else {
return 'Long-term value creation requires sustained commitment and phased approach';
}
}
extractROIInsights(summary, financial_metrics, use_cases) {
const insights = {
primary: [],
risks: [],
opportunities: [],
patterns: []
};
// Analyze use case distribution
const categories = use_cases.reduce((acc, uc) => {
acc[uc.category] = (acc[uc.category] || 0) + uc.monthly_benefit;
return acc;
}, {});
const topCategory = Object.entries(categories)
.sort(([, a], [, b]) => b - a)[0];
if (topCategory) {
insights.primary.push(`${topCategory[0]} use cases drive ${((topCategory[1] / summary.total_investment) * 100).toFixed(0)}% of total value`);
}
// ROI insights
if (summary.expected_roi > 150) {
insights.primary.push('ROI exceeds typical enterprise hurdle rates by 3-5x');
}
// Payback insights
if (summary.payback_period_months < 12) {
insights.primary.push('Quick payback reduces financial risk and enables rapid scaling');
}
// Risk factors
if (summary.payback_period_months > 24) {
insights.risks.push('Extended payback period increases execution risk');
}
if (use_cases.length > 5) {
insights.risks.push('Multiple concurrent use cases may strain implementation resources');
}
// Opportunities
insights.opportunities.push('Consider phased rollout to capture quick wins first');
if (summary.expected_roi > 100) {
insights.opportunities.push('High ROI justifies accelerated timeline with additional resources');
}
return insights;
}
generateROIRecommendations(summary, use_cases, primaryInsights) {
// Sort use cases by benefit
const sortedUseCases = [...use_cases].sort((a, b) => b.monthly_benefit - a.monthly_benefit);
const topUseCase = sortedUseCases[0];
let next_action = '';
let timeline = '';
let success_criteria = '';
if (summary.payback_period_months <= 12) {
next_action = `Launch pilot program for ${topUseCase.name}`;
timeline = 'Begin within 30 days';
success_criteria = `Achieve ${(topUseCase.monthly_benefit * 0.7).toFixed(0)} monthly benefit within 90 days`;
}
else {
next_action = 'Conduct detailed feasibility study for top 3 use cases';
timeline = 'Complete within 60 days';
success_criteria = 'Validate assumptions and refine implementation plan';
}
return {
next_action,
timeline,
success_criteria,
prerequisites: [
'Secure executive sponsorship',
'Allocate dedicated project team',
'Establish success metrics baseline'
]
};
}
generateROINarrative(summary, insights) {
const context = `This AI investment analysis evaluates a total investment of $${(summary.total_investment / 1000).toFixed(0)}K ` +
`with projected returns of ${summary.expected_roi.toFixed(0)}% over 5 years.`;
const analysis = `The financial analysis reveals a ${summary.payback_period_months}-month payback period ` +
`with a net present value of $${(summary.net_present_value / 1000).toFixed(0)}K. ` +
insights.primary.join('. ') + '.';
const conclusion = `Based on the analysis, this investment presents a ${summary.expected_roi > 100 ? 'compelling' : 'solid'} opportunity with ${summary.payback_period_months <= 18 ? 'rapid' : 'reasonable'} time to value. ` +
`Key success factors include focused execution and phased implementation.`;
return { context, analysis, conclusion };
}
generateComparativeExecutiveSummary(projects, rankings, insights) {
const topProject = projects.find(p => p.id === rankings.by_roi[0].project_id);
const confidence = this.assessComparativeConfidence(projects);
const headline = insights.best_overall
? `${insights.best_overall} emerges as the optimal choice across multiple dimensions`
: `Portfolio analysis reveals diverse strengths across ${projects.length} projects`;
const key_insight = this.extractTopComparativeInsight(projects, rankings);
return {
headline,
confidence,
key_insight,
primary_metric: topProject
? `Top ROI: ${topProject.financial_summary.expected_roi.toFixed(0)}%`
: undefined
};
}
enhanceComparativeInsights(existingInsights, projects) {
const insights = {
primary: [],
risks: [],
opportunities: [],
patterns: []
};
// Add existing insights
if (existingInsights.best_overall) {
insights.primary.push(`${existingInsights.best_overall} offers the best overall value`);
}
if (existingInsights.quickest_payback) {
insights.primary.push(`${existingInsights.quickest_payback} provides fastest time to value`);
}
// Analyze patterns
const avgROI = projects.reduce((sum, p) => sum + p.financial_summary.expected_roi, 0) / projects.length;
insights.patterns.push(`Portfolio average ROI: ${avgROI.toFixed(0)}%`);
// Risk analysis
if (existingInsights.highest_risk) {
insights.risks.push(`${existingInsights.highest_risk} requires careful risk management`);
}
// Opportunities from synergies
if (existingInsights.synergies && existingInsights.synergies.length > 0) {
insights.opportunities.push('Synergy opportunities identified between projects');
}
return insights;
}
structureComparativeRecommendations(recommendations, insights) {
const next_action = recommendations[0] || 'Prioritize projects based on strategic alignment';
return {
next_action,
timeline: 'Review within 2 weeks',
success_criteria: 'Select 1-2 projects for immediate implementation',
alternatives: recommendations.slice(1, 3).map(rec => ({
action: rec,
tradeoff: 'May require different resource allocation'
}))
};
}
generateComparativeNarrative(projects, rankings) {
const context = `This analysis compares ${projects.length} AI investment opportunities ` +
`to identify optimal resource allocation strategies.`;
const analysis = `Projects range from ${Math.min(...projects.map(p => p.financial_summary.total_investment)) / 1000}K to ${Math.max(...projects.map(p => p.financial_summary.total_investment)) / 1000}K in investment with ROIs between ${Math.min(...projects.map(p => p.financial_summary.expected_roi))}% and ${Math.max(...projects.map(p => p.financial_summary.expected_roi))}%.`;
const conclusion = 'Portfolio approach enables risk diversification while maximizing overall returns.';
return { context, analysis, conclusion };
}
calculateMetadata(toolName, originalMetadata, startTime) {
return {
confidence_score: originalMetadata?.confidence_level || 0.85,
data_quality: this.assessDataQuality(originalMetadata),
assumptions_impact: 'medium', // Could be calculated based on variance
generated_at: new Date().toISOString(),
response_version: '2.0',
tool_name: toolName,
processing_time_ms: Date.now() - startTime
};
}
assessDataQuality(metadata) {
if (!metadata)
return 'medium';
if (metadata.calculated_with_benchmarks && metadata.confidence_level > 0.9) {
return 'high';
}
if (metadata.confidence_level < 0.7) {
return 'low';
}
return 'medium';
}
assessComparativeConfidence(projects) {
if (projects.length >= 3 && projects.every(p => p.ml_insights)) {
return 'high';
}
if (projects.length >= 2) {
return 'medium';
}
return 'low';
}
extractTopComparativeInsight(projects, rankings) {
const roiSpread = Math.max(...projects.map(p => p.financial_summary.expected_roi)) -
Math.min(...projects.map(p => p.financial_summary.expected_roi));
if (roiSpread > 100) {
return 'Significant ROI variance suggests careful project selection critical';
}
else if (roiSpread < 30) {
return 'Similar ROI profiles indicate selection should focus on strategic fit';
}
else {
return 'Balanced portfolio approach recommended for risk mitigation';
}
}
}
// Export singleton instance
export const responseTransformer = new ResponseTransformer();
//# sourceMappingURL=response-transformer.js.map