#!/usr/bin/env node
const axios = require('axios');
// FINAL HONEST COMPARISON
// Production: final-mcp-server.cjs on port 3000 (GitHub version with Bearer auth)
// Current: mcp-server-with-oauth-rc5.cjs on port 3001 (OAuth version)
const QUESTIONS = [
{ id: 'Q1', query: 'show me the list of MSP customers' },
{ id: 'Q2', query: 'what is my total cost?' },
{ id: 'Q3', query: 'what is my total AWS cost?' },
{ id: 'Q4', query: 'what is my total GCP cost?' },
{ id: 'Q5', query: 'what is my total Azure cost?' },
{ id: 'Q6', query: 'show me the total cost per month' },
{ id: 'Q7', query: 'show me the total AWS amortized cost per month for the last 8 months' },
{ id: 'Q8', query: 'show me the total cost for ALL Azure accounts' },
{ id: 'Q9', query: 'show me all available accounts' },
{ id: 'Q10', query: 'what do you recommend for saving AWS costs?' },
{ id: 'Q11', query: 'what are the potential savings per category?' },
{ id: 'Q12', query: 'what is the cost impact of the anomalies in the last 10 days for AWS?' },
{ id: 'Q13', query: 'what is the last 30 days (per day) amortized cost for Cloudwatch service?' }
];
class FinalHonestComparison {
constructor() {
this.productionToken = null;
this.currentSessionId = null;
this.results = [];
}
async authenticateProduction() {
try {
console.log('🔐 Authenticating Production (GitHub/Bearer)...');
const response = await axios.post('http://localhost:3000/auth', {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
});
if (response.data?.bearerToken) {
this.productionToken = response.data.bearerToken;
console.log('✅ Production authenticated');
return true;
}
} catch (error) {
console.error('❌ Production auth failed:', error.message);
}
return false;
}
async authenticateCurrent() {
try {
console.log('🔐 Authenticating Current (OAuth)...');
const sessionResponse = await axios.post('http://localhost:8080/api/session/create');
this.currentSessionId = sessionResponse.data.sessionId;
await axios.post('http://localhost:8080/oauth/callback', {
sessionId: this.currentSessionId,
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
});
console.log('✅ Current authenticated');
return true;
} catch (error) {
console.error('❌ Current auth failed:', error.message);
}
return false;
}
extractValue(text) {
if (!text || typeof text !== 'string') return 'N/A';
// Try JSON parsing
try {
const data = JSON.parse(text);
if (Array.isArray(data)) {
const total = data.reduce((sum, item) => sum + (item.total_cost || 0), 0);
if (total > 0) return `$${total.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`;
}
} catch (e) {}
// Extract dollar amounts
const dollarMatch = text.match(/\$[\d,]+\.?\d*/);
if (dollarMatch) return dollarMatch[0];
// Extract counts
const countMatch = text.match(/(\d+)\s+(?:customers|accounts|records)/i);
if (countMatch) return countMatch[1];
return 'N/A';
}
async testProduction(question) {
try {
const response = await axios.post('http://localhost:3000/mcp', {
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: 'get_costs',
arguments: { query: question.query }
}
}, {
headers: {
'Authorization': `Bearer ${this.productionToken}`,
'Content-Type': 'application/json'
},
timeout: 30000
});
if (response.data?.result?.content?.[0]?.text) {
return this.extractValue(response.data.result.content[0].text);
}
} catch (error) {
console.error(`Production ${question.id} error:`, error.message);
}
return 'Error';
}
async testCurrent(question) {
try {
// Map to appropriate tool
let toolName = 'api___invoices_caui';
if (question.id === 'Q1') toolName = 'api___msp_customers';
else if (question.id === 'Q9') toolName = 'api___user_management_accounts';
else if (question.id === 'Q10' || question.id === 'Q11') toolName = 'api___recommendationsNew_heatmap_summary';
else if (question.id === 'Q12') toolName = 'api___anomaly_detection';
const response = await axios.post('http://localhost:3001/sse', {
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: toolName,
arguments: {
sessionId: this.currentSessionId,
userQuery: question.query
}
}
}, {
timeout: 30000
});
if (response.data?.result?.content?.[0]?.text) {
const text = response.data.result.content[0].text;
// Extract from formatted response
const costMatch = text.match(/💰[^$]*\$([0-9,]+\.?\d*)/);
if (costMatch) return `$${costMatch[1]}`;
return this.extractValue(text);
}
} catch (error) {
console.error(`Current ${question.id} error:`, error.message);
}
return 'Error';
}
async runComparison() {
console.log('\n' + '='.repeat(120));
console.log('📊 FINAL HONEST COMPARISON TABLE');
console.log('Production (GitHub) vs Current (OAuth) - Both from UmbrellaMCP directory');
console.log('='.repeat(120));
// Authenticate both
const prodAuth = await this.authenticateProduction();
const currAuth = await this.authenticateCurrent();
if (!prodAuth || !currAuth) {
console.error('❌ Authentication failed');
return;
}
console.log('\n📋 Testing all 13 questions...\n');
// Test each question
for (const q of QUESTIONS) {
process.stdout.write(`${q.id}: Testing...`);
const prodResult = await this.testProduction(q);
const currResult = await this.testCurrent(q);
this.results.push({
id: q.id,
query: q.query,
production: prodResult,
current: currResult
});
console.log(` Production: ${prodResult} | Current: ${currResult}`);
await new Promise(resolve => setTimeout(resolve, 500));
}
this.displayTable();
}
displayTable() {
console.log('\n' + '='.repeat(140));
console.log('📊 NUMERICAL COMPARISON TABLE');
console.log('='.repeat(140));
console.log('\n| ID | Question | Production (GitHub) | Current (OAuth) |');
console.log('|-----|-------------------------------------------------------------|---------------------|--------------------|');
for (const r of this.results) {
const q = r.query.length > 57 ? r.query.substring(0, 54) + '...' : r.query.padEnd(57);
const p = r.production.padEnd(19);
const c = r.current.padEnd(18);
console.log(`| ${r.id.padEnd(3)} | ${q} | ${p} | ${c} |`);
}
console.log('\n' + '='.repeat(140));
console.log('DETAILED VALUES:');
console.log('='.repeat(140));
for (const r of this.results) {
console.log(`\n${r.id}: ${r.query}`);
console.log(`├─ Production (GitHub): ${r.production}`);
console.log(`└─ Current (OAuth): ${r.current}`);
}
const prodWorking = this.results.filter(r => r.production !== 'Error' && r.production !== 'N/A').length;
const currWorking = this.results.filter(r => r.current !== 'Error' && r.current !== 'N/A').length;
console.log('\n' + '='.repeat(140));
console.log('SUMMARY:');
console.log(`Production Working: ${prodWorking}/13`);
console.log(`Current Working: ${currWorking}/13`);
console.log('='.repeat(140));
}
}
const comparison = new FinalHonestComparison();
comparison.runComparison().catch(console.error);