UNPKG

@robertdouglass/mcp-tester

Version:

Advanced testing framework for Model Context Protocol (MCP) servers with enhanced error handling, performance testing, and comprehensive tool validation

236 lines (211 loc) 6.39 kB
#!/usr/bin/env node const { MCPTestFrameworkAdvanced } = require('./mcp-test-framework-advanced'); /** * Example script showing how to test MCP servers with all transport types */ async function testAllTransports() { const framework = new MCPTestFrameworkAdvanced({ verbose: true, timeout: 30000, outputDir: './test-results' }); // Example 1: Test Toolbase server (stdio only) console.log('=== Testing Toolbase Server (stdio) ===\n'); const toolbaseConfig = { type: 'stdio', command: '/Users/robert/.toolbase/toolbase-runner', args: ['-p=proxy', '-f=/Users/robert/.toolbase/config.json', '-v=claudeCode', '-l=/Users/robert/Library/Logs/Toolbase/claudeCode-toolbase-proxy.log', '-t=49'] }; const toolbaseTests = { name: 'Toolbase MCP Server', testDiscovery: true, testStability: true, toolTests: [ { toolName: 'brave_search_brave_web_search', arguments: { query: 'MCP testing', count: 2 }, assertions: [ async (result) => { if (!result || !result.content) { throw new Error('No content returned'); } } ] } ] }; await framework.testServer(toolbaseConfig, toolbaseTests); // Example 2: Test multiple transports for a hypothetical server console.log('\n=== Testing Multi-Transport Server ===\n'); const multiTransportConfigs = [ { type: 'stdio', command: './example-server', args: ['--mode', 'stdio'] }, { type: 'sse', url: 'http://localhost:3000/mcp/sse', headers: { 'Authorization': 'Bearer test-token' } }, { type: 'streamableHttp', url: 'http://localhost:3000/mcp/streamable', headers: { 'Authorization': 'Bearer test-token' } } ]; const multiTransportTests = { name: 'Example MCP Server', testDiscovery: true, testStability: false, // Skip stability tests for this example transportTests: { sse: [ { name: 'SSE-specific test', fn: async (client) => { // Test SSE-specific functionality const tools = await client.listTools(); return { message: 'SSE transport working', toolCount: tools.tools.length }; } } ], streamableHttp: [ { name: 'StreamableHTTP-specific test', fn: async (client) => { // Test StreamableHTTP-specific functionality const tools = await client.listTools(); return { message: 'StreamableHTTP transport working', toolCount: tools.tools.length }; } } ] }, customTests: [ { name: 'Cross-transport compatibility', fn: async (client) => { // This test runs on all transports const tools = await client.listTools(); if (tools.tools.length === 0) { throw new Error('No tools available'); } return { success: true, toolCount: tools.tools.length }; } } ] }; // Test each transport configuration // Note: This will fail if the example servers aren't running try { await framework.testServerMultiTransport(multiTransportConfigs, multiTransportTests); } catch (error) { console.log('Multi-transport test skipped (servers not running):', error.message); } // Generate final report const report = await framework.generateReport(); framework.printSummary(report); return report; } // Example 3: Test a specific transport with custom configuration async function testSpecificTransport(type, config) { const framework = new MCPTestFrameworkAdvanced({ verbose: true, timeout: 30000 }); const tests = { name: `${type} Transport Test`, testDiscovery: true, customTests: [ { name: 'Transport Health Check', fn: async (client) => { const start = Date.now(); const tools = await client.listTools(); const latency = Date.now() - start; return { transport: type, connected: true, latency: latency + 'ms', capabilities: { tools: tools.tools.length > 0, resources: false, // Will be updated by discovery test prompts: false // Will be updated by discovery test } }; } } ] }; await framework.testServer(config, tests); const report = await framework.generateReport(); framework.printSummary(report); return report; } // Export functions for use by other scripts module.exports = { testAllTransports, testSpecificTransport }; // Run tests if called directly if (require.main === module) { const args = process.argv.slice(2); if (args.length > 0 && args[0] === '--transport') { // Test specific transport if (args.length < 3) { console.log('Usage: test-all-transports --transport <type> <url-or-command> [options...]'); process.exit(1); } const type = args[1]; let config = { type }; if (type === 'stdio') { config.command = args[2]; config.args = args.slice(3); } else if (type === 'sse' || type === 'streamableHttp') { config.url = args[2]; config.headers = {}; // Parse additional options for (let i = 3; i < args.length; i += 2) { if (args[i] === '--header' && i + 1 < args.length) { const [key, ...valueParts] = args[i + 1].split(':'); config.headers[key.trim()] = valueParts.join(':').trim(); } else if (args[i] === '--auth' && i + 1 < args.length) { config.auth = args[i + 1]; } } } testSpecificTransport(type, config) .then(report => { process.exit(report.summary.failed > 0 ? 1 : 0); }) .catch(error => { console.error('Test failed:', error); process.exit(1); }); } else { // Run all transport tests testAllTransports() .then(report => { process.exit(report.summary.failed > 0 ? 1 : 0); }) .catch(error => { console.error('Test failed:', error); process.exit(1); }); } }