From 3fbb9a18372f2b6a675dd6c039ba52be76f3eeb4 Mon Sep 17 00:00:00 2001 From: TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:30:14 +0900 Subject: updates --- .../simple-mcp-server/.claude/commands/debug.md | 310 +++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 mcp-servers/simple-mcp-server/.claude/commands/debug.md (limited to 'mcp-servers/simple-mcp-server/.claude/commands/debug.md') diff --git a/mcp-servers/simple-mcp-server/.claude/commands/debug.md b/mcp-servers/simple-mcp-server/.claude/commands/debug.md new file mode 100644 index 0000000..47eca5f --- /dev/null +++ b/mcp-servers/simple-mcp-server/.claude/commands/debug.md @@ -0,0 +1,310 @@ +# Debug MCP Server + +Provides comprehensive debugging tools for troubleshooting MCP server issues. + +## Usage + +``` +/debug [component] [options] +``` + +## Components + +- `protocol` - Debug protocol messages +- `tools` - Debug tool execution +- `resources` - Debug resource access +- `transport` - Debug transport layer +- `all` - Enable all debugging (default) + +## Options + +- `--verbose` - Extra verbose output +- `--save` - Save debug logs to file +- `--inspector` - Launch with MCP Inspector + +## Implementation + +```typescript +import * as fs from 'fs/promises'; +import { exec, spawn } from 'child_process'; +import * as path from 'path'; + +async function debugServer( + component: 'protocol' | 'tools' | 'resources' | 'transport' | 'all' = 'all', + options: { + verbose?: boolean; + save?: boolean; + inspector?: boolean; + } = {} +) { + console.log('šŸ” MCP Server Debugger'); + console.log('='.repeat(50)); + + // Set debug environment variables + const debugEnv = { + ...process.env, + DEBUG: component === 'all' ? 'mcp:*' : `mcp:${component}`, + LOG_LEVEL: options.verbose ? 'trace' : 'debug', + MCP_DEBUG: 'true', + }; + + // Create debug configuration + const debugConfig = await createDebugConfig(); + + // Start debug session + if (options.inspector) { + await launchWithInspector(debugEnv); + } else { + await runDebugSession(component, debugEnv, options); + } +} + +async function createDebugConfig(): Promise { + const config = { + logging: { + level: 'debug', + format: 'pretty', + includeTimestamp: true, + includeLocation: true, + }, + debug: { + protocol: { + logRequests: true, + logResponses: true, + logNotifications: true, + }, + tools: { + logCalls: true, + logValidation: true, + logErrors: true, + measurePerformance: true, + }, + resources: { + logReads: true, + logWrites: true, + trackCache: true, + }, + transport: { + logConnections: true, + logMessages: true, + logErrors: true, + }, + }, + }; + + const configPath = '.debug-config.json'; + await fs.writeFile(configPath, JSON.stringify(config, null, 2)); + return configPath; +} + +async function runDebugSession( + component: string, + env: NodeJS.ProcessEnv, + options: { verbose?: boolean; save?: boolean } +) { + console.log(`\nšŸ” Debugging: ${component}`); + console.log('Press Ctrl+C to stop\n'); + + // Create debug wrapper + const debugScript = ` +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import debug from 'debug'; +import pino from 'pino'; + +// Enable debug logging +const log = { + protocol: debug('mcp:protocol'), + tools: debug('mcp:tools'), + resources: debug('mcp:resources'), + transport: debug('mcp:transport'), +}; + +// Create logger +const logger = pino({ + level: process.env.LOG_LEVEL || 'debug', + transport: { + target: 'pino-pretty', + options: { + colorize: true, + translateTime: 'HH:MM:ss.l', + ignore: 'pid,hostname', + }, + }, +}); + +// Wrap server methods for debugging +const originalServer = await import('./src/index.js'); +const server = originalServer.server; + +// Intercept requests +const originalSetRequestHandler = server.setRequestHandler.bind(server); +server.setRequestHandler = (schema, handler) => { + const wrappedHandler = async (request) => { + const start = Date.now(); + log.protocol('→ Request: %O', request); + logger.debug({ request }, 'Incoming request'); + + try { + const result = await handler(request); + const duration = Date.now() - start; + + log.protocol('← Response (%dms): %O', duration, result); + logger.debug({ result, duration }, 'Response sent'); + + return result; + } catch (error) { + log.protocol('āœ— Error: %O', error); + logger.error({ error }, 'Request failed'); + throw error; + } + }; + + return originalSetRequestHandler(schema, wrappedHandler); +}; + +// Start server with debugging +logger.info('Debug server starting...'); +const transport = new StdioServerTransport(); +await server.connect(transport); +logger.info('Debug server ready'); +`; + + // Write debug script + const debugScriptPath = '.debug-server.js'; + await fs.writeFile(debugScriptPath, debugScript); + + // Start server with debugging + const serverProcess = spawn('node', [debugScriptPath], { + env, + stdio: options.save ? 'pipe' : 'inherit', + }); + + if (options.save) { + const logFile = `debug-${component}-${Date.now()}.log`; + const logStream = await fs.open(logFile, 'w'); + + serverProcess.stdout?.pipe(logStream.createWriteStream()); + serverProcess.stderr?.pipe(logStream.createWriteStream()); + + console.log(`Saving debug output to: ${logFile}`); + } + + // Handle cleanup + process.on('SIGINT', () => { + serverProcess.kill(); + process.exit(); + }); + + serverProcess.on('exit', async () => { + // Cleanup + await fs.unlink(debugScriptPath).catch(() => {}); + await fs.unlink('.debug-config.json').catch(() => {}); + }); +} + +async function launchWithInspector(env: NodeJS.ProcessEnv) { + console.log('\nšŸ” Launching with MCP Inspector...'); + console.log('This will provide an interactive debugging interface.\n'); + + // Start server in debug mode + const serverProcess = spawn('node', ['--inspect', 'dist/index.js'], { + env, + stdio: 'pipe', + }); + + // Parse debug port from output + serverProcess.stderr?.on('data', (data) => { + const output = data.toString(); + const match = output.match(/Debugger listening on ws:\/\/(.+):(\d+)/); + if (match) { + console.log(`šŸ”— Node.js debugger: chrome://inspect`); + console.log(` Connect to: ${match[1]}:${match[2]}`); + } + }); + + // Wait a moment for server to start + await new Promise(resolve => setTimeout(resolve, 2000)); + + // Launch MCP Inspector + console.log('\nšŸ” Starting MCP Inspector...'); + const inspector = exec('npx @modelcontextprotocol/inspector'); + + inspector.stdout?.on('data', (data) => { + console.log(data.toString()); + }); + + // Cleanup on exit + process.on('SIGINT', () => { + serverProcess.kill(); + inspector.kill(); + process.exit(); + }); +} + +// Additional debug utilities +export async function analyzeProtocolFlow() { + console.log('\nšŸ“Š Analyzing Protocol Flow...'); + + const checks = [ + { name: 'Initialization', test: testInitialization }, + { name: 'Capability Negotiation', test: testCapabilities }, + { name: 'Tool Discovery', test: testToolDiscovery }, + { name: 'Resource Listing', test: testResourceListing }, + { name: 'Error Handling', test: testErrorHandling }, + ]; + + for (const check of checks) { + try { + await check.test(); + console.log(` āœ… ${check.name}`); + } catch (error) { + console.log(` āŒ ${check.name}: ${error.message}`); + } + } +} + +async function testInitialization() { + // Test initialization flow + const { Server } = await import('@modelcontextprotocol/sdk/server/index.js'); + const server = new Server({ name: 'test', version: '1.0.0' }, {}); + if (!server) throw new Error('Server initialization failed'); +} + +async function testCapabilities() { + // Test capability declaration + const capabilities = { + tools: {}, + resources: {}, + prompts: {}, + }; + if (!capabilities.tools) throw new Error('Tools capability missing'); +} + +async function testToolDiscovery() { + // Test tool discovery + try { + const { tools } = await import('./src/tools/index.js'); + if (!Array.isArray(tools)) throw new Error('Tools not properly exported'); + } catch { + // Tools may not be implemented yet + } +} + +async function testResourceListing() { + // Test resource listing + try { + const { resources } = await import('./src/resources/index.js'); + if (!Array.isArray(resources)) throw new Error('Resources not properly exported'); + } catch { + // Resources may not be implemented yet + } +} + +async function testErrorHandling() { + // Test error handling + const { handleError } = await import('./src/utils/error-handler.js'); + const result = handleError(new Error('Test')); + if (!result.error) throw new Error('Error handler not working'); +} +``` \ No newline at end of file -- cgit v1.2.3