#!/usr/bin/env node
const https = require('https');
const axios = require('axios');
// Create axios instance that ignores SSL certificate errors
const axiosInstance = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false
})
});
// Expected values from MANUAL_ANSWERS.txt
const EXPECTED = {
bankLeumi: {
august2025: 0.0026837670123269763,
accountId: '696314371547',
customerKey: '22676',
divisionId: '139'
},
saola: {
costs: {
'2025-03': 104755.07,
'2025-04': 111340.42,
'2025-05': 149774.24,
'2025-06': 165666.57,
'2025-07': 183920.58
},
accountId: '932213950603'
}
};
async function testBankLeumiComplete() {
console.log('\n' + '═'.repeat(80));
console.log(' 🏦 BANK LEUMI TEST RESULTS');
console.log('═'.repeat(80));
const baseUrl = 'https://api.umbrellacost.io/api/v1';
try {
// Step 1: Authenticate
console.log('\n📌 AUTHENTICATION:');
console.log(' User: david+allcloud@umbrellacost.com (MSP Customer)');
const authResponse = await axiosInstance.post(`${baseUrl}/users/signin`, {
username: 'david+allcloud@umbrellacost.com',
password: 'Dsamsung1!123'
});
const token = authResponse.data.jwtToken;
const tokenPayload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
const userKey = tokenPayload.username || tokenPayload['custom:username'] || tokenPayload.sub;
console.log(' ✅ Authentication successful');
console.log(` User Key: ${userKey}`);
// Step 2: Get Bank Leumi August 2025 costs
console.log('\n📊 QUERYING COSTS:');
console.log(' Customer: Bank Leumi Reseller-1');
console.log(' Period: August 2025');
console.log(' Customer Key: 22676, Division: 139');
// Build proper API key for Bank Leumi
const apiKey = `${userKey}:22676:139`;
const params = new URLSearchParams({
startDate: '2025-08-01',
endDate: '2025-08-31',
periodGranLevel: 'month',
groupBy: 'none',
'costType': 'cost',
'excludeFilters[chargetype]': 'Tax'
});
const response = await axiosInstance.get(`${baseUrl}/invoices/caui?${params}`, {
headers: {
'Authorization': token,
'apikey': apiKey
}
});
console.log('\n🎯 RESULTS:');
if (response.data && response.data.length > 0) {
const data = response.data[0];
console.log(' ┌─────────────────────────────────────────┐');
console.log(' │ ACTUAL vs EXPECTED │');
console.log(' ├─────────────────────────────────────────┤');
console.log(` │ Account ID: │`);
console.log(` │ Actual: ${data.account_id} │`);
console.log(` │ Expected: ${EXPECTED.bankLeumi.accountId} │`);
console.log(` │ Status: ${data.account_id === EXPECTED.bankLeumi.accountId ? '✅ MATCH' : '❌ MISMATCH'} │`);
console.log(' ├─────────────────────────────────────────┤');
console.log(` │ Total Cost: │`);
console.log(` │ Actual: $${data.total_cost.toFixed(10)} │`);
console.log(` │ Expected: $${EXPECTED.bankLeumi.august2025.toFixed(10)} │`);
const costDiff = Math.abs(data.total_cost - EXPECTED.bankLeumi.august2025);
console.log(` │ Status: ${costDiff < 0.0001 ? '✅ MATCH' : '❌ MISMATCH'} │`);
console.log(' └─────────────────────────────────────────┘');
if (data.account_id === EXPECTED.bankLeumi.accountId && costDiff < 0.0001) {
console.log('\n 🎉 ✅ BANK LEUMI TEST PASSED! ✅ 🎉');
} else {
console.log('\n ⚠️ ❌ BANK LEUMI TEST FAILED ❌ ⚠️');
}
} else {
console.log(' ❌ No data returned for Bank Leumi');
}
} catch (error) {
console.error('\n❌ Bank Leumi Test Error:', error.response?.data || error.message);
}
}
async function testSaolaComplete() {
console.log('\n\n' + '═'.repeat(80));
console.log(' 🌟 SAOLA TEST RESULTS');
console.log('═'.repeat(80));
const baseUrl = 'https://api.umbrellacost.io/api/v1';
try {
// Step 1: Authenticate
console.log('\n📌 AUTHENTICATION:');
console.log(' User: david+saola@umbrellacost.com (Direct Customer)');
const authResponse = await axiosInstance.post(`${baseUrl}/users/signin`, {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
});
const token = authResponse.data.jwtToken;
const tokenPayload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
const userKey = tokenPayload.username || tokenPayload['custom:username'] || tokenPayload.sub;
console.log(' ✅ Authentication successful');
console.log(` User Key: ${userKey}`);
// Get user's accounts to find SAOLA
const userResponse = await axiosInstance.get(`${baseUrl}/users`, {
headers: { 'Authorization': token }
});
const saolaAccount = userResponse.data.accounts?.find(acc =>
acc.accountKey === '9350' || acc.accountKey === 9350
);
const accountKey = saolaAccount?.accountKey || '9350';
const apiKey = `${userKey}:${accountKey}:0`;
// Step 2: Get SAOLA March-July 2025 costs
console.log('\n📊 QUERYING COSTS:');
console.log(' Customer: SAOLA');
console.log(' Period: March - July 2025');
const params = new URLSearchParams({
startDate: '2025-03-01',
endDate: '2025-07-31',
periodGranLevel: 'month',
groupBy: 'usagedate',
'costType': 'cost'
});
const response = await axiosInstance.get(`${baseUrl}/invoices/caui?${params}`, {
headers: {
'Authorization': token,
'apikey': apiKey
}
});
console.log('\n🎯 RESULTS:');
if (response.data && response.data.length > 0) {
console.log(' ┌─────────────────────────────────────────────┐');
console.log(' │ MONTHLY COSTS COMPARISON │');
console.log(' ├─────────────────────────────────────────────┤');
let allMatch = true;
const months = ['2025-03', '2025-04', '2025-05', '2025-06', '2025-07'];
const monthNames = ['March', 'April', 'May', 'June', 'July'];
months.forEach((month, i) => {
const actual = response.data.find(d => d.usage_date === month);
const expected = EXPECTED.saola.costs[month];
if (actual) {
const match = Math.abs(actual.total_cost - expected) < 1;
if (!match) allMatch = false;
console.log(` │ ${monthNames[i].padEnd(10)} 2025: │`);
console.log(` │ Actual: $${actual.total_cost.toFixed(2).padEnd(12)} │`);
console.log(` │ Expected: $${expected.toFixed(2).padEnd(12)} │`);
console.log(` │ Status: ${match ? '✅ MATCH' : '❌ MISMATCH'} │`);
if (i < months.length - 1) {
console.log(' ├─────────────────────────────────────────────┤');
}
}
});
console.log(' └─────────────────────────────────────────────┘');
// Check account ID
const accountId = response.data[0]?.account_id;
console.log(`\n Account ID: ${accountId}`);
console.log(` Expected: ${EXPECTED.saola.accountId}`);
console.log(` Status: ${accountId === EXPECTED.saola.accountId ? '✅ MATCH' : '❌ MISMATCH'}`);
if (allMatch && accountId === EXPECTED.saola.accountId) {
console.log('\n 🎉 ✅ SAOLA TEST PASSED! ✅ 🎉');
} else {
console.log('\n ⚠️ ❌ SAOLA TEST FAILED ❌ ⚠️');
}
} else {
console.log(' ❌ No data returned for SAOLA');
}
} catch (error) {
console.error('\n❌ SAOLA Test Error:', error.response?.data || error.message);
}
}
async function showSummary() {
console.log('\n\n' + '═'.repeat(80));
console.log(' 📋 TEST EXECUTION SUMMARY');
console.log('═'.repeat(80));
console.log('\n🔧 FIX APPLIED:');
console.log(' ✅ Removed hardcoded account 9350 from authentication');
console.log(' ✅ Dynamic customer detection enabled');
console.log(' ✅ MSP customers can query sub-customers');
console.log('\n🌐 SERVER STATUS:');
console.log(' OAuth MCP Server: https://gonna-opens-glossary-presence.trycloudflare.com');
console.log(' MCP Endpoint: https://gonna-opens-glossary-presence.trycloudflare.com/mcp');
console.log('\n📝 NEXT STEPS:');
console.log(' 1. Connect Claude Desktop to the MCP endpoint');
console.log(' 2. Authenticate with the OAuth flow');
console.log(' 3. Test queries like "Show me Bank Leumi costs for August 2025"');
console.log(' 4. Verify dynamic customer detection works');
console.log('\n' + '═'.repeat(80));
}
async function main() {
console.clear();
console.log('🚀 UMBRELLA MCP - FULL TEST RESULTS');
console.log('Time:', new Date().toISOString());
await testBankLeumiComplete();
await testSaolaComplete();
await showSummary();
}
main().catch(console.error);