#!/usr/bin/env node
const { spawn } = require('child_process');
const path = require('path');
console.log('π AWS MONTHLY COSTS - LAST 8 MONTHS');
console.log('Account: david+saola@umbrellacost.com');
console.log('Query: Total AWS costs per month for the last 8 months');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββ\n');
// Calculate last 8 months - go back to January 2025
const startDate = '2025-01-01';
const endDate = new Date().toISOString().split('T')[0];
console.log(`π
Period: ${startDate} to ${endDate}`);
console.log(`π Expected: 8 months of AWS cost data\n`);
// Start the MCP server
const serverPath = path.join(__dirname, 'src', 'index.ts');
const server = spawn('npx', ['tsx', serverPath], {
env: { ...process.env },
stdio: ['pipe', 'pipe', 'pipe']
});
let serverReady = false;
server.stderr.on('data', (data) => {
const output = data.toString();
if (output.includes('Umbrella MCP Server started successfully')) {
serverReady = true;
authenticate();
}
});
server.stdout.on('data', (data) => {
const text = data.toString();
const lines = text.split('\n');
for (const line of lines) {
if (line.trim() && line.includes('"result"')) {
try {
const response = JSON.parse(line);
if (response.id === 1 && text.includes('Successfully authenticated')) {
console.log('β
Authentication successful\n');
setTimeout(() => getAWS8MonthsCosts(), 2000);
}
else if (response.id === 2) {
console.log('π **AWS COSTS - LAST 8 MONTHS (2025)**\n');
console.log('β'.repeat(80));
const content = response.result?.content?.find(c => c.type === 'text')?.text || '';
// Parse and format the response properly
formatAWS8MonthsResponse(content);
server.kill();
process.exit(0);
}
} catch (e) {
// Continue if JSON parsing fails
}
}
}
});
function authenticate() {
console.log('π Authenticating with david+saola account...\n');
const authRequest = {
jsonrpc: '2.0',
method: 'tools/call',
params: {
name: 'authenticate_user',
arguments: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
}
},
id: 1
};
server.stdin.write(JSON.stringify(authRequest) + '\n');
}
function getAWS8MonthsCosts() {
console.log('π€ Requesting 8 months of AWS cost data...');
console.log('π§ Tool: api___invoices_caui');
console.log('βοΈ Filter: cloud_context="aws"');
console.log('π Granularity: month');
console.log('π’ Account: 932213950603\n');
const costRequest = {
jsonrpc: '2.0',
method: 'tools/call',
params: {
name: 'api___invoices_caui',
arguments: {
accountId: '932213950603',
startDate: startDate,
endDate: endDate,
groupBy: 'none',
periodGranLevel: 'month',
cloud_context: 'aws'
}
},
id: 2
};
server.stdin.write(JSON.stringify(costRequest) + '\n');
}
function formatAWS8MonthsResponse(content) {
console.log('π€ **RAW MCP SERVER RESPONSE:**');
console.log(content);
console.log('\n' + 'β'.repeat(80) + '\n');
// Extract JSON data
const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/);
if (!jsonMatch) {
console.log('β Unable to extract JSON data from response');
return;
}
try {
// Handle truncated JSON by trying to parse what we can see
let jsonText = jsonMatch[1];
// If truncated, try to extract visible monthly data
if (jsonText.includes('... and ') || jsonText.includes(']')) {
// Extract visible entries
const entries = [];
const entryMatches = jsonText.matchAll(/{\s*"group_by":\s*"[^"]*",\s*"usage_date":\s*"([^"]+)",\s*"account_id":\s*"[^"]*",\s*"total_cost":\s*([0-9.]+)[^}]*}/g);
for (const match of entryMatches) {
entries.push({
usage_date: match[1],
total_cost: parseFloat(match[2])
});
}
if (entries.length > 0) {
console.log('π° **EXTRACTED AWS MONTHLY COSTS:**\n');
let totalCost = 0;
const monthNames = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
entries.forEach((entry, index) => {
const [year, month] = entry.usage_date.split('-');
const monthName = monthNames[parseInt(month) - 1];
const cost = entry.total_cost;
totalCost += cost;
console.log(`${index + 1}. **${monthName} ${year}**: $${cost.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`);
});
console.log('\n' + 'β'.repeat(50));
console.log(`**Total AWS Costs (${entries.length} months)**: $${totalCost.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`);
console.log(`**Average Monthly Cost**: $${(totalCost / entries.length).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`);
// Calculate month-over-month changes
if (entries.length > 1) {
console.log('\nπ **MONTH-OVER-MONTH ANALYSIS:**');
for (let i = 1; i < entries.length; i++) {
const prevCost = entries[i-1].total_cost;
const currCost = entries[i].total_cost;
const change = currCost - prevCost;
const changePercent = ((change / prevCost) * 100).toFixed(1);
const [prevYear, prevMonth] = entries[i-1].usage_date.split('-');
const [currYear, currMonth] = entries[i].usage_date.split('-');
const prevMonthName = monthNames[parseInt(prevMonth) - 1];
const currMonthName = monthNames[parseInt(currMonth) - 1];
const changeSymbol = change >= 0 ? 'βοΈ' : 'βοΈ';
const changeFormatted = change >= 0 ? `+$${change.toLocaleString('en-US', {minimumFractionDigits: 2})}` : `-$${Math.abs(change).toLocaleString('en-US', {minimumFractionDigits: 2})}`;
console.log(`${prevMonthName} β ${currMonthName}: ${changeFormatted} (${changePercent}%) ${changeSymbol}`);
}
}
console.log('\nπ **DATA QUALITY:**');
console.log(`β
Account: 932213950603`);
console.log(`β
Cost Type: Unblended (default)`);
console.log(`β
Cloud Filter: AWS only`);
console.log(`β
Period: ${startDate} to ${endDate}`);
console.log(`β
Months Retrieved: ${entries.length}`);
} else {
console.log('β No monthly cost entries found in response');
}
}
} catch (error) {
console.log(`β Error parsing response: ${error.message}`);
}
}
setTimeout(() => {
if (!serverReady) {
console.error('β Server failed to start within 15 seconds');
server.kill();
process.exit(1);
}
}, 15000);