Skip to main content
Glama
test-saola-simple.tsβ€’8.21 kB
#!/usr/bin/env node import dotenv from 'dotenv'; import { UmbrellaAuth } from './auth.js'; import { UmbrellaApiClient } from './api-client.js'; dotenv.config(); // Simple test processor for SAOLA account class SaolaProcessor { private auth: UmbrellaAuth; private apiClient: UmbrellaApiClient; private isAuthenticated = false; constructor(baseURL: string) { this.auth = new UmbrellaAuth(baseURL); this.apiClient = new UmbrellaApiClient(baseURL); } async authenticate(): Promise<boolean> { try { await this.auth.authenticate({ username: 'david+saola@umbrellacost.com', password: 'Dsamsung1!' }); this.apiClient.setAuthToken(this.auth.getAuthHeaders()); this.isAuthenticated = true; return true; } catch (error) { console.error('Auth error:', error); return false; } } async testAllQuestions(): Promise<void> { console.log('πŸ§ͺ TESTING ALL QUESTIONS WITH SAOLA ACCOUNT'); console.log('Username: david+saola@umbrellacost.com'); console.log('Testing exact questions from questions.test'); console.log('════════════════════════════════════════════════\n'); const questions = [ 'show me the list of customers', 'what is my total cost?', 'what is my total AWS cost?', 'what is my total GCP cost?', 'what is my total Azure cost?', 'show me the total cost per month', 'show me the total AWS cost per month', 'show me the total cost for ALL Azure accounts', 'show me all available accounts', 'what do you recommend to to for saving AWS costs?', 'what are the potential savings percategory?', 'Is there any anomalies on AWS?' ]; for (let i = 0; i < questions.length; i++) { const question = questions[i]; console.log('═'.repeat(80)); console.log(`Q${i+1}: "${question}"`); console.log('═'.repeat(80)); let response = ''; try { // Question 1: MSP Customers if (question.includes('list of customers')) { console.log('πŸ”§ Testing MSP customers endpoint...'); const result = await this.apiClient.getCustomers(); response = `**MSP Customers Response:**\nSuccess: ${result.success}\n` + `Data: ${JSON.stringify(result.data, null, 2)}\n` + `Error: ${result.error || 'None'}\n` + `Message: ${result.message || 'None'}`; } // Question 2-7: Cost questions else if (question.includes('total cost')) { console.log('πŸ”§ Testing cost endpoints...'); const today = new Date(); const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); const startDate = startOfMonth.toISOString().split('T')[0]; const endDate = today.toISOString().split('T')[0]; // Get accounts first const accountsResult = await this.apiClient.getAccounts(); if (accountsResult.success && accountsResult.data) { console.log(`Found ${accountsResult.data.length} accounts`); // Use the main AWS account const awsAccount = accountsResult.data.find((acc: any) => acc.accountId === '932213950603' || acc.accountName?.includes('932213950603') ); if (awsAccount) { console.log(`Using account: ${awsAccount.accountName} (${awsAccount.accountId})`); const costResult = await this.apiClient.getCosts({ accountId: awsAccount.accountId, startDate, endDate, groupBy: 'none', periodGranLevel: 'month' }); let totalCost = 0; if (costResult.success && Array.isArray(costResult.data)) { totalCost = costResult.data.reduce((sum: number, item: any) => { return sum + (parseFloat(item.total_cost || item.cost || 0)); }, 0); } response = `**Cost Analysis Response:**\n` + `Question: ${question}\n` + `Account: ${awsAccount.accountName} (${awsAccount.accountId})\n` + `Period: ${startDate} to ${endDate}\n` + `Total Cost: $${totalCost.toLocaleString('en-US', {minimumFractionDigits: 2})}\n` + `Success: ${costResult.success}\n` + `Raw Data: ${JSON.stringify(costResult.data, null, 2)}`; } else { response = `**No suitable account found**\nAvailable accounts: ${JSON.stringify(accountsResult.data, null, 2)}`; } } else { response = `**Failed to get accounts**\nError: ${accountsResult.error}`; } } // Question 8: Available accounts else if (question.includes('available accounts')) { console.log('πŸ”§ Testing accounts endpoint...'); const result = await this.apiClient.getAccounts(); response = `**Available Accounts Response:**\n` + `Success: ${result.success}\n` + `Count: ${Array.isArray(result.data) ? result.data.length : 0}\n` + `Accounts: ${JSON.stringify(result.data, null, 2)}`; } // Question 9-10: Recommendations else if (question.includes('recommend') || question.includes('savings')) { console.log('πŸ”§ Testing recommendations endpoint...'); const result = await this.apiClient.getRecommendations(); response = `**Recommendations Response:**\n` + `Success: ${result.success}\n` + `Total Count: ${result.total_count || 0}\n` + `Total Savings: $${(result.total_potential_savings || 0).toLocaleString()}\n` + `Category Breakdown: ${JSON.stringify(result.category_breakdown, null, 2)}\n` + `Sample Recommendations: ${JSON.stringify(result.data?.slice(0, 3), null, 2)}`; } // Question 11: Anomalies else if (question.includes('anomalies')) { console.log('πŸ”§ Testing anomalies endpoint...'); const endDate = new Date().toISOString().split('T')[0]; const startDate = new Date(); startDate.setDate(startDate.getDate() - 30); const result = await this.apiClient.getAnomalyDetection({ startDate: startDate.toISOString().split('T')[0], endDate: endDate }); response = `**Anomaly Detection Response:**\n` + `Success: ${result.success}\n` + `Period: Last 30 days (${startDate.toISOString().split('T')[0]} to ${endDate})\n` + `Data: ${JSON.stringify(result.data, null, 2)}\n` + `Error: ${result.error || 'None'}`; } else { response = `**Generic Response:**\nQuestion not specifically handled: "${question}"`; } } catch (error: any) { response = `**ERROR:**\n${error.message}\n${error.stack}`; } console.log('πŸ€– SAOLA ACCOUNT RESPONSE:'); console.log(response); console.log('\n'); // Small delay between questions await new Promise(resolve => setTimeout(resolve, 1000)); } console.log('βœ… All questions tested with saola account!'); } } async function main() { const baseURL = 'https://api.umbrellacost.io/api/v1'; const processor = new SaolaProcessor(baseURL); console.log('πŸ” Authenticating with david+saola@umbrellacost.com...'); const authenticated = await processor.authenticate(); if (!authenticated) { console.error('❌ Authentication failed'); return; } console.log('βœ… Authentication successful!\n'); await processor.testAllQuestions(); } main().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