Skip to main content
Glama
cloudwatch-ui-format.cjsโ€ข8.56 kB
#!/usr/bin/env node /** * CloudWatch Costs - UI Format Match * Using the exact same parameters as the UI request */ const { spawn } = require('child_process'); class CloudWatchUIFormat { constructor() { this.server = null; this.requestId = 1; this.responses = []; } async startServer() { console.log('๐ŸŽฏ CLOUDWATCH COSTS - MATCHING UI FORMAT'); console.log('Using exact parameters from UI request'); console.log('=' .repeat(80)); return new Promise((resolve, reject) => { this.server = spawn('node', ['dist/index.js'], { stdio: ['pipe', 'pipe', 'pipe'], cwd: process.cwd(), env: { ...process.env, UMBRELLA_API_BASE_URL: 'https://api-front.umbrellacost.io/api/v1' } }); this.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); this.responses.push(response); } catch (e) {} } }); this.server.stderr.on('data', (data) => { const message = data.toString().trim(); if (message.includes('๐Ÿš€') || message.includes('Successfully authenticated') || message.includes('API REQUEST')) { console.log('SERVER:', message); } }); this.server.on('error', reject); setTimeout(resolve, 3000); }); } async sendRequest(method, params = {}) { return new Promise((resolve) => { const request = { jsonrpc: "2.0", id: this.requestId++, method, params }; this.server.stdin.write(JSON.stringify(request) + '\n'); const startTime = Date.now(); const startResponseCount = this.responses.length; const checkForResponse = () => { const newResponses = this.responses.slice(startResponseCount); const matchingResponse = newResponses.find(r => r.id === request.id); if (matchingResponse) { resolve(matchingResponse); } else if (Date.now() - startTime > 45000) { resolve(null); } else { setTimeout(checkForResponse, 500); } }; setTimeout(checkForResponse, 500); }); } formatCurrency(amount) { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2 }).format(amount); } formatDate(dateString) { return new Date(dateString).toLocaleDateString('en-US', { month: 'short', day: '2-digit' }); } analyzeCloudWatchData(data) { console.log('\n๐Ÿ” CLOUDWATCH COST CALCULATION:'); console.log('=' .repeat(60)); if (!data || !Array.isArray(data)) { console.log('โŒ No data to analyze'); return 0; } console.log(`๐Ÿ“Š Total CloudWatch records: ${data.length}`); // Calculate total cost let totalCost = 0; const dailyCosts = {}; const serviceCosts = {}; data.forEach((item, index) => { const cost = item.total_cost || 0; totalCost += cost; // Daily breakdown if (item.usage_date) { const date = this.formatDate(item.usage_date); dailyCosts[date] = (dailyCosts[date] || 0) + cost; } // Service breakdown const service = item.service_name || item.resource_name || 'CloudWatch'; serviceCosts[service] = (serviceCosts[service] || 0) + cost; // Show first few records if (index < 3) { console.log(`\n๐Ÿ“‹ Record ${index + 1}:`); console.log(` Date: ${item.usage_date}`); console.log(` Cost: ${this.formatCurrency(cost)}`); console.log(` Service: ${item.service_name || 'N/A'}`); console.log(` Usage Type: ${item.usage_type || 'N/A'}`); console.log(` Resource: ${item.resource_name || 'N/A'}`); } }); console.log('\n๐Ÿ’ฐ TOTAL CALCULATION:'); console.log(` Sum of all daily costs = ${this.formatCurrency(totalCost)}`); console.log('\n๐Ÿ“… DAILY BREAKDOWN:'); Object.entries(dailyCosts) .sort(([a], [b]) => new Date(a) - new Date(b)) .forEach(([date, cost]) => { console.log(` ${date}: ${this.formatCurrency(cost)}`); }); console.log('\n๐Ÿ”ง SERVICE COMPONENTS:'); Object.entries(serviceCosts) .sort(([,a], [,b]) => b - a) .forEach(([service, cost]) => { const percentage = ((cost / totalCost) * 100).toFixed(1); console.log(` ${service}: ${this.formatCurrency(cost)} (${percentage}%)`); }); return totalCost; } async runCloudWatchUITest() { try { await this.startServer(); // Authenticate first console.log('\n๐Ÿ” AUTHENTICATING...'); const authResponse = await this.sendRequest('tools/call', { name: 'authenticate_user', arguments: { username: 'david+saola@umbrellacost.com', password: 'Dsamsung1!' } }); if (!authResponse?.result?.content?.[0]?.text?.includes('Successfully authenticated')) { console.log('โŒ Authentication failed'); return; } console.log('โœ… Authentication successful'); console.log('\n๐Ÿ“‹ UI REQUEST ANALYSIS:'); console.log('Original UI URL:'); console.log('https://api-front.umbrellacost.io/api/v1/invoices/caui'); console.log('?groupBy=service&groupBy=usagedate'); console.log('&startDate=2025-07-16&endDate=2025-08-24'); console.log('&periodGranLevel=day'); console.log('&costType=cost&costType=discount'); console.log('&filters[service]=AmazonCloudWatch'); console.log('&filters[linkedaccid]=932213950603'); console.log('&isAmortized=true'); // Convert UI parameters to MCP format - simplified first const uiParams = { startDate: "2025-07-16", endDate: "2025-08-24", periodGranLevel: "day", costType: ["cost", "discount"], // Array format groupBy: "service", // Single groupBy first isAmortized: true, // MCP requires accountId instead of filters[linkedaccid] accountId: "932213950603" // Account ID (converted from filters[linkedaccid]) }; console.log('\n๐Ÿ“ค CONVERTED MCP PARAMETERS:'); console.log(JSON.stringify(uiParams, null, 2)); const response = await this.sendRequest('tools/call', { name: 'api___invoices_caui', arguments: uiParams }); if (response?.result?.content?.[0]?.text) { const text = response.result.content[0].text; console.log('\nโœ… CLOUDWATCH DATA RECEIVED'); const jsonMatch = text.match(/```json\n([\s\S]*?)\n```/); if (jsonMatch) { try { const data = JSON.parse(jsonMatch[1]); const totalCost = this.analyzeCloudWatchData(data); console.log('\n' + '=' .repeat(80)); console.log('๐ŸŽฏ CLOUDWATCH COST SUMMARY (39 days):'); console.log(` ${this.formatCurrency(totalCost)}`); console.log('=' .repeat(80)); // Calculate daily average and 30-day projection const days = (new Date('2025-08-24') - new Date('2025-07-16')) / (1000 * 60 * 60 * 24) + 1; const avgDaily = totalCost / days; const thirtyDayProjection = avgDaily * 30; console.log('\n๐Ÿ“Š PROJECTIONS:'); console.log(` Average daily cost: ${this.formatCurrency(avgDaily)}`); console.log(` 30-day projection: ${this.formatCurrency(thirtyDayProjection)}`); } catch (e) { console.log('โŒ Could not parse JSON data:', e.message); console.log('Response preview:', text.substring(0, 500)); } } else { console.log('โŒ No JSON data found'); console.log('Full response:', text); } } else if (response?.error) { console.log('โŒ ERROR:', JSON.stringify(response.error, null, 2)); } else { console.log('โŒ No response received - request may have timed out'); } } catch (error) { console.error('๐Ÿ’ฅ TEST ERROR:', error); } finally { this.cleanup(); } } cleanup() { if (this.server) { this.server.kill(); } } } // Run the UI format test const tester = new CloudWatchUIFormat(); tester.runCloudWatchUITest().catch(console.error);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server