Skip to main content
Glama

start_gui

Launch a web interface to manage Claude Code conversation sessions through your browser.

Instructions

Start the web GUI for session management and open it in browser

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
portNoPort to run the web server on (default: 5173)
open_browserNoWhether to open browser automatically (default: true)
restartNoRestart the server if already running (default: false)

Implementation Reference

  • Registration of the 'start_gui' MCP tool, including input schema with Zod validation and the inline asynchronous handler function that manages the web server instance (restart if requested, start via helper, return MCP-formatted response with URL or error).
    server.tool( 'start_gui', 'Start the web GUI for session management and open it in browser', { port: z.number().default(5173).describe('Port to run the web server on (default: 5173)'), open_browser: z .boolean() .default(true) .describe('Whether to open browser automatically (default: true)'), restart: z .boolean() .default(false) .describe('Restart the server if already running (default: false)'), }, async ({ port, open_browser, restart }) => { try { if (webServerInstance) { if (restart) { await stopWebServer(webServerInstance) webServerInstance = null } else { return { content: [ { type: 'text', text: JSON.stringify( { success: true, message: 'Web GUI is already running', url: `http://localhost:${port}`, }, null, 2 ), }, ], } } } webServerInstance = await startWebServer(port, open_browser) return { content: [ { type: 'text', text: JSON.stringify( { success: true, message: 'Web GUI started successfully', url: `http://localhost:${port}`, pid: process.pid, }, null, 2 ), }, ], } } catch (error) { return { content: [ { type: 'text', text: JSON.stringify( { success: false, error: String(error), }, null, 2 ), }, ], } } } )
  • Helper functions to start and stop the web GUI server: computes path to built SvelteKit app, spawns Node process, waits for startup signal, opens browser cross-platform; stop sends SIGTERM to process. Used by the start_gui handler.
    const __dirname = path.dirname(fileURLToPath(import.meta.url)) // dist/web/index.js is the built SvelteKit server (adapter-node) const webServerPath = path.join(__dirname, 'web', 'index.js') interface WebServer { process: ChildProcess port: number } export async function startWebServer( port: number = 5173, openBrowser: boolean = true ): Promise<WebServer> { // Run the built SvelteKit server directly with Node const child = spawn('node', [webServerPath], { stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, PORT: String(port) }, }) // Wait for server to start await new Promise<void>((resolve, reject) => { const timeout = setTimeout(() => reject(new Error('Server startup timeout')), 10000) child.stdout?.on('data', (data: Buffer) => { const output = data.toString() // SvelteKit adapter-node outputs "Listening on http://0.0.0.0:PORT" if ( output.includes('Listening on') || output.includes('localhost') || output.includes('Local:') ) { clearTimeout(timeout) resolve() } }) child.on('error', (err) => { clearTimeout(timeout) reject(err) }) child.on('exit', (code) => { if (code !== 0) { clearTimeout(timeout) reject(new Error(`Server exited with code ${code}`)) } }) }) // Open browser if requested if (openBrowser) { const url = `http://localhost:${port}` const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open' spawn(openCmd, [url], { stdio: 'ignore', detached: true }).unref() } return { process: child, port } } export async function stopWebServer(server: WebServer): Promise<void> { server.process.kill('SIGTERM') }

Latest Blog Posts

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/DrumRobot/claude-sessions-mcp'

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