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
#!/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);