#!/usr/bin/env node
const { spawn } = require('child_process');
async function detailedTest14Questions() {
console.log('π DETAILED RESPONSES FOR ALL 14 QUESTIONS');
console.log('=' .repeat(70));
console.log('Account: david+saola@umbrellacost.com');
console.log('Date: ' + new Date().toISOString().split('T')[0]);
console.log('=' .repeat(70));
const server = spawn('node', ['dist/index.js'], {
stdio: ['pipe', 'pipe', 'pipe'],
env: {
...process.env,
UMBRELLA_API_BASE_URL: 'https://api-front.umbrellacost.io/api/v1'
}
});
const responses = [];
let requestId = 0;
server.stdout.on('data', (data) => {
const lines = data.toString().split('\n').filter(line => line.trim());
for (const line of lines) {
try {
const response = JSON.parse(line);
responses.push(response);
} catch (e) {}
}
});
server.stderr.on('data', () => {}); // Suppress server logs
await new Promise(resolve => setTimeout(resolve, 2000));
// Authenticate
console.log('π Authenticating...\n');
server.stdin.write(JSON.stringify({
jsonrpc: "2.0",
id: ++requestId,
method: "tools/call",
params: {
name: 'authenticate_user',
arguments: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
}
}
}) + '\n');
await new Promise(resolve => setTimeout(resolve, 5000));
// Helper to make API calls
async function makeCall(toolName, args, waitTime = 8000) {
const id = ++requestId;
server.stdin.write(JSON.stringify({
jsonrpc: "2.0",
id,
method: "tools/call",
params: {
name: toolName,
arguments: args
}
}) + '\n');
await new Promise(resolve => setTimeout(resolve, waitTime));
return responses.find(r => r.id === id);
}
// Helper to parse and display response
function showDetailedResponse(response, questionNum) {
if (!response) {
console.log(' β ERROR: No response received\n');
return { success: false, error: 'No response' };
}
if (response.error) {
console.log(' β ERROR:', response.error.message || 'Unknown error');
console.log('');
return { success: false, error: response.error.message };
}
if (response.result?.content?.[0]?.text) {
const text = response.result.content[0].text;
// Check for JSON data
const jsonMatch = text.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
try {
const data = JSON.parse(jsonMatch[1]);
console.log(' β
SUCCESS - JSON Response received');
console.log(' π Data Structure:', Array.isArray(data) ? 'Array' : 'Object');
// Handle different response types
if (Array.isArray(data)) {
console.log(' π Items:', data.length);
if (data.length > 0 && data[0].total_cost !== undefined) {
const total = data.reduce((sum, item) => sum + parseFloat(item.total_cost || item.cost || 0), 0);
console.log(' π° Total Cost: $' + total.toFixed(2));
}
} else if (data.anomalies) {
console.log(' π₯ Anomalies Found:', data.anomalies.length);
const totalImpact = data.anomalies.reduce((sum, a) => sum + parseFloat(a.totalCostImpact || 0), 0);
console.log(' π° Total Impact: $' + totalImpact.toFixed(2));
} else if (data.recommendations) {
console.log(' π‘ Recommendations:', data.recommendations.length);
} else if (data.customers) {
console.log(' π₯ Customers:', data.customers.length);
} else if (data.accounts) {
console.log(' π’ Accounts:', data.accounts.length);
}
console.log('');
return { success: true, data, text };
} catch (e) {
console.log(' β οΈ JSON parsing error:', e.message);
console.log('');
return { success: true, text };
}
}
// Text response (no JSON)
console.log(' β
SUCCESS - Text Response');
// Extract key information from text
if (text.includes('Results:')) {
const resultsMatch = text.match(/Results: (\d+) items/);
if (resultsMatch) {
console.log(' π Results:', resultsMatch[1], 'items');
}
}
if (text.includes('Total Annual Savings')) {
const savingsMatch = text.match(/Total Annual Savings: \$([0-9,\.]+)/);
if (savingsMatch) {
console.log(' π° Potential Savings: $' + savingsMatch[1]);
}
}
// Show first 200 chars of response
console.log(' π Response preview:', text.substring(0, 200).replace(/\n/g, ' '));
console.log('');
return { success: true, text };
}
console.log(' β ERROR: Invalid response format\n');
return { success: false, error: 'Invalid format' };
}
console.log('=' .repeat(70));
console.log('Q1: QUESTIONS FOR THE MSP ACCOUNT');
console.log('=' .repeat(70));
console.log(' βΉοΈ This is a section header - no API call needed\n');
console.log('=' .repeat(70));
console.log('Q2: SHOW ME THE LIST OF CUSTOMERS (MSP)');
console.log('=' .repeat(70));
const q2 = await makeCall('api___msp_customers', {});
showDetailedResponse(q2, 2);
console.log('=' .repeat(70));
console.log('Q3: QUESTIONS FOR BOTH MSP AND DIRECT ACCOUNTS');
console.log('=' .repeat(70));
console.log(' βΉοΈ This is a section header - no API call needed\n');
console.log('=' .repeat(70));
console.log('Q4: WHAT IS MY TOTAL COST?');
console.log('=' .repeat(70));
console.log(' π
Period: August 2025\n');
const q4 = await makeCall('api___invoices_caui', {
startDate: '2025-08-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
accountId: '932213950603'
});
showDetailedResponse(q4, 4);
console.log('=' .repeat(70));
console.log('Q5: WHAT IS MY TOTAL AWS COST?');
console.log('=' .repeat(70));
console.log(' π
Period: August 2025\n');
const q5 = await makeCall('api___invoices_caui', {
startDate: '2025-08-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
cloud_context: 'aws',
accountId: '932213950603'
});
showDetailedResponse(q5, 5);
console.log('=' .repeat(70));
console.log('Q6: WHAT IS MY TOTAL GCP COST?');
console.log('=' .repeat(70));
console.log(' π
Period: August 2025\n');
const q6 = await makeCall('api___invoices_caui', {
startDate: '2025-08-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
cloud_context: 'gcp',
accountId: '932213950603'
});
showDetailedResponse(q6, 6);
console.log('=' .repeat(70));
console.log('Q7: WHAT IS MY TOTAL AZURE COST?');
console.log('=' .repeat(70));
console.log(' π
Period: August 2025\n');
const q7 = await makeCall('api___invoices_caui', {
startDate: '2025-08-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
cloud_context: 'azure',
accountId: '932213950603'
});
showDetailedResponse(q7, 7);
console.log('=' .repeat(70));
console.log('Q8: SHOW ME THE TOTAL COST PER MONTH');
console.log('=' .repeat(70));
console.log(' π
Period: July - August 2025\n');
const q8 = await makeCall('api___invoices_caui', {
startDate: '2025-07-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
accountId: '932213950603'
});
showDetailedResponse(q8, 8);
console.log('=' .repeat(70));
console.log('Q9: SHOW ME THE TOTAL AWS COST PER MONTH');
console.log('=' .repeat(70));
console.log(' π
Period: July - August 2025\n');
const q9 = await makeCall('api___invoices_caui', {
startDate: '2025-07-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
cloud_context: 'aws',
accountId: '932213950603'
});
showDetailedResponse(q9, 9);
console.log('=' .repeat(70));
console.log('Q10: SHOW ME THE TOTAL COST FOR ALL AZURE ACCOUNTS');
console.log('=' .repeat(70));
console.log(' π
Period: August 2025\n');
console.log(' β οΈ Note: This account may not have Azure configured\n');
const q10 = await makeCall('api___invoices_caui', {
startDate: '2025-08-01',
endDate: '2025-08-26',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost'],
isAmortized: true,
cloud_context: 'azure',
accountId: 'ALL' // Try ALL accounts
});
showDetailedResponse(q10, 10);
console.log('=' .repeat(70));
console.log('Q11: SHOW ME ALL AVAILABLE ACCOUNTS');
console.log('=' .repeat(70));
const q11 = await makeCall('api___user_management_accounts', {});
const q11Result = showDetailedResponse(q11, 11);
// Show first few accounts if available
if (q11Result.success && q11Result.data?.accounts) {
console.log(' π First 3 accounts:');
q11Result.data.accounts.slice(0, 3).forEach(acc => {
console.log(' β’ ' + (acc.name || acc.linkedaccid || 'Unknown') +
' (' + (acc.cloud || 'AWS') + ')');
});
console.log('');
}
console.log('=' .repeat(70));
console.log('Q12: WHAT DO YOU RECOMMEND FOR SAVING AWS COSTS?');
console.log('=' .repeat(70));
const q12 = await makeCall('api___recommendations_report', {
cloud_context: 'aws'
}, 10000);
const q12Result = showDetailedResponse(q12, 12);
// Parse recommendations if available
if (q12Result.success && q12Result.text) {
if (q12Result.text.includes('EC2 Instance Optimization')) {
console.log(' π Categories found:');
if (q12Result.text.includes('EC2 Instance Optimization')) console.log(' β’ EC2 Instance Optimization');
if (q12Result.text.includes('Unattached EBS')) console.log(' β’ Unattached EBS Volumes');
if (q12Result.text.includes('Reserved Instances')) console.log(' β’ Reserved Instances');
console.log('');
}
}
console.log('=' .repeat(70));
console.log('Q13: WHAT ARE THE POTENTIAL SAVINGS PER CATEGORY?');
console.log('=' .repeat(70));
console.log(' βΉοΈ See Q12 above for detailed savings breakdown\n');
console.log('=' .repeat(70));
console.log('Q14: COST IMPACT OF ANOMALIES IN LAST 10 DAYS FOR AWS');
console.log('=' .repeat(70));
console.log(' π
Period: Last 10 days\n');
const endDate = '2025-08-27';
const startDate = '2025-08-17';
const q14 = await makeCall('api___anomaly_detection', {
startDate: startDate,
endDate: endDate,
cloud_context: 'aws',
isFull: 'true',
isPpApplied: 'false'
}, 15000);
const q14Result = showDetailedResponse(q14, 14);
// Show top anomalies if found
if (q14Result.success && q14Result.data?.anomalies && q14Result.data.anomalies.length > 0) {
console.log(' π Top 3 Anomalies:');
q14Result.data.anomalies
.sort((a, b) => parseFloat(b.totalCostImpact || 0) - parseFloat(a.totalCostImpact || 0))
.slice(0, 3)
.forEach((anomaly, i) => {
console.log(` ${i+1}. ${anomaly.serviceName}: $${parseFloat(anomaly.totalCostImpact || 0).toFixed(2)}`);
console.log(` Status: ${anomaly.isClosed ? 'Closed' : 'Open'}`);
});
console.log('');
}
// Final Summary
console.log('=' .repeat(70));
console.log('π SUMMARY');
console.log('=' .repeat(70));
let successCount = 0;
let totalQuestions = 11; // Excluding headers (Q1, Q3, Q13)
[q2, q4, q5, q6, q7, q8, q9, q10, q11, q12, q14].forEach((response, idx) => {
const qNum = [2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14][idx];
if (response?.result?.content?.[0]?.text) {
successCount++;
console.log(` β
Q${qNum}: Response received`);
} else {
console.log(` β Q${qNum}: No response`);
}
});
console.log(`\n Success Rate: ${successCount}/${totalQuestions} (${Math.round(successCount/totalQuestions * 100)}%)`);
console.log('=' .repeat(70));
server.kill();
console.log('\nβ
Detailed test complete!');
}
detailedTest14Questions().catch(console.error);