#!/usr/bin/env node import { spawn } from 'child_process'; import { promises as fs } from 'fs'; // Simple MCP client test async function testMCPServer() { console.log('๐Ÿงช Testing Incus MCP Server...\n'); // Test 1: List tools console.log('1. Testing list tools...'); const listToolsMessage = { jsonrpc: '2.0', id: 1, method: 'tools/list', params: {} }; try { const toolsResult = await sendMCPRequest(listToolsMessage); console.log(` โœ… Found ${toolsResult.tools.length} tools`); toolsResult.tools.forEach(tool => { console.log(` - ${tool.name}`); }); } catch (error) { console.log(` โŒ Error: ${error.message}`); } // Test 2: List resources console.log('\n2. Testing list resources...'); const listResourcesMessage = { jsonrpc: '2.0', id: 2, method: 'resources/list', params: {} }; try { const resourcesResult = await sendMCPRequest(listResourcesMessage); console.log(` โœ… Found ${resourcesResult.resources.length} resources`); resourcesResult.resources.forEach(resource => { console.log(` - ${resource.uri}: ${resource.name}`); }); } catch (error) { console.log(` โŒ Error: ${error.message}`); } // Test 3: Test incus info tool console.log('\n3. Testing incus_info tool...'); const infoMessage = { jsonrpc: '2.0', id: 3, method: 'tools/call', params: { name: 'incus_info', arguments: {} } }; try { const infoResult = await sendMCPRequest(infoMessage); console.log(` โœ… Got incus info`); if (infoResult.content && infoResult.content[0]) { console.log(` First few chars: ${infoResult.content[0].text.substring(0, 100)}...`); } } catch (error) { console.log(` โŒ Error: ${error.message}`); } // Test 4: Test list instances console.log('\n4. Testing incus_list_instances tool...'); const listInstancesMessage = { jsonrpc: '2.0', id: 4, method: 'tools/call', params: { name: 'incus_list_instances', arguments: {} } }; try { const instancesResult = await sendMCPRequest(listInstancesMessage); console.log(` โœ… Got instances list`); if (instancesResult.content && instancesResult.content[0]) { console.log(` Response: ${instancesResult.content[0].text.substring(0, 200)}...`); } } catch (error) { console.log(` โŒ Error: ${error.message}`); } // Test 5: Test list remotes console.log('\n5. Testing incus_list_remotes tool...'); const listRemotesMessage = { jsonrpc: '2.0', id: 5, method: 'tools/call', params: { name: 'incus_list_remotes', arguments: {} } }; try { const remotesResult = await sendMCPRequest(listRemotesMessage); console.log(` โœ… Got remotes list`); if (remotesResult.content && remotesResult.content[0]) { console.log(` Response: ${remotesResult.content[0].text.substring(0, 200)}...`); } } catch (error) { console.log(` โŒ Error: ${error.message}`); } } async function sendMCPRequest(message) { return new Promise((resolve, reject) => { const serverProcess = spawn('node', ['build/index.js'], { stdio: ['pipe', 'pipe', 'pipe'] }); let response = ''; let error = ''; serverProcess.stdout.on('data', (data) => { response += data.toString(); }); serverProcess.stderr.on('data', (data) => { error += data.toString(); }); serverProcess.on('close', (code) => { if (code !== 0) { reject(new Error(`Server exited with code ${code}: ${error}`)); return; } try { // Parse JSON-RPC response const lines = response.trim().split('\n'); let jsonResponse = null; for (const line of lines) { if (line.trim()) { try { const parsed = JSON.parse(line); if (parsed.id === message.id) { jsonResponse = parsed; break; } } catch (e) { // Skip non-JSON lines } } } if (jsonResponse) { if (jsonResponse.error) { reject(new Error(jsonResponse.error.message || 'Unknown error')); } else { resolve(jsonResponse.result); } } else { reject(new Error(`No valid response found in: ${response}`)); } } catch (e) { reject(new Error(`Failed to parse response: ${e.message}\nResponse: ${response}`)); } }); serverProcess.on('error', (err) => { reject(new Error(`Failed to start server: ${err.message}`)); }); // Send the JSON-RPC message serverProcess.stdin.write(JSON.stringify(message) + '\n'); serverProcess.stdin.end(); }); } // Run tests testMCPServer().then(() => { console.log('\nโœ… All tests completed!'); }).catch((error) => { console.error('\nโŒ Test suite failed:', error); process.exit(1); });