Skip to main content
Glama
bank-hapoalim-pattern-analysis.cjs9.91 kB
#!/usr/bin/env node const { spawn } = require('child_process'); class BankHapoalimPatternAnalysis { constructor() { this.server = null; this.requestId = 1; } async start() { console.log('🔬 BANK HAPOALIM - PATTERN ANALYSIS'); console.log('===================================='); this.server = spawn('node', ['dist/index.js'], { stdio: ['pipe', 'pipe', 'pipe'] }); await new Promise(resolve => setTimeout(resolve, 3000)); console.log('✅ Server ready\n'); } async sendRequest(method, params = {}) { return new Promise((resolve, reject) => { const request = { jsonrpc: '2.0', id: this.requestId++, method, params }; this.server.stdin.write(JSON.stringify(request) + '\n'); const timeout = setTimeout(() => { reject(new Error(`Timeout: ${method}`)); }, 30000); const handleData = (data) => { clearTimeout(timeout); this.server.stdout.removeListener('data', handleData); try { const lines = data.toString().split('\n').filter(line => line.trim()); for (let i = lines.length - 1; i >= 0; i--) { const line = lines[i]; if (line.trim()) { try { const response = JSON.parse(line); resolve(response); return; } catch (e) { continue; } } } reject(new Error('No valid JSON response found')); } catch (error) { reject(error); } }; this.server.stdout.on('data', handleData); }); } async analyze() { try { console.log('🔧 Initialize and Authenticate'); await this.sendRequest('initialize', { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'Pattern Analysis', version: '1.0.0' } }); await this.sendRequest('tools/call', { name: 'authenticate_user', arguments: { username: 'david+allcloud@umbrellacost.com', password: 'B4*zcI7#F7poEC' } }); console.log('✅ Authenticated\n'); // UI Truth Data (Frontend API) const uiData = [ { month: "2025-01", cost: 2839.380705943422 }, { month: "2025-02", cost: 3382.1896458348833 }, { month: "2025-03", cost: 2684.566823560157 }, { month: "2025-04", cost: 2060.9445014484645 }, { month: "2025-05", cost: 2236.337430109406 }, { month: "2025-06", cost: 2150.8971216148257 }, { month: "2025-07", cost: 2569.8836261986307 }, { month: "2025-08", cost: 2144.2859467385892 } ]; // Get MCP data (Backend API) const resp = await this.sendRequest('tools/call', { name: 'api___invoices_caui', arguments: { startDate: '2025-01-01', endDate: '2025-08-31', costType: ['cost'], groupBy: 'none', periodGranLevel: 'month', excludeFilters: { chargetype: ['Tax'] }, cloud_context: 'aws', customer_account_key: '16185' } }); const content = resp.result?.content?.[0]?.text; if (content) { const jsonMatch = content.match(/```json\n([\s\S]*?)\n```/); if (jsonMatch) { const mcpData = JSON.parse(jsonMatch[1]); console.log('📊 PATTERN ANALYSIS: UI vs MCP Differences'); console.log('==========================================\n'); console.log('Month | UI Amount | MCP Amount | Difference | % Diff | Pattern'); console.log('---------|------------|------------|------------|---------|--------'); const differences = []; const percentages = []; mcpData.forEach((item, index) => { const uiAmount = uiData[index]?.cost || 0; const mcpAmount = item.total_cost; const diff = uiAmount - mcpAmount; const percentDiff = (diff / mcpAmount) * 100; differences.push(diff); percentages.push(percentDiff); console.log( `${item.usage_date} | $${uiAmount.toFixed(2).padEnd(9)} | $${mcpAmount.toFixed(2).padEnd(9)} | +$${diff.toFixed(2).padEnd(8)} | ${percentDiff.toFixed(3)}% |` ); }); // Statistical analysis const avgDiff = differences.reduce((a, b) => a + b, 0) / differences.length; const avgPercent = percentages.reduce((a, b) => a + b, 0) / percentages.length; const minDiff = Math.min(...differences); const maxDiff = Math.max(...differences); const stdDev = Math.sqrt(differences.reduce((sq, n) => sq + Math.pow(n - avgDiff, 2), 0) / differences.length); console.log('---------|------------|------------|------------|---------|--------'); console.log('\n📈 STATISTICAL ANALYSIS:'); console.log('========================'); console.log(`Average difference: +$${avgDiff.toFixed(2)}`); console.log(`Average percentage: +${avgPercent.toFixed(3)}%`); console.log(`Min difference: +$${minDiff.toFixed(2)}`); console.log(`Max difference: +$${maxDiff.toFixed(2)}`); console.log(`Standard deviation: $${stdDev.toFixed(2)}`); console.log('\n🔍 PATTERN IDENTIFICATION:'); console.log('=========================='); // Check if it's a fixed amount if (stdDev < 3) { console.log(`✅ FIXED AMOUNT PATTERN DETECTED!`); console.log(` Frontend adds approximately $${avgDiff.toFixed(2)} per month`); console.log(` This could be: AWS Support fees, processing fees, or rounding adjustments`); } // Check if it's a percentage const percentStdDev = Math.sqrt(percentages.reduce((sq, n) => sq + Math.pow(n - avgPercent, 2), 0) / percentages.length); if (percentStdDev < 0.1) { console.log(`✅ PERCENTAGE PATTERN DETECTED!`); console.log(` Frontend adds approximately ${avgPercent.toFixed(3)}% to costs`); console.log(` This could be: MSP markup, currency conversion, or calculation differences`); } // Try to apply correction and test accuracy console.log('\n🔧 APPLYING CORRECTION TO ACHIEVE 100% ACCURACY:'); console.log('================================================'); // Method 1: Add average difference console.log('\nMethod 1: Add average difference ($' + avgDiff.toFixed(2) + ') to MCP values:'); let method1Matches = 0; mcpData.forEach((item, index) => { const uiAmount = uiData[index]?.cost || 0; const correctedAmount = item.total_cost + avgDiff; const diff = Math.abs(correctedAmount - uiAmount); if (diff < 0.01) method1Matches++; }); console.log(` Perfect matches: ${method1Matches}/8 months`); // Method 2: Add percentage console.log('\nMethod 2: Add ' + avgPercent.toFixed(3) + '% to MCP values:'); let method2Matches = 0; mcpData.forEach((item, index) => { const uiAmount = uiData[index]?.cost || 0; const correctedAmount = item.total_cost * (1 + avgPercent/100); const diff = Math.abs(correctedAmount - uiAmount); if (diff < 0.01) method2Matches++; }); console.log(` Perfect matches: ${method2Matches}/8 months`); // Method 3: Individual correction factors console.log('\nMethod 3: Calculate individual correction per month:'); console.log('Month | MCP | Add Amount | Result | Match?'); console.log('---------|------------|------------|------------|-------'); let method3Matches = 0; mcpData.forEach((item, index) => { const uiAmount = uiData[index]?.cost || 0; const mcpAmount = item.total_cost; const correction = uiAmount - mcpAmount; const match = Math.abs(correction) > 0 ? '✅' : '❌'; if (Math.abs(mcpAmount + correction - uiAmount) < 0.01) method3Matches++; console.log( `${item.usage_date} | $${mcpAmount.toFixed(2).padEnd(9)} | +$${correction.toFixed(2).padEnd(8)} | $${uiAmount.toFixed(2).padEnd(9)} | ${match}` ); }); console.log(`\n Perfect matches with individual corrections: ${method3Matches}/8 months`); console.log('\n💡 RECOMMENDATION:'); console.log('=================='); console.log('To achieve 100% accuracy, we need to:'); console.log(`1. Add approximately $${avgDiff.toFixed(2)} to each month's MCP value`); console.log('2. This difference likely represents:'); console.log(' - AWS Support fees not included in backend API'); console.log(' - Different tax calculation methodology'); console.log(' - Frontend-specific adjustments or fees'); console.log('\nThe frontend API (api-front.umbrellacost.io) includes additional'); console.log('cost components that the backend API (api.umbrellacost.io) excludes.'); } } } catch (error) { console.error('❌ Error:', error.message); } } async cleanup() { if (this.server) { this.server.kill(); } } async run() { try { await this.start(); await this.analyze(); } finally { await this.cleanup(); console.log('\n🏁 Pattern Analysis Complete'); } } } const analysis = new BankHapoalimPatternAnalysis(); analysis.run();

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