Skip to main content
Glama

TOYBOX MCP Server

by isnbh0
test-mcp.js6.7 kB
#!/usr/bin/env node import { spawn } from 'child_process'; import { EventEmitter } from 'events'; class MCPTestClient extends EventEmitter { constructor() { super(); this.server = null; this.requestId = 0; this.pendingRequests = new Map(); } async start(useNpx = false) { console.log(`🚀 Starting MCP server ${useNpx ? 'via npx' : 'locally'}...`); // Set environment variables for the server process const env = { ...process.env, TOYBOX_DEBUG: 'true', TOYBOX_LOG_LEVEL: 'debug' }; const command = useNpx ? 'npx' : 'node'; const args = useNpx ? ['@isnbh0/toybox-mcp-server@latest'] : ['dist/index.js']; this.server = spawn(command, args, { stdio: ['pipe', 'pipe', 'pipe'], env }); this.server.stderr.on('data', (data) => { console.log('📡 Server stderr:', data.toString().trim()); }); this.server.stdout.on('data', (data) => { const messages = data.toString().trim().split('\n'); for (const message of messages) { if (message.trim()) { try { const parsed = JSON.parse(message); this.handleMessage(parsed); } catch (e) { console.log('📡 Server stdout (non-JSON):', message); } } } }); this.server.on('error', (error) => { console.error('❌ Server error:', error); }); this.server.on('exit', (code) => { console.log(`🛑 Server exited with code ${code}`); }); // Wait a bit for server to start await new Promise(resolve => setTimeout(resolve, 1000)); } handleMessage(message) { console.log('📥 Received:', JSON.stringify(message, null, 2)); if (message.id && this.pendingRequests.has(message.id)) { const { resolve, reject } = this.pendingRequests.get(message.id); this.pendingRequests.delete(message.id); if (message.error) { reject(new Error(message.error.message || 'MCP Error')); } else { resolve(message.result); } } } async sendRequest(method, params = {}) { const id = ++this.requestId; const request = { jsonrpc: '2.0', id, method, params }; console.log('📤 Sending:', JSON.stringify(request, null, 2)); return new Promise((resolve, reject) => { this.pendingRequests.set(id, { resolve, reject }); this.server.stdin.write(JSON.stringify(request) + '\n'); // Timeout after 30 seconds setTimeout(() => { if (this.pendingRequests.has(id)) { this.pendingRequests.delete(id); reject(new Error('Request timeout')); } }, 30000); }); } async initialize() { console.log('\n🔌 Initializing MCP connection...'); return await this.sendRequest('initialize', { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } }); } async listTools() { console.log('\n🛠️ Listing available tools...'); return await this.sendRequest('tools/list'); } async listResources() { console.log('\n📚 Listing available resources...'); return await this.sendRequest('resources/list'); } async listPrompts() { console.log('\n💬 Listing available prompts...'); return await this.sendRequest('prompts/list'); } async callTool(name, arguments_) { console.log(`\n⚡ Calling tool: ${name}`); return await this.sendRequest('tools/call', { name, arguments: arguments_ }); } async stop() { if (this.server) { console.log('\n🛑 Stopping server...'); this.server.kill('SIGINT'); // Wait for graceful shutdown await new Promise(resolve => { this.server.on('exit', resolve); setTimeout(() => { this.server.kill('SIGKILL'); resolve(); }, 5000); }); } } } async function runTests() { const useNpx = process.argv.includes('--npx'); const client = new MCPTestClient(); try { // Start the server await client.start(useNpx); // Initialize the connection const initResult = await client.initialize(); console.log('✅ Initialization successful:', initResult); // List available tools const tools = await client.listTools(); console.log('✅ Available tools:', tools.tools.map(t => t.name)); // Test resources/list (this is causing errors) try { const resources = await client.listResources(); console.log('✅ Available resources:', resources); } catch (error) { console.log('⚠️ resources/list error:', error.message); } // Test prompts/list (this is also causing errors) try { const prompts = await client.listPrompts(); console.log('✅ Available prompts:', prompts); } catch (error) { console.log('⚠️ prompts/list error:', error.message); } // Test GitHub authentication by trying to initialize a toybox console.log('\n🧪 Testing TOYBOX initialization (this will test GitHub auth)...'); const initParams = { repoName: 'test-toybox-' + Date.now(), templateOwner: 'isnbh0', templateRepo: 'toybox', config: { title: 'Test TOYBOX', description: 'A test TOYBOX for debugging auth', theme: 'auto', layout: 'grid', showFooter: true, }, debug: true, createRemote: false, // Start without remote to test local setup isPrivate: false, }; const result = await client.callTool('initialize_toybox', initParams); if (result.content && result.content[0]) { const parsed = JSON.parse(result.content[0].text); console.log('\n📋 TOYBOX initialization result:'); console.log(' Success:', parsed.success); if (parsed.success) { console.log(' Repository:', parsed.repository.localPath); console.log(' Message:', parsed.message); } else { console.log(' Error:', parsed.error); } } } catch (error) { console.error('\n💥 Test failed:', error.message); console.error('Full error:', error); } finally { await client.stop(); } console.log('\n📋 Check logs for detailed debugging info:'); console.log(' tail -f ../.local/logs/$(ls -t ../.local/logs/ | head -1)'); } // Handle Ctrl+C gracefully process.on('SIGINT', () => { console.log('\n⚠️ Received SIGINT, shutting down...'); process.exit(0); }); console.log('🧪 MCP Server Test Client'); console.log('========================\n'); runTests().catch(console.error);

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/isnbh0/toybox-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server