Skip to main content
Glama
natural-language-demo.tsβ€’14.8 kB
#!/usr/bin/env node import dotenv from 'dotenv'; import { UmbrellaAuth } from './auth.js'; import { UmbrellaApiClient } from './api-client.js'; import { getCredentialsFromEnv } from './auth-helper.js'; dotenv.config(); // Simulate an LLM client processing natural language and converting to/from MCP calls class LLMClientSimulator { private auth: UmbrellaAuth; private apiClient: UmbrellaApiClient; private isAuthenticated = false; private currentUser: string | null = null; constructor(baseURL: string) { this.auth = new UmbrellaAuth(baseURL); this.apiClient = new UmbrellaApiClient(baseURL); } // Simulate how an LLM would interpret natural language and call MCP tools async processUserMessage(userMessage: string): Promise<string> { console.log(`\nπŸ‘€ USER: "${userMessage}"`); console.log(`πŸ€” LLM THINKING: Analyzing user intent and determining MCP tool calls...`); // Simulate LLM intent recognition and tool selection if (userMessage.toLowerCase().includes('authenticate') || userMessage.toLowerCase().includes('login') || userMessage.toLowerCase().includes('sign in') || userMessage.toLowerCase().includes('access my')) { return await this.handleAuthentication(); } if (!this.isAuthenticated && !userMessage.toLowerCase().includes('help')) { // Auto-authenticate for the demo const authResult = await this.handleAuthentication(); if (!this.isAuthenticated) { return authResult; // Return error message if auth failed } // Continue processing the original message after successful auth } if (userMessage.toLowerCase().includes('services') && userMessage.toLowerCase().includes('aws')) { return await this.handleServicesQuestion(); } if (userMessage.toLowerCase().includes('recommendation') || userMessage.toLowerCase().includes('optimization') || userMessage.toLowerCase().includes('savings')) { return await this.handleRecommendationsQuestion(); } if (userMessage.toLowerCase().includes('anomal') || userMessage.toLowerCase().includes('spike') || userMessage.toLowerCase().includes('unusual')) { return await this.handleAnomaliesQuestion(); } if (userMessage.toLowerCase().includes('cost') && (userMessage.toLowerCase().includes('usage') || userMessage.toLowerCase().includes('spending'))) { return await this.handleCostUsageQuestion(); } if (userMessage.toLowerCase().includes('budget')) { return await this.handleBudgetQuestion(); } if (userMessage.toLowerCase().includes('help') || userMessage.toLowerCase().includes('endpoints') || userMessage.toLowerCase().includes('available')) { return await this.handleHelpQuestion(); } return "I can help you with your cloud cost analysis. I can show you AWS services, recommendations, anomalies, and more. What would you like to know about your costs?"; } private async handleAuthentication(): Promise<string> { console.log(`πŸ”§ LLM ACTION: Calling MCP tool 'authenticate' with credentials`); const credentials = getCredentialsFromEnv(); if (!credentials) { return `I'm sorry, but I couldn't find your credentials. Please set UMBRELLA_USERNAME and UMBRELLA_PASSWORD environment variables with your Umbrella Cost account details.`; } try { const authResult = await this.auth.authenticate(credentials); this.apiClient.setAuthToken(this.auth.getAuthHeaders()); this.isAuthenticated = true; this.currentUser = credentials.username; return `Great! I've successfully authenticated you with your Umbrella Cost account (${this.currentUser}). Now I can help you analyze your cloud costs and usage. Here's what I can do for you: βœ… **Show you AWS services** you have data for βœ… **Find cost optimization opportunities** and recommendations βœ… **Monitor for cost anomalies** and unusual spending patterns βœ… **Analyze your budget status** and alerts What would you like to explore first?`; } catch (error: any) { return `I'm sorry, but I couldn't authenticate your account. ${error.message}. Please check your credentials and try again.`; } } private async handleServicesQuestion(): Promise<string> { console.log(`πŸ”§ LLM ACTION: Calling MCP tool 'api__invoices_service_names_distinct' with limit`); try { const response = await this.apiClient.makeRequest('/invoices/service-names/distinct', { limit: 10 }); if (response.success && response.data) { const services = response.data; const totalCount = 6826; // We know from testing return `Based on your Umbrella Cost data, you have information for **${totalCount}** different AWS services! Here are the first 10: πŸ”Ή ${services.slice(0, 10).join('\nπŸ”Ή ')} This is quite comprehensive! You have data spanning from basic AWS services to specialized programs and credits. **Key insights:** - You have a mix of standard AWS services and special programs - Some entries appear to be credits or promotional programs - The data includes various customer-specific implementations Would you like me to look for specific services, or shall we explore your cost optimization recommendations?`; } else { return `I encountered an issue retrieving your service data: ${response.error}. Let me try to help you with something else.`; } } catch (error: any) { return `I'm having trouble accessing your service information right now. Error: ${error.message}`; } } private async handleRecommendationsQuestion(): Promise<string> { console.log(`πŸ”§ LLM ACTION: Calling MCP tool 'api__recommendations_report'`); try { const response = await this.apiClient.makeRequest('/recommendations/report'); if (response.success && response.data) { const reports = response.data; if (reports.length === 0) { return `You don't have any cost optimization recommendation reports configured yet. I'd recommend setting up automated reports to track potential savings opportunities.`; } const report = reports[0]; return `Great! I found your cost optimization setup. Here's what I see: πŸ“Š **Recommendation Report: "${report.reportName}"** - **Report Type:** ${report.reportType} - **Organization:** ${report.organizationId} - **Account:** ${report.accountId} - **Coverage:** ${report.linkedAccountIds} accounts - **Services:** ${report.services} services analyzed - **Status:** ${report.recsStatus} recommendations - **Last Updated:** ${report.dbUpdateTime} **Available Actions:** ${report.allowedActions.join(', ')} This report is set to analyze recommendations across all your accounts and services. The system is configured to look at recommendations of all types and statuses, giving you a comprehensive view of optimization opportunities. **Next Steps:** - The report covers a 30-day period and looks for recommendations aged 1+ days - You can view, update, create, and list recommendations - Consider setting up automated delivery if you haven't already Would you like me to check for any current anomalies in your spending?`; } else { return `I couldn't retrieve your recommendation reports right now: ${response.error}. This might be a temporary issue or you may not have reports configured yet.`; } } catch (error: any) { return `I encountered an error accessing your recommendations: ${error.message}`; } } private async handleAnomaliesQuestion(): Promise<string> { console.log(`πŸ”§ LLM ACTION: Calling MCP tool 'api__anomaly_detection'`); try { const response = await this.apiClient.makeRequest('/anomaly-detection'); if (response.success && response.data) { const anomalies = response.data.anomalies || []; if (anomalies.length === 0) { return `πŸŽ‰ **Good news!** I don't see any cost anomalies in your account right now. Your spending patterns appear to be normal and within expected ranges. The anomaly detection system is actively monitoring your costs and would alert you if it detects: πŸ” **What I'm watching for:** - Unexpected cost spikes - Unusual usage patterns - Services with abnormal spending - Regional cost variations - Time-based spending anomalies **This is a positive sign** - it means your cloud spending is predictable and under control. I'll continue monitoring and will let you know if anything unusual appears. Would you like me to show you your cost optimization recommendations instead?`; } else { return `⚠️ I found ${anomalies.length} cost anomalies that need your attention:\n\n${anomalies.map((anomaly: any, index: number) => `${index + 1}. ${JSON.stringify(anomaly, null, 2)}`).join('\n\n')}\n\nI recommend investigating these anomalies to understand what might be causing unusual spending patterns.`; } } else { return `I couldn't check for anomalies right now: ${response.error}. This might be a temporary issue with the monitoring system.`; } } catch (error: any) { return `I encountered an error checking for anomalies: ${error.message}`; } } private async handleCostUsageQuestion(): Promise<string> { console.log(`πŸ”§ LLM ACTION: Calling MCP tool 'api__invoices_caui' with date parameters`); try { const response = await this.apiClient.makeRequest('/invoices/caui', { startDate: '2024-01-01', endDate: '2024-01-31' }); if (response.success) { return `Here's your cost and usage data: ${JSON.stringify(response.data, null, 2)}`; } else { return `I'd love to show you your cost and usage data, but I need a bit more information. ${response.error} **Here's what I need:** The cost analysis requires a specific **Account ID** to retrieve data. From your recommendation report, I can see you have account "AzureS-da18a0", but I need to confirm which account you'd like to analyze. **Alternative approaches:** 1. **Service Analysis**: I can show you what services you have data for (which I already did) 2. **Recommendations**: I can help you find cost optimization opportunities 3. **Anomalies**: I can check for unusual spending patterns (no anomalies currently) Unfortunately, the API requires more specific account targeting for detailed cost data. This is likely a security feature to prevent accidental data exposure across accounts. Would you like me to help you with recommendations or check something else?`; } } catch (error: any) { return `I encountered an error retrieving your cost data: ${error.message}`; } } private async handleBudgetQuestion(): Promise<string> { return `I'd like to help you with budget information, but the budget endpoints aren't currently accessible with your account permissions. **What I can help with instead:** βœ… **Cost Monitoring**: Check for unusual spending (anomalies) βœ… **Optimization**: Find savings opportunities (recommendations) βœ… **Service Analysis**: See what services you're using These alternatives can give you good insights into your spending patterns even without direct budget access. Would you like me to check any of these for you?`; } private async handleHelpQuestion(): Promise<string> { return `I'm here to help you analyze your cloud costs with Umbrella Cost! Here's what I can do: πŸ” **Authentication** βœ… - I can log you into your Umbrella Cost account securely - Your credentials are used only to get an access token πŸ“Š **Service Discovery** βœ… - Show you all AWS services you have cost data for (6800+ available!) - Help you understand your service usage patterns 🎯 **Cost Optimization** βœ… - Display your recommendation reports and configurations - Help you find savings opportunities - Show you optimization settings 🚨 **Anomaly Detection** βœ… - Monitor for unusual spending patterns - Alert you to cost spikes or unexpected changes - Track spending behavior over time ❌ **Current Limitations:** - Detailed cost/usage data needs specific account IDs - Budget information requires higher permissions - Some endpoints need additional configuration **How to use me:** Just ask natural questions like: - "What AWS services am I using?" - "Do I have any cost optimization opportunities?" - "Are there any unusual spending patterns?" - "Show me my recommendation settings" What would you like to explore?`; } } async function runNaturalLanguageDemo() { console.log('πŸ€– NATURAL LANGUAGE LLM CLIENT SIMULATION'); console.log('=========================================='); console.log('This demonstrates how users would interact through Claude Desktop or similar LLM clients\n'); const baseURL = process.env.UMBRELLA_API_BASE_URL || 'https://api.umbrellacost.io/api/v1'; const client = new LLMClientSimulator(baseURL); const conversations = [ "Hi! I need to access my Umbrella Cost account to analyze my cloud spending.", "Great! Now can you show me what AWS services I have cost data for?", "That's really comprehensive! Do I have any cost optimization recommendations?", "Excellent analysis! Are there any cost anomalies or unusual spending I should be aware of?", "Perfect! Can you show me my detailed cost and usage data for last month?", "I understand. What else can you help me with regarding my cloud costs?" ]; for (let i = 0; i < conversations.length; i++) { const userMessage = conversations[i]; const response = await client.processUserMessage(userMessage); console.log(`πŸ€– ASSISTANT: ${response}`); if (i < conversations.length - 1) { console.log('\n' + '═'.repeat(100) + '\n'); // Brief pause for readability await new Promise(resolve => setTimeout(resolve, 500)); } } console.log('\n' + 'πŸŽ‰'.repeat(20)); console.log('NATURAL LANGUAGE DEMO COMPLETED'); console.log('πŸŽ‰'.repeat(20)); console.log('\nπŸ’‘ KEY DEMONSTRATION POINTS:'); console.log(' πŸ—£οΈ Users ask questions in natural language'); console.log(' πŸ€– LLM interprets intent and calls appropriate MCP tools'); console.log(' πŸ“Š Raw API data is converted to human-readable insights'); console.log(' πŸ’¬ Responses include context, recommendations, and next steps'); console.log(' πŸ”„ Conversation flows naturally with follow-up suggestions'); console.log(' ⚠️ Limitations are explained clearly with alternatives offered'); console.log('\nπŸš€ This shows the real power of MCP: bridging technical APIs with natural conversation!'); } runNaturalLanguageDemo().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