#!/usr/bin/env npx tsx /** * Test the spawn options logic that was causing the "Invalid configuration" error */ function testSpawnOptionsLogic() { console.log('šŸ”§ Testing MCP Spawn Options Logic\n'); function buildSpawnOptions(serverConfig: any): { command: string; args: string[]; env: Record } { const env = process.env as Record; switch (serverConfig.type) { case 'custom': if (serverConfig.config.type === 'custom') { const command = serverConfig.config.command; const args = serverConfig.config.args || []; if (command === 'npx') { return { command: 'npx', args: args, env: { ...env, ...serverConfig.config.env }, }; } const isNpmPackage = command.startsWith('@') || (!command.includes('/') && !command.includes('\\')); if (isNpmPackage) { return { command: 'npx', args: [command, ...args], env: { ...env, ...serverConfig.config.env }, }; } return { command: command, args: args, env: { ...env, ...serverConfig.config.env }, }; } throw new Error(`Invalid custom server configuration`); default: throw new Error(`Unsupported server type: ${serverConfig.type}`); } } const testConfigs = [ { name: 'Wikipedia (npx with args)', type: 'custom', config: { type: 'custom', command: 'npx', args: ['-y', 'wikipedia-mcp'], env: {} } }, { name: 'QR Codes (npx with args)', type: 'custom', config: { type: 'custom', command: 'npx', args: ['-y', 'qr-codes-mcp'], env: {} } }, { name: 'Package name (needs npx)', type: 'custom', config: { type: 'custom', command: 'wikipedia-mcp', args: [], env: {} } }, { name: 'Scoped package (needs npx)', type: 'custom', config: { type: 'custom', command: '@modelcontextprotocol/server-filesystem', args: ['/path'], env: {} } }, { name: 'Absolute path executable', type: 'custom', config: { type: 'custom', command: '/usr/local/bin/my-mcp-server', args: ['--port', '3000'], env: {} } }, { name: 'Relative path executable', type: 'custom', config: { type: 'custom', command: './my-server', args: [], env: {} } } ]; console.log('šŸ“ Testing spawn options for various configurations:\n'); let passed = 0; let failed = 0; for (const config of testConfigs) { console.log(`šŸ“Œ ${config.name}`); console.log(` Input: command="${config.config.command}" args=${JSON.stringify(config.config.args)}`); try { const result = buildSpawnOptions(config); console.log(` āœ… Success: ${result.command} ${result.args.join(' ')}`); if (config.config.command === 'npx' && result.command !== 'npx') { console.log(` āš ļø Warning: Expected npx but got ${result.command}`); } if (config.config.command === 'npx' && JSON.stringify(result.args) !== JSON.stringify(config.config.args)) { console.log(` āš ļø Warning: Args mismatch. Expected ${JSON.stringify(config.config.args)} but got ${JSON.stringify(result.args)}`); } passed++; } catch (error) { console.log(` āŒ Failed: ${error instanceof Error ? error.message : error}`); failed++; } console.log(''); } console.log('šŸ“Š Results:'); console.log(` āœ… Passed: ${passed}/${testConfigs.length}`); console.log(` āŒ Failed: ${failed}/${testConfigs.length}`); if (failed === 0) { console.log('\nšŸŽ‰ All tests passed! The spawn options logic is working correctly.'); } else { console.log('\nāš ļø Some tests failed. The spawn options logic needs more fixes.'); } } testSpawnOptionsLogic();