Skip to main content
Glama

Claude Desktop Commander MCP

index.ts5.59 kB
#!/usr/bin/env node import { FilteredStdioServerTransport } from './custom-stdio.js'; import { server, flushDeferredMessages } from './server.js'; import { commandManager } from './command-manager.js'; import { configManager } from './config-manager.js'; import { runSetup } from './npm-scripts/setup.js'; import { runUninstall } from './npm-scripts/uninstall.js'; import { capture } from './utils/capture.js'; import { logToStderr, logger } from './utils/logger.js'; // Store messages to defer until after initialization const deferredMessages: Array<{level: string, message: string}> = []; function deferLog(level: string, message: string) { deferredMessages.push({level, message}); } async function runServer() { try { // Check if first argument is "setup" if (process.argv[2] === 'setup') { await runSetup(); return; } // Check if first argument is "remove" if (process.argv[2] === 'remove') { await runUninstall(); return; } // Parse command line arguments for onboarding control const DISABLE_ONBOARDING = process.argv.includes('--no-onboarding'); if (DISABLE_ONBOARDING) { logToStderr('info', 'Onboarding disabled via --no-onboarding flag'); } // Set global flag for onboarding control (global as any).disableOnboarding = DISABLE_ONBOARDING; try { deferLog('info', 'Loading configuration...'); await configManager.loadConfig(); deferLog('info', 'Configuration loaded successfully'); } catch (configError) { deferLog('error', `Failed to load configuration: ${configError instanceof Error ? configError.message : String(configError)}`); if (configError instanceof Error && configError.stack) { deferLog('debug', `Stack trace: ${configError.stack}`); } deferLog('warning', 'Continuing with in-memory configuration only'); // Continue anyway - we'll use an in-memory config } const transport = new FilteredStdioServerTransport(); // Export transport for use throughout the application global.mcpTransport = transport; // Handle uncaught exceptions process.on('uncaughtException', async (error) => { const errorMessage = error instanceof Error ? error.message : String(error); // If this is a JSON parsing error, log it to stderr but don't crash if (errorMessage.includes('JSON') && errorMessage.includes('Unexpected token')) { logger.error(`JSON parsing error: ${errorMessage}`); return; // Don't exit on JSON parsing errors } capture('run_server_uncaught_exception', { error: errorMessage }); logger.error(`Uncaught exception: ${errorMessage}`); process.exit(1); }); // Handle unhandled rejections process.on('unhandledRejection', async (reason) => { const errorMessage = reason instanceof Error ? reason.message : String(reason); // If this is a JSON parsing error, log it to stderr but don't crash if (errorMessage.includes('JSON') && errorMessage.includes('Unexpected token')) { logger.error(`JSON parsing rejection: ${errorMessage}`); return; // Don't exit on JSON parsing errors } capture('run_server_unhandled_rejection', { error: errorMessage }); logger.error(`Unhandled rejection: ${errorMessage}`); process.exit(1); }); capture('run_server_start'); deferLog('info', 'Connecting server...'); // Set up event-driven initialization completion handler server.oninitialized = () => { // This callback is triggered after the client sends the "initialized" notification // At this point, the MCP protocol handshake is fully complete transport.enableNotifications(); // Flush all deferred messages from both index.ts and server.ts while (deferredMessages.length > 0) { const msg = deferredMessages.shift()!; transport.sendLog('info', msg.message); } flushDeferredMessages(); // Now we can send regular logging messages transport.sendLog('info', 'Server connected successfully'); transport.sendLog('info', 'MCP fully initialized, all startup messages sent'); }; await server.connect(transport); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`FATAL ERROR: ${errorMessage}`); if (error instanceof Error && error.stack) { logger.debug(error.stack); } // Send a structured error notification const errorNotification = { jsonrpc: "2.0" as const, method: "notifications/message", params: { level: "error", logger: "desktop-commander", data: `Failed to start server: ${errorMessage} (${new Date().toISOString()})` } }; process.stdout.write(JSON.stringify(errorNotification) + '\n'); capture('run_server_failed_start_error', { error: errorMessage }); process.exit(1); } } runServer().catch(async (error) => { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`RUNTIME ERROR: ${errorMessage}`); console.error(error instanceof Error && error.stack ? error.stack : 'No stack trace available'); process.stderr.write(JSON.stringify({ type: 'error', timestamp: new Date().toISOString(), message: `Fatal error running server: ${errorMessage}` }) + '\n'); capture('run_server_fatal_error', { error: errorMessage }); process.exit(1); });

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/wonderwhy-er/DesktopCommanderMCP'

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