Restart Extension Server
skippr_restart_extension_serverRestart the WebSocket server that communicates with browser extensions to resolve connectivity issues or apply configuration changes.
Instructions
Restarts the WebSocket server that communicates with browser extensions
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Optional port number for the extension server (defaults to WS_PORT env var or 4040) |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| success | Yes | ||
| message | Yes | ||
| port | Yes |
Implementation Reference
- src/servers/websocket.ts:300-354 (handler)Core handler function that restarts the WebSocket server. Closes the existing server (if any), creates a new one with the specified port (defaults to WS_PORT env var or 4040), and waits for it to start listening. Returns success/failure with port and message.
export async function restartWebSocketServer(port?: number): Promise<{ success: boolean; message: string; port: number }> { const targetPort = port || parseInt(process.env.WS_PORT || '4040', 10); try { if (wss) { await new Promise<void>((resolve) => { wss!.close(() => { wss = null; resolve(); }); }); } const server = createWebSocketServer(targetPort); await new Promise<void>((resolve, reject) => { const timeout = setTimeout(() => { reject(new Error('WebSocket server startup timeout')); }, 5000); server.once('listening', () => { clearTimeout(timeout); resolve(); }); server.once('error', (error) => { clearTimeout(timeout); reject(error); }); }); return { success: true, message: `WebSocket server restarted successfully on port ${targetPort}`, port: targetPort }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; console.error(`[restartWebSocketServer] Failed to restart WebSocket server: ${errorMessage}`, error); if ((error as any)?.code === 'EADDRINUSE') { return { success: false, message: `Port ${targetPort} is already in use by another process`, port: targetPort }; } return { success: false, message: `Failed to restart WebSocket server: ${errorMessage}`, port: targetPort }; } } - src/servers/mcp.ts:97-104 (schema)Input/output schema for skippr_restart_extension_server. Input: optional port number. Output: success boolean, message string, port number.
inputSchema: z.object({ port: z.number().optional().describe('Optional port number for the extension server (defaults to WS_PORT env var or 4040)') }).shape, outputSchema: z.object({ success: z.boolean(), message: z.string(), port: z.number() }).shape - src/servers/mcp.ts:92-110 (registration)Registration of the tool as an MCP tool named 'skippr_restart_extension_server' with title 'Restart Extension Server'. The handler calls restartWebSocketServer(args.port).
mcpServer.registerTool( 'skippr_restart_extension_server', { title: 'Restart Extension Server', description: 'Restarts the WebSocket server that communicates with browser extensions', inputSchema: z.object({ port: z.number().optional().describe('Optional port number for the extension server (defaults to WS_PORT env var or 4040)') }).shape, outputSchema: z.object({ success: z.boolean(), message: z.string(), port: z.number() }).shape }, async (args) => { const result = await restartWebSocketServer(args.port); return createStructuredResponse(result); } ); - src/servers/websocket.ts:69-99 (helper)Helper function createWebSocketServer() that creates a new WebSocketServer instance on the given port if one doesn't already exist. Used by restartWebSocketServer.
export function createWebSocketServer(port: number): WebSocketServer { if (wss) { return wss; } wss = new WebSocketServer({ port }); wss.on('connection', (ws: WebSocket) => { let clientId: string | null = null; // Server-side heartbeat: Send ping to client every 30 seconds const heartbeatInterval = setInterval(() => { if (clientId) { const client = clients.get(clientId); if (client) { // Check if client responded to previous ping if (client.isAlive === false) { console.error(`[WebSocket] Client ${clientId} failed heartbeat check. Terminating connection.`); clearInterval(heartbeatInterval); ws.terminate(); return; } // Mark as not alive, will be set back to true when pong is received client.isAlive = false; // Send ping message try { ws.send(JSON.stringify({ type: 'ping', timestamp: Date.now() })); } catch (error) { console.error(`[WebSocket] Failed to send heartbeat ping to client ${clientId}:`, error);