#!/usr/bin/env node
const { spawn } = require('child_process');
const path = require('path');
console.log('🧪 Testing STDIO Mode Compatibility with Existing MCP Protocol...\n');
const tests = [
{
name: 'Initialize',
request: {
jsonrpc: '2.0',
method: 'initialize',
params: {
protocolVersion: '1.0.0',
capabilities: {},
clientInfo: {
name: 'test-client',
version: '1.0.0'
}
},
id: 1
},
expectedKeys: ['capabilities', 'serverInfo']
},
{
name: 'List Tools',
request: {
jsonrpc: '2.0',
method: 'tools/list',
params: {},
id: 2
},
expectedKeys: ['tools'],
validateTools: true
}
];
let currentTest = 0;
let allPassed = true;
// Start the server using the dual-transport entry point
const serverPath = path.resolve(__dirname, '../../dist/index-dual.js');
console.log(`Starting server: ${serverPath}\n`);
const proc = spawn('node', [serverPath], {
stdio: ['pipe', 'pipe', 'pipe']
});
// Collect all stdout data
let stdoutBuffer = '';
proc.stdout.on('data', (data) => {
stdoutBuffer += data.toString();
// Try to parse JSON responses
const lines = stdoutBuffer.split('\n');
for (let i = 0; i < lines.length - 1; i++) {
const line = lines[i].trim();
if (line.startsWith('{') && line.includes('jsonrpc')) {
try {
const response = JSON.parse(line);
handleResponse(response);
// Remove processed line from buffer
stdoutBuffer = lines.slice(i + 1).join('\n');
} catch (e) {
// Not valid JSON yet, keep buffering
}
}
}
});
// Log stderr for debugging
proc.stderr.on('data', (data) => {
// Only show errors, not info messages
const msg = data.toString();
if (!msg.includes('[STDIO]') && !msg.includes('[MAIN]')) {
console.error('STDERR:', msg);
}
});
function handleResponse(response) {
const test = tests[currentTest];
console.log(`📥 Response for "${test.name}":`);
if (response.error) {
console.log(` ❌ Error: ${response.error.message}`);
allPassed = false;
} else if (response.result) {
let passed = true;
// Check for expected keys
for (const key of test.expectedKeys) {
if (!(key in response.result)) {
console.log(` ❌ Missing expected key: ${key}`);
passed = false;
}
}
// Validate tools if needed
if (test.validateTools && response.result.tools) {
const tools = response.result.tools;
const expectedTools = [
'authenticate_user',
'logout',
'session_status',
'list_endpoints',
'help'
];
const toolNames = tools.map(t => t.name);
for (const expected of expectedTools) {
if (!toolNames.includes(expected)) {
console.log(` ❌ Missing expected tool: ${expected}`);
passed = false;
}
}
if (passed) {
console.log(` ✅ Found ${tools.length} tools including all core tools`);
}
} else if (passed) {
console.log(` ✅ Response has all expected fields`);
}
if (!passed) allPassed = false;
}
console.log();
// Send next test
currentTest++;
if (currentTest < tests.length) {
sendNextTest();
} else {
// All tests complete
console.log('═'.repeat(60));
if (allPassed) {
console.log('✅ All compatibility tests passed!');
console.log('The dual-transport server maintains full backward compatibility.');
} else {
console.log('❌ Some tests failed. Check the implementation.');
}
console.log('═'.repeat(60));
proc.kill();
process.exit(allPassed ? 0 : 1);
}
}
function sendNextTest() {
const test = tests[currentTest];
console.log(`📤 Sending test: "${test.name}"`);
const request = JSON.stringify(test.request) + '\n';
proc.stdin.write(request);
}
// Start tests after server initializes
setTimeout(() => {
console.log('Starting tests...\n');
console.log('═'.repeat(60));
sendNextTest();
}, 2000);
// Timeout protection
setTimeout(() => {
console.error('❌ Test timeout - server may not be responding');
proc.kill();
process.exit(1);
}, 10000);