#!/usr/bin/env node
// Check what parameters RC5 sends to the API
const { spawn } = require('child_process');
class RC5ParameterChecker {
constructor() {
this.serverProcess = null;
this.messageId = 1;
this.pendingRequests = new Map();
this.capturedLogs = [];
}
async startRC5() {
console.log('🚀 Starting RC5...');
this.serverProcess = spawn('npx', ['tsx', 'src/index.ts'], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: '/tmp/release-candidate'
});
this.serverProcess.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.serverProcess.stderr.on('data', (data) => {
const output = data.toString();
// Capture API request logs
if (output.includes('API REQUEST:') ||
output.includes('URL:') ||
output.includes('accountId') ||
output.includes('Headers:')) {
this.capturedLogs.push(output);
}
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 sendRequest(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.serverProcess.stdin.write(JSON.stringify(request) + '\n');
setTimeout(() => {
if (this.pendingRequests.has(id)) {
this.pendingRequests.delete(id);
reject(new Error('Timeout'));
}
}, 15000);
});
}
async initialize() {
await this.sendRequest('initialize', {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'parameter-checker', version: '1.0.0' }
});
}
async authenticate() {
console.log('🔐 Authenticating RC5...');
await this.sendRequest('tools/call', {
name: 'authenticate_user',
arguments: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
}
});
console.log('✅ RC5 authenticated');
}
async testAWSCost() {
console.log('\n📊 Testing RC5 AWS cost request...');
// Clear logs before test
this.capturedLogs = [];
const result = await this.sendRequest('tools/call', {
name: 'api___invoices_caui',
arguments: {
startDate: '2025-08-01',
endDate: '2025-08-31',
groupBy: 'none',
periodGranLevel: 'month',
costType: ['cost', 'discount'],
cloud_context: 'aws'
}
});
// Wait a bit for logs to be captured
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('\n🔍 CAPTURED API REQUEST DETAILS:');
console.log('─'.repeat(50));
this.capturedLogs.forEach(log => {
if (log.includes('URL:') || log.includes('Headers:') || log.includes('accountId')) {
console.log(log.trim());
}
});
const response = result.result?.content?.[0]?.text || '';
const jsonMatch = response.match(/```json\s*\n([\s\S]*?)\n```/);
if (jsonMatch) {
const data = JSON.parse(jsonMatch[1]);
let totalCost = 0;
if (Array.isArray(data)) {
data.forEach(item => totalCost += parseFloat(item.total_cost || 0));
} else {
totalCost = parseFloat(data.total_cost || 0);
}
console.log(`\n💰 RC5 Result: $${totalCost.toLocaleString()}`);
return totalCost;
}
return 0;
}
async disconnect() {
if (this.serverProcess) {
this.serverProcess.kill();
}
}
}
async function checkRC5Parameters() {
const checker = new RC5ParameterChecker();
try {
console.log('🔍 CHECKING RC5 API REQUEST PARAMETERS');
console.log('═'.repeat(50));
await checker.startRC5();
await checker.initialize();
await checker.authenticate();
await checker.testAWSCost();
} catch (error) {
console.error('❌ Check failed:', error.message);
} finally {
await checker.disconnect();
}
}
checkRC5Parameters();