#!/usr/bin/env node
import dotenv from 'dotenv';
import { UmbrellaAuth } from './auth.js';
import { UmbrellaApiClient } from './api-client.js';
import { getTestCredentialSets } from './auth-helper.js';
dotenv.config();
// Simulate an LLM client processing natural language and converting to/from MCP calls
class FixedMSPQuestionsSimulator {
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);
}
async authenticate(credentials: { username: string; password: string }): Promise<boolean> {
try {
await this.auth.authenticate(credentials);
this.apiClient.setAuthToken(this.auth.getAuthHeaders());
this.isAuthenticated = true;
this.currentUser = credentials.username;
return true;
} catch (error) {
return false;
}
}
// MSP Customer question handler - FIXED VERSION
private async handleMSPCustomerQuestion(userMessage: string): Promise<string> {
console.log(`🔧 LLM ACTION: Calling MCP tool 'api__user_management_accounts' for MSP customer data`);
try {
const response = await this.apiClient.makeRequest('/user-management/accounts');
if (response.success && response.data) {
const customers = response.data;
if (userMessage.toLowerCase().includes('list') || userMessage.toLowerCase().includes('all')) {
return `👥 **MSP Customer Portfolio:**\n\nI found ${customers.length} customers in your MSP account:\n\n${customers.slice(0, 10).map((customer: any, index: number) => `${index + 1}. ${customer.accountName || customer.accountKey || `Customer ${index + 1}`} (ID: ${customer.accountId || customer.accountKey})`).join('\n')}\n\n${customers.length > 10 ? `...and ${customers.length - 10} more customers.\n\n` : ''}**MSP Overview:**\n- Total Customers: ${customers.length}\n- Account Type: MSP (Managed Service Provider)\n- Customer Management: Full access\n\nWould you like detailed information about a specific customer?`;
} else if (userMessage.toLowerCase().includes('top') || userMessage.toLowerCase().includes('largest')) {
return `👥 **Top MSP Customers:**\n\nAs an MSP, you manage ${customers.length} customer accounts. Here are your key customers:\n\n${customers.slice(0, 5).map((customer: any, index: number) => `${index + 1}. ${customer.accountName || customer.accountKey || `Customer ${index + 1}`}`).join('\n')}\n\n**MSP Capabilities:**\n- Customer cost analysis and reporting\n- Multi-tenant billing and rebilling\n- Customer-specific recommendations\n- Consolidated cost management\n\nWould you like to analyze costs for a specific customer?`;
} else {
return `👥 **MSP Customer Management:**\n\nI can see you have access to ${customers.length} customer accounts as an MSP partner. \n\n**Available Customer Operations:**\n- View all customer accounts\n- Analyze per-customer costs\n- Generate customer-specific reports\n- Manage billing and rebilling\n- Customer recommendation analysis\n\nWhich customer would you like me to analyze, or would you prefer an overview of all customers?`;
}
} else {
return `I attempted to retrieve your MSP customer data but encountered: ${response.error}\n\nThis could mean:\n- You have a direct account (not MSP)\n- Customer data requires additional permissions\n- The customer management system is temporarily unavailable\n\nI can still help with your own account analysis, recommendations, and cost optimization!`;
}
} catch (error: any) {
return `Error accessing MSP customer information: ${error.message}\n\nThis might indicate you have a direct account rather than an MSP account. I can still provide full cost analysis for your own cloud usage!`;
}
}
async processUserMessage(userMessage: string): Promise<string> {
console.log(`\n👤 USER: "${userMessage}"`);
console.log(`🤔 LLM THINKING: Analyzing user intent and determining MCP tool calls...`);
if (!this.isAuthenticated) {
return "I need to authenticate first before I can access your Umbrella Cost data.";
}
// MSP Customer questions
if (userMessage.toLowerCase().includes('customer') || userMessage.toLowerCase().includes('client') || userMessage.toLowerCase().includes('partner')) {
return await this.handleMSPCustomerQuestion(userMessage);
}
return "I can help you with your cloud cost analysis. Ask me about services, recommendations, costs by different groupings, budgets, or anomalies!";
}
}
async function testFixedMSPQuestions() {
console.log('🧪 TESTING FIXED MSP CUSTOMER QUESTIONS');
console.log('======================================');
const baseURL = process.env.UMBRELLA_API_BASE_URL || 'https://api.umbrellacost.io/api/v1';
const credentialSets = getTestCredentialSets();
if (!credentialSets || credentialSets.length === 0) {
console.error('❌ No test credentials available');
return;
}
// Use the MSP account (first credential set)
const mspCreds = credentialSets[0];
console.log(`\n🔍 Testing Fixed MSP Questions with Account: ${mspCreds.username}`);
console.log('='.repeat(70));
const client = new FixedMSPQuestionsSimulator(baseURL);
// Authenticate
const authSuccess = await client.authenticate(mspCreds);
if (!authSuccess) {
console.log(`❌ Authentication failed for ${mspCreds.username}`);
return;
}
console.log(`✅ Authentication successful for ${mspCreds.username}`);
const mspQuestions = [
"List all my customers",
"Show me my top customers by usage",
"Who are my largest clients?",
"Give me an overview of all customer accounts"
];
console.log('\n🧪 Testing MSP Customer Questions:');
console.log('-'.repeat(40));
let passedQuestions = 0;
for (let i = 0; i < mspQuestions.length; i++) {
const question = mspQuestions[i];
try {
console.log(`\n[${i + 1}/${mspQuestions.length}] Testing Question:`);
const response = await client.processUserMessage(question);
console.log(`🤖 ASSISTANT: ${response.substring(0, 300)}${response.length > 300 ? '...' : ''}`);
// Check if this is a successful MSP response (contains customer data)
if (response.includes('MSP Customer') && response.includes('customers in your MSP account') && !response.includes('encountered:')) {
console.log(`✅ SUCCESS - MSP customer data retrieved and formatted properly`);
passedQuestions++;
} else if (response.includes('MSP Customer') && response.includes('manage') && response.includes('customer accounts')) {
console.log(`✅ SUCCESS - MSP capabilities described properly`);
passedQuestions++;
} else {
console.log(`❌ FAILED - Unexpected response format`);
}
// Brief pause between questions
await new Promise(resolve => setTimeout(resolve, 200));
} catch (error: any) {
console.log(`❌ FAILED: ${error.message}`);
}
}
console.log(`\n📊 MSP Customer Questions Results: ${passedQuestions}/${mspQuestions.length} questions handled successfully`);
if (passedQuestions === mspQuestions.length) {
console.log('🎉 ALL MSP CUSTOMER QUESTIONS NOW WORKING CORRECTLY!');
console.log(' ✅ MSP accounts endpoint discovered and implemented');
console.log(' ✅ Natural language responses properly formatted');
console.log(' ✅ Customer data retrieved and displayed appropriately');
console.log(' ✅ Error handling graceful for non-MSP accounts');
} else {
console.log(`⚠️ ${mspQuestions.length - passedQuestions} questions still need attention`);
}
}
testFixedMSPQuestions().catch(console.error);