Skip to main content
Glama
complete-test.cjsβ€’10.9 kB
#!/usr/bin/env node // Complete test of all questions with detailed answers const { spawn } = require('child_process'); class CompleteTester { constructor() { this.server = null; this.requestId = 1; this.responses = []; } async startServer() { return new Promise((resolve, reject) => { this.server = spawn('node', ['dist/index.js'], { stdio: ['pipe', 'pipe', 'pipe'], cwd: process.cwd() }); 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.on('error', reject); setTimeout(resolve, 3000); }); } async sendRequest(method, params = {}) { return new Promise((resolve) => { const request = { jsonrpc: "2.0", id: this.requestId++, method, params }; const startResponseCount = this.responses.length; this.server.stdin.write(JSON.stringify(request) + '\n'); 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 > 20000) { resolve(null); // Timeout after 20s } else { setTimeout(checkForResponse, 200); } }; const startTime = Date.now(); setTimeout(checkForResponse, 200); }); } cleanup() { if (this.server) { this.server.kill(); } } } async function runAllQuestions() { console.log('🎯 COMPLETE TEST: ALL 12 QUESTIONS WITH DETAILED ANSWERS'); console.log('=' .repeat(80)); const client = new CompleteTester(); await client.startServer(); // Authenticate once const authResponse = await client.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'); client.cleanup(); return; } console.log('βœ… Authentication successful\n'); const questions = [ { num: 1, text: "What was my total AWS cost for March 2025?", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "none" } }, expected: 104755.07 }, { num: 2, text: "What was my total unblended AWS cost for March 2025?", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "none", isUnblended: "true" } }, expected: 104755.07 }, { num: 3, text: "What was my total amortized AWS cost for March 2025?", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "none", isAmortized: "true" } }, expected: 108831.79 }, { num: 4, text: "What was my total net amortized AWS cost for March 2025?", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "none", isNetAmortized: "true" } }, expected: 64730.56 }, { num: 5, text: "What are my top 5 AWS services by cost for March 2025?", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "service" } } }, { num: 6, text: "Show me AWS costs grouped by account for March 2025", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "account" } } }, { num: 7, text: "What was my daily AWS cost trend for March 2025?", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "none", periodGranLevel: "day" } } }, { num: 8, text: "Show me AWS region breakdown for March 2025", params: { name: 'api___invoices_caui', arguments: { startDate: "2025-03-01", endDate: "2025-03-31", cloud_context: "aws", groupBy: "region" } } }, { num: 9, text: "What are my AWS Reserved Instance recommendations?", params: { name: 'api___recommendations_v2', arguments: { cloud_context: "aws", recommendation_type: "reserved_instance" } } }, { num: 10, text: "What are my AWS EC2 rightsizing recommendations?", params: { name: 'api___recommendations_v2', arguments: { cloud_context: "aws", recommendation_type: "rightsizing" } } }, { num: 11, text: "Show me all AWS cost optimization recommendations", params: { name: 'api___recommendations_v2', arguments: { cloud_context: "aws" } } }, { num: 12, text: "What are my top savings opportunities across all AWS services?", params: { name: 'api___recommendations_v2', arguments: { cloud_context: "aws", recommendation_type: "all" } } } ]; const results = []; for (const q of questions) { console.log(`πŸ“Š QUESTION ${q.num}: ${q.text}`); console.log('-'.repeat(80)); const response = await client.sendRequest('tools/call', q.params); if (response?.result?.content?.[0]?.text) { const text = response.result.content[0].text; if (q.num <= 8) { // Cost questions - parse JSON data const jsonMatch = text.match(/```json\n(.*?)\n```/s); if (jsonMatch) { try { const data = JSON.parse(jsonMatch[1]); const total = data.reduce((sum, item) => sum + (item.total_cost || 0), 0); console.log(`πŸ’° ANSWER: $${total.toFixed(2)}`); if (q.expected && Math.abs(total - q.expected) < 1) { console.log(`βœ… CORRECT! Matches expected $${q.expected.toFixed(2)}`); results.push(`βœ… Q${q.num}: $${total.toFixed(2)} (CORRECT)`); } else if (q.expected) { console.log(`⚠️ Expected $${q.expected.toFixed(2)}, got $${total.toFixed(2)}`); results.push(`⚠️ Q${q.num}: $${total.toFixed(2)} (expected ${q.expected.toFixed(2)})`); } else { results.push(`πŸ“Š Q${q.num}: $${total.toFixed(2)}`); } if (q.num === 5 && data.length > 0) { // Show top services const serviceMap = {}; data.forEach(item => { const serviceName = item.service_name || item.group_by || 'Unknown'; if (!serviceMap[serviceName]) serviceMap[serviceName] = 0; serviceMap[serviceName] += (item.total_cost || 0); }); const topServices = Object.entries(serviceMap) .sort(([,a], [,b]) => b - a) .slice(0, 5); console.log('\nπŸ† TOP 5 AWS SERVICES:'); topServices.forEach(([service, cost], index) => { console.log(` ${index + 1}. ${service}: $${cost.toFixed(2)}`); }); } if (q.num === 6 && data.length > 0) { // Show top accounts const accountMap = {}; data.forEach(item => { const accountName = item.account_name || item.group_by || 'Unknown'; if (!accountMap[accountName]) accountMap[accountName] = 0; accountMap[accountName] += (item.total_cost || 0); }); const topAccounts = Object.entries(accountMap) .sort(([,a], [,b]) => b - a) .slice(0, 3); console.log('\n🏒 TOP ACCOUNTS:'); topAccounts.forEach(([account, cost], index) => { console.log(` ${index + 1}. ${account}: $${cost.toFixed(2)}`); }); } } catch (e) { console.log('❌ JSON parsing error'); results.push(`❌ Q${q.num}: JSON parsing error`); } } else { console.log('❌ No JSON data found'); results.push(`❌ Q${q.num}: No JSON data found`); } } else { // Recommendation questions const recMatch = text.match(/(\d+)\s+recommendations/i); const savingsMatch = text.match(/\$([0-9,]+(?:\.\d+)?)/); if (recMatch && savingsMatch) { console.log(`🎯 ANSWER: ${recMatch[1]} recommendations found`); console.log(`πŸ’° SAVINGS: $${savingsMatch[1]} potential annual savings`); results.push(`🎯 Q${q.num}: ${recMatch[1]} recommendations, $${savingsMatch[1]} savings`); } else { console.log('πŸ“‹ Recommendations data available'); results.push(`πŸ“‹ Q${q.num}: Recommendations available`); } // Show brief excerpt const lines = text.split('\n').slice(0, 3); console.log('πŸ“ Summary:', lines.join(' ').substring(0, 100) + '...'); } } else { console.log('❌ No response received'); results.push(`❌ Q${q.num}: No response`); } console.log(''); await new Promise(resolve => setTimeout(resolve, 1000)); } // Summary console.log('\n' + '='.repeat(80)); console.log('πŸ“Š COMPLETE RESULTS SUMMARY:'); console.log('='.repeat(80)); results.forEach(result => console.log(result)); client.cleanup(); console.log('\nβœ… All 12 questions completed successfully!'); } runAllQuestions().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