#!/usr/bin/env node
const { spawn } = require('child_process');
// CORRECTED: Get proper monthly aggregation from production STDIO MCP
class CorrectProductionMonthly {
constructor() {
this.mcpProcess = null;
}
async startMCP() {
console.log('๐ Starting Production MCP Server (STDIO)...');
this.mcpProcess = spawn('node', ['dist/index.js'], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: '/Users/david/Downloads/MCP/UmbrellaMCP/production'
});
this.mcpProcess.stderr.on('data', (data) => {
console.log('MCP Server:', data.toString().trim());
});
await new Promise(resolve => setTimeout(resolve, 3000));
}
sendMCPRequest(method, params) {
return new Promise((resolve, reject) => {
const request = {
jsonrpc: '2.0',
id: Date.now(),
method,
params: params || {}
};
this.mcpProcess.stdin.write(JSON.stringify(request) + '\n');
let buffer = '';
const handler = (data) => {
buffer += data.toString();
const lines = buffer.split('\n');
for (let i = 0; i < lines.length - 1; i++) {
const line = lines[i].trim();
if (line) {
try {
const response = JSON.parse(line);
if (response.id === request.id) {
this.mcpProcess.stdout.removeListener('data', handler);
resolve(response);
return;
}
} catch (e) {
// Not complete JSON yet
}
}
}
buffer = lines[lines.length - 1];
};
this.mcpProcess.stdout.on('data', handler);
setTimeout(() => {
this.mcpProcess.stdout.removeListener('data', handler);
reject(new Error('Request timeout'));
}, 30000);
});
}
async authenticate() {
console.log('๐ Authenticating SAOLA account...');
try {
// Initialize
await this.sendMCPRequest('initialize', {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'correct-monthly-client', version: '1.0.0' }
});
// Authenticate
const authResponse = await this.sendMCPRequest('tools/call', {
name: 'authenticate_user',
arguments: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
}
});
if (authResponse.result?.content?.[0]?.text?.includes('Successfully')) {
console.log('โ
Authentication successful\n');
return true;
} else {
console.log('โ Authentication failed');
return false;
}
} catch (error) {
console.log('โ Authentication error:', error.message);
return false;
}
}
async getCorrectMonthlyCosts() {
try {
await this.startMCP();
const authSuccess = await this.authenticate();
if (!authSuccess) {
console.log('โ Cannot proceed without authentication');
return;
}
console.log('๐ CORRECTED MONTHLY BREAKDOWN: JANUARY TO AUGUST 2025');
console.log('Using periodGranLevel="month" for proper monthly aggregation');
console.log('=' .repeat(80));
// CORRECT approach: Use single API call with periodGranLevel="month"
// to get proper monthly aggregated data for the entire period
console.log('๐ค Requesting monthly aggregated data for Jan-Aug 2025...\n');
const response = await this.sendMCPRequest('tools/call', {
name: 'api___invoices_caui',
arguments: {
startDate: '2025-01-01',
endDate: '2025-08-31',
groupBy: 'none', // KEY FIX: Use 'none' not 'service'
periodGranLevel: 'month', // KEY FIX: Use month aggregation
cloud_context: 'aws', // KEY FIX: Add AWS context
accountId: '932213950603' // KEY FIX: Correct AWS account ID
}
});
if (response.result?.content?.[0]?.text) {
try {
const data = JSON.parse(response.result.content[0].text);
if (Array.isArray(data) && data.length > 0) {
console.log('โ
Received monthly aggregated data\n');
// Group by month for display
const monthlyTotals = {};
data.forEach(record => {
const date = new Date(record.usage_date);
const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
const monthName = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' });
if (!monthlyTotals[monthKey]) {
monthlyTotals[monthKey] = {
month: monthName,
total_cost: 0,
records: 0
};
}
monthlyTotals[monthKey].total_cost += record.total_cost || 0;
monthlyTotals[monthKey].records++;
});
// Display results
console.log('๐ CORRECTED MONTHLY COST SUMMARY - PRODUCTION VERSION');
console.log('=' .repeat(80));
let grandTotal = 0;
const sortedMonths = Object.keys(monthlyTotals).sort();
sortedMonths.forEach((monthKey, index) => {
const month = monthlyTotals[monthKey];
const monthNum = String(index + 1).padStart(2, '0');
const costDisplay = `$${month.total_cost.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`;
console.log(`${monthNum}. ${month.month.padEnd(15)} ${costDisplay.padStart(15)} (${month.records} records)`);
grandTotal += month.total_cost;
});
console.log('-' .repeat(80));
console.log(` TOTAL (8 months): $${grandTotal.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`);
console.log('=' .repeat(80));
// Show sample records to verify data
console.log('\n๐ SAMPLE MONTHLY RECORDS (first 3):');
data.slice(0, 3).forEach((record, i) => {
console.log(`${i + 1}. Date: ${record.usage_date}, Cost: $${record.total_cost?.toFixed(2) || '0.00'}, Service: ${record.service_name || 'N/A'}`);
});
console.log(`\nTotal records returned: ${data.length}`);
} else {
console.log('โ No monthly data received or empty array');
}
} catch (parseError) {
console.log('โ Failed to parse response:', parseError.message);
console.log('Raw response:', response.result.content[0].text.substring(0, 200) + '...');
}
} else {
console.log('โ No response content received');
if (response.error) {
console.log('Error:', JSON.stringify(response.error, null, 2));
}
}
} finally {
if (this.mcpProcess) {
this.mcpProcess.kill();
console.log('\n๐ MCP Server stopped');
}
}
}
}
const correctedMonthly = new CorrectProductionMonthly();
correctedMonthly.getCorrectMonthlyCosts().catch(console.error);