Skip to main content
Glama

claude-debugs-for-you

extension.ts13.1 kB
import * as vscode from 'vscode'; import { DebugServer } from './debug-server'; import * as fs from 'fs'; import * as path from 'path'; export function activate(context: vscode.ExtensionContext) { // Get the storage path for your extension const storagePath = context.globalStorageUri.fsPath; // Ensure the storage directory exists fs.mkdirSync(storagePath, { recursive: true }); const mcpServerPath = path.join(storagePath, 'mcp-debug.js'); const sourcePath = path.join(context.extensionUri.fsPath, 'mcp', 'build', 'index.js'); try { fs.copyFileSync(sourcePath, mcpServerPath); } catch (err: any) { vscode.window.showErrorMessage(`Failed to setup debug server: ${err.message}`); return; } const config = vscode.workspace.getConfiguration('mcpDebug'); const port = config.get<number>('port') ?? 4711; // Write port configuration to a file that can be read by the MCP server const portConfigPath = path.join(storagePath, 'port-config.json'); try { fs.writeFileSync(portConfigPath, JSON.stringify({ port })); } catch (err: any) { vscode.window.showErrorMessage(`Failed to write port configuration: ${err.message}`); } const server = new DebugServer(port, portConfigPath); // Create status bar item const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); statusBarItem.command = 'claude-debugs-for-you.showCommands'; // Update status bar with server state function updateStatusBar() { if (server.isRunning) { statusBarItem.text = "$(check) Claude Debugs For You"; statusBarItem.tooltip = "Claude Debugs For You (Running) - Click to show commands"; } else { statusBarItem.text = "$(x) Claude Debugs For You"; statusBarItem.tooltip = "Claude Debugs For You (Stopped) - Click to show commands"; } statusBarItem.show(); } // Listen for server state changes server.on('started', updateStatusBar); server.on('stopped', updateStatusBar); // Listen for configuration changes context.subscriptions.push( vscode.workspace.onDidChangeConfiguration(async e => { if (e.affectsConfiguration('mcpDebug.port')) { // Always reload the latest configuration const updatedConfig = vscode.workspace.getConfiguration('mcpDebug'); const newPort = updatedConfig.get<number>('port') ?? 4711; // Update port configuration file try { const portConfigPath = path.join(storagePath, 'port-config.json'); fs.writeFileSync(portConfigPath, JSON.stringify({ port: newPort })); } catch (err: any) { vscode.window.showErrorMessage(`Failed to write port configuration: ${err.message}`); } // Update server's port setting server.setPort(newPort); if (server.isRunning) { // Port changed, restart server with new port vscode.window.showInformationMessage(`Port changed to ${newPort}. Restarting server...`); await vscode.commands.executeCommand('vscode-mcp-debug.restart'); } } else if (e.affectsConfiguration('mcpDebug')) { updateStatusBar(); } }) ); // Initial state updateStatusBar(); async function startServer() { // Always get the current port from config const updatedConfig = vscode.workspace.getConfiguration('mcpDebug'); const currentPort = updatedConfig.get<number>('port') ?? 4711; server.setPort(currentPort); try { await server.start(); } catch (err: any) { // Stop our own server await server.stop(); // Check if this is likely a port conflict (server already running) const nodeErr = err as NodeJS.ErrnoException; if ((nodeErr.code === 'EADDRINUSE') || (nodeErr.message && nodeErr.message.includes('already running'))) { const response = await vscode.window.showInformationMessage( `Failed to start debug server. Another server is likely already running in a different VS Code window. Would you like to stop it and start the server in this window?`, 'Yes', 'No', 'Disable Autostart' ); if (response === 'Yes') { try { // First try to stop any existing server await server.forceStopExistingServer(); // Wait for the port to be released with retry logic let portAvailable = false; let retryCount = 0; const maxRetries = 5; const currentPort = server.getPort(); while (!portAvailable && retryCount < maxRetries) { try { // Check if port is available const net = require('net'); const testServer = net.createServer(); await new Promise<void>((resolve, reject) => { testServer.once('error', (err: any) => { testServer.close(); if (err.code === 'EADDRINUSE') { reject(new Error('Port still in use')); } else { reject(err); } }); testServer.once('listening', () => { testServer.close(); portAvailable = true; resolve(); }); testServer.listen(currentPort); }); } catch (err) { // Port still in use, wait and retry await new Promise(resolve => setTimeout(resolve, 500)); retryCount++; } } if (!portAvailable) { throw new Error(`Port ${currentPort} is still in use after ${maxRetries} attempts to release it`); } // Now try to start our server await server.start(); } catch (startErr: any) { vscode.window.showErrorMessage(`Still failed to start debug server: ${startErr.message}`); } } else if (response === 'Disable Autostart') { // Update autostart configuration to false await startupConfig.update('autostart', false, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage('Autostart has been disabled'); } } else { vscode.window.showErrorMessage(`Failed to start debug server: ${err.message}`); } } } const startupConfig = vscode.workspace.getConfiguration('mcpDebug'); if (startupConfig.get<boolean>('autostart')) { void startServer(); } context.subscriptions.push( statusBarItem, vscode.commands.registerCommand('claude-debugs-for-you.showCommands', async () => { const updatedConfig = vscode.workspace.getConfiguration('mcpDebug'); const currentPort = updatedConfig.get<number>('port') ?? 4711; const commands = [ // Show either Start or Stop based on server state server.isRunning ? { label: "Stop Server", command: 'vscode-mcp-debug.stop' } : { label: "Start Server", command: 'vscode-mcp-debug.restart' }, { label: `Set Port (currently: ${currentPort})`, command: 'vscode-mcp-debug.setPort' }, { label: `${updatedConfig.get<boolean>('autostart') ? 'Disable' : 'Enable'} Autostart`, command: 'vscode-mcp-debug.toggleAutostart' }, { label: "Copy stdio path", command: 'vscode-mcp-debug.copyStdioPath' }, { label: "Copy SSE address", command: 'vscode-mcp-debug.copySseAddress' } ]; const selected = await vscode.window.showQuickPick(commands, { placeHolder: 'Select a Claude Debugs For You command' }); if (selected) { vscode.commands.executeCommand(selected.command); } }), vscode.commands.registerCommand('vscode-mcp-debug.restart', async () => { try { await server.stop(); await startServer(); } catch (err: any) { vscode.window.showErrorMessage(`Failed to stop debug server: ${err.message}`); await startServer(); } }), vscode.commands.registerCommand('vscode-mcp-debug.stop', () => { server.stop() .then(() => { vscode.window.showInformationMessage('MCP Debug Server stopped'); }) .catch(err => { vscode.window.showErrorMessage(`Failed to stop debug server: ${err.message}`); }); }), vscode.commands.registerCommand('vscode-mcp-debug.copyStdioPath', async () => { await vscode.env.clipboard.writeText(mcpServerPath); vscode.window.showInformationMessage(`MCP stdio server path copied to clipboard.`); }), vscode.commands.registerCommand('vscode-mcp-debug.copySseAddress', async () => { // Always get the latest port from config const updatedConfig = vscode.workspace.getConfiguration('mcpDebug'); const currentPort = updatedConfig.get<number>('port') ?? 4711; await vscode.env.clipboard.writeText(`http://localhost:${currentPort}/sse`); vscode.window.showInformationMessage(`MCP sse server address copied to clipboard.`); }), vscode.commands.registerCommand('vscode-mcp-debug.setPort', async () => { // Always get the latest configuration const updatedConfig = vscode.workspace.getConfiguration('mcpDebug'); const currentPort = updatedConfig.get<number>('port') ?? 4711; const newPort = await vscode.window.showInputBox({ prompt: 'Enter port number for MCP Debug Server', placeHolder: 'Port number', value: currentPort.toString(), validateInput: (input) => { const port = parseInt(input); if (isNaN(port) || port < 1024 || port > 65535) { return 'Please enter a valid port number (1024-65535)'; } return null; } }); if (newPort) { const portNum = parseInt(newPort); await updatedConfig.update('port', portNum, vscode.ConfigurationTarget.Global); // Update port configuration file try { const portConfigPath = path.join(storagePath, 'port-config.json'); fs.writeFileSync(portConfigPath, JSON.stringify({ port: portNum })); } catch (err: any) { vscode.window.showErrorMessage(`Failed to write port configuration: ${err.message}`); } // Update server's port setting directly server.setPort(portNum); if (server.isRunning) { const restart = await vscode.window.showInformationMessage( 'Port updated. Restart server to apply changes?', 'Yes', 'No' ); if (restart === 'Yes') { vscode.commands.executeCommand('vscode-mcp-debug.restart'); } } } }), vscode.commands.registerCommand('vscode-mcp-debug.toggleAutostart', async () => { const updatedConfig = vscode.workspace.getConfiguration('mcpDebug'); const currentAutostart = updatedConfig.get<boolean>('autostart') ?? true; await updatedConfig.update('autostart', !currentAutostart, vscode.ConfigurationTarget.Global); vscode.window.showInformationMessage(`Autostart ${!currentAutostart ? 'enabled' : 'disabled'}`); }), ); } export function deactivate() { // We should already have cleaned up during context disposal, but just in case }

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/jasonjmcghee/claude-debugs-for-you'

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