#!/usr/bin/env node
// Detailed response analyzer to see actual API responses
const { spawn } = require('child_process');
const axios = require('axios');
class DetailedResponseAnalyzer {
constructor() {
this.rc5Process = null;
this.messageId = 1;
this.pendingRequests = new Map();
}
async startRC5() {
console.log('๐ Starting RC5...');
this.rc5Process = spawn('npx', ['tsx', 'src/index.ts'], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: '/tmp/release-candidate'
});
this.rc5Process.stdout.on('data', (data) => {
const lines = data.toString().split('\n').filter(line => line.trim());
lines.forEach(line => {
try {
const message = JSON.parse(line);
this.handleMessage(message);
} catch (e) {}
});
});
this.rc5Process.stderr.on('data', (data) => {
const output = data.toString();
if (output.includes('Umbrella MCP Server started successfully')) {
console.log('โ
RC5 ready');
}
});
await new Promise(resolve => setTimeout(resolve, 3000));
}
handleMessage(message) {
if (message.id && this.pendingRequests.has(message.id)) {
const resolve = this.pendingRequests.get(message.id);
this.pendingRequests.delete(message.id);
resolve(message);
}
}
async sendRC5Request(method, params) {
const id = this.messageId++;
const request = { jsonrpc: '2.0', id, method, params };
return new Promise((resolve, reject) => {
this.pendingRequests.set(id, resolve);
this.rc5Process.stdin.write(JSON.stringify(request) + '\n');
setTimeout(() => {
if (this.pendingRequests.has(id)) {
this.pendingRequests.delete(id);
reject(new Error('RC5 Timeout'));
}
}, 15000);
});
}
async sendCurrentRequest(toolName, args) {
try {
const loginResponse = await axios.post('http://localhost:3000/auth', {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
});
const token = loginResponse.data.bearerToken;
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
const result = await axios.post('http://localhost:3000/mcp', {
jsonrpc: '2.0',
id: 1,
method: 'tools/call',
params: {
name: toolName,
arguments: args
}
}, { headers });
return result.data;
} catch (error) {
return {
error: {
code: -1,
message: error.message,
details: error.response?.data
}
};
}
}
async initializeRC5() {
await this.sendRC5Request('initialize', {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'response-analyzer', version: '1.0.0' }
});
console.log('๐ Authenticating RC5...');
await this.sendRC5Request('tools/call', {
name: 'authenticate_user',
arguments: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
}
});
console.log('โ
RC5 authenticated');
}
async analyzeSpecificEndpoint(rc5Tool, currentTool, args, description) {
console.log(`\n${'โ'.repeat(80)}`);
console.log(`๐ ANALYZING: ${description}`);
console.log(`${'โ'.repeat(80)}`);
console.log(`RC5 Tool: ${rc5Tool}`);
console.log(`Current Tool: ${currentTool}`);
console.log(`Args: ${JSON.stringify(args, null, 2)}`);
// Test RC5
console.log(`\n๐ต RC5 RESPONSE:`);
console.log('โ'.repeat(50));
try {
const rc5Result = await this.sendRC5Request('tools/call', {
name: rc5Tool,
arguments: args
});
if (rc5Result.error) {
console.log(`โ Error: ${rc5Result.error.message}`);
} else {
const response = rc5Result.result?.content?.[0]?.text || JSON.stringify(rc5Result.result, null, 2);
console.log(response.substring(0, 1000) + (response.length > 1000 ? '...' : ''));
// Extract values
const dollarMatches = response.match(/\\$[\\d,]+\\.?\\d*/g);
if (dollarMatches) {
console.log(`๐ฐ Found values: ${dollarMatches.slice(0, 5).join(', ')}`);
}
}
} catch (error) {
console.log(`โ RC5 Error: ${error.message}`);
}
// Test Current Server
console.log(`\n๐ข CURRENT SERVER RESPONSE:`);
console.log('โ'.repeat(50));
try {
const currentResult = await this.sendCurrentRequest(currentTool, args);
if (currentResult.error) {
console.log(`โ Error: ${currentResult.error.message}`);
} else {
const response = currentResult.result?.content?.[0]?.text || JSON.stringify(currentResult.result, null, 2);
console.log(response.substring(0, 1000) + (response.length > 1000 ? '...' : ''));
// Extract values
const dollarMatches = response.match(/\\$[\\d,]+\\.?\\d*/g);
if (dollarMatches) {
console.log(`๐ฐ Found values: ${dollarMatches.slice(0, 5).join(', ')}`);
}
}
} catch (error) {
console.log(`โ Current Server Error: ${error.message}`);
}
}
async runDetailedAnalysis() {
console.log('๐ DETAILED ENDPOINT RESPONSE ANALYSIS');
console.log('โ'.repeat(80));
await this.startRC5();
await this.initializeRC5();
// Test specific endpoint mappings to understand the differences
const testCases = [
{
rc5Tool: 'api___invoices_caui',
currentTool: 'get_costs',
args: {
startDate: '2025-08-01',
endDate: '2025-08-31',
accountId: '932213950603',
groupBy: 'none',
periodGranLevel: 'day'
},
description: 'AWS Total Costs for August 2025'
},
{
rc5Tool: 'api___invoices_caui',
currentTool: 'get_costs',
args: {
startDate: '2025-07-01',
endDate: '2025-08-31',
accountId: '932213950603',
groupBy: 'none',
periodGranLevel: 'month'
},
description: 'AWS Monthly Costs (July-August 2025)'
},
{
rc5Tool: 'api___user_management_accounts',
currentTool: 'get_accounts',
args: {},
description: 'All Available Accounts'
},
{
rc5Tool: 'api___recommendationsNew_heatmap_summary',
currentTool: 'get_recommendations',
args: { accountId: '932213950603' },
description: 'Cost Optimization Recommendations'
},
{
rc5Tool: 'api___msp_customers',
currentTool: 'get_accounts', // Try with current equivalent
args: {},
description: 'MSP Customer List'
}
];
for (const testCase of testCases) {
await this.analyzeSpecificEndpoint(
testCase.rc5Tool,
testCase.currentTool,
testCase.args,
testCase.description
);
// Small delay between tests
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
async disconnect() {
if (this.rc5Process) {
this.rc5Process.kill();
}
}
}
async function runDetailedAnalysis() {
const analyzer = new DetailedResponseAnalyzer();
try {
await analyzer.runDetailedAnalysis();
} catch (error) {
console.error('โ Analysis failed:', error.message);
} finally {
await analyzer.disconnect();
}
}
runDetailedAnalysis();