browserbase_session_close
Terminate and clean up browser sessions, ensuring proper shutdown of Stagehand instances and session recording closure, to maintain resource efficiency and session integrity.
Instructions
Closes the current Browserbase session by properly shutting down the Stagehand instance, which handles browser cleanup and terminates the session recording.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/session.ts:130-232 (handler)The main handler function `handleCloseSession` that executes the tool: closes the active browser if present, cleans up the session using cleanupSession, resets context.currentSessionId to default, clears snapshot if applicable, logs session replay URL, and returns success or info message.async function handleCloseSession( context: Context, _params: CloseSessionInput ): Promise<ToolResult> { const code = [`// Attempting to close the current Browserbase session.`]; const action = async (): Promise<ToolActionResult> => { // Store the current session ID before it's potentially changed. // This allows us to reference the original session ID later if needed. const previousSessionId = context.currentSessionId; // Capture the ID before any changes let browser: BrowserSession["browser"] | null = null; let browserClosedSuccessfully = false; let browserCloseErrorMessage = ""; // Step 1: Attempt to get the active browser instance WITHOUT creating a new one try { // Use read-only version to avoid creating new sessions browser = context.getActiveBrowserReadOnly(); } catch (error: any) { process.stderr.write( `[tool.closeSession] Error retrieving active browser (session ID was ${previousSessionId || 'default/unknown'}): ${error.message || String(error)}` ); // If we can't even get the browser, we can't close it. // We will still proceed to reset context. } // Step 2: If a browser instance was retrieved, attempt to close it if (browser) { try { process.stderr.write( `[tool.closeSession] Attempting to close browser for session: ${previousSessionId || 'default (actual might differ)'}` ); await browser.close(); browserClosedSuccessfully = true; process.stderr.write( `[tool.closeSession] Browser connection for session (was ${previousSessionId}) closed.` ); // Clean up the session from tracking cleanupSession(previousSessionId); process.stderr.write( `[tool.closeSession] View session replay at https://www.browserbase.com/sessions/${previousSessionId}` ); } catch (error: any) { browserCloseErrorMessage = error.message || String(error); process.stderr.write( `[tool.closeSession] Error during browser.close() for session (was ${previousSessionId}): ${browserCloseErrorMessage}` ); } } else { process.stderr.write( `[tool.closeSession] No active browser instance found to close. (Session ID in context was: ${previousSessionId || 'default/unknown'}).` ); } // Step 3: Always reset the context's current session ID to default // and clear snapshot if the previous session was a specific one. const oldContextSessionId = context.currentSessionId; // This should effectively be 'previousSessionId' context.currentSessionId = defaultSessionId; if (oldContextSessionId && oldContextSessionId !== defaultSessionId) { context.clearLatestSnapshot(); process.stderr.write( `[tool.closeSession] Snapshot cleared for previous session: ${oldContextSessionId}.` ); } process.stderr.write( `[tool.closeSession] Session context reset to default. Previous context session ID was ${oldContextSessionId || 'default/unknown'}.` ); // Step 4: Determine the result message if (browser && !browserClosedSuccessfully) { // An attempt was made to close, but it failed throw new Error( `Failed to close the Browserbase browser (session ID in context was ${previousSessionId || 'default/unknown'}). Error: ${browserCloseErrorMessage}. Session context has been reset to default.` ); } if (browserClosedSuccessfully) { // Browser was present and closed let successMessage = `Browserbase session (associated with context ID ${previousSessionId || 'default'}) closed successfully. Context reset to default.`; if (previousSessionId && previousSessionId !== defaultSessionId) { successMessage += ` If this was a uniquely named session (${previousSessionId}), view replay (if available) at https://browserbase.com/sessions`; } return { content: [{ type: "text", text: successMessage }] }; } // No browser was found, or browser was null initially. let infoMessage = "No active browser instance was found to close. Session context has been reset to default."; if (previousSessionId && previousSessionId !== defaultSessionId) { // This means a specific session was in context, but no browser for it. infoMessage = `No active browser found for session ID '${previousSessionId}' in context. The context has been reset to default.`; } return { content: [{ type: "text", text: infoMessage }] }; }; return { action: action, code: code, captureSnapshot: false, waitForNetwork: false, }; }
- src/tools/session.ts:115-128 (schema)Zod input schema (dummy optional random_string for consistent format) and tool schema defining name 'browserbase_session_close', description, and inputSchema reference.const CloseSessionInputSchema = z.object({ random_string: z .string() .optional() .describe("Dummy parameter to ensure consistent tool call format."), }); type CloseSessionInput = z.infer<typeof CloseSessionInputSchema>; const closeSessionSchema: ToolSchema<typeof CloseSessionInputSchema> = { name: "browserbase_session_close", description: "Closes the current Browserbase session by disconnecting the Playwright browser. This will terminate the recording for the session.", inputSchema: CloseSessionInputSchema, };
- src/tools/session.ts:233-239 (registration)Local tool registration: defines closeSessionTool with capability 'core', schema, and handle; exported in default array alongside createSessionTool.const closeSessionTool: Tool<typeof CloseSessionInputSchema> = { capability: "core", schema: closeSessionSchema, handle: handleCloseSession, }; export default [createSessionTool, closeSessionTool];
- src/index.ts:73-106 (registration)Global MCP server registration: imports session tools (line 12: import session from "./tools/session.js"), adds to tools array (...session), then loops over tools calling server.tool(name, description, inputSchema.shape, async handler wrapper using context.run(tool, params)).const tools: Tool<any>[] = [ ...common, ...snapshot, ...keyboard, ...getText, ...navigate, ...session, ...contextTools, ]; // Register each tool with the Smithery server tools.forEach(tool => { if (tool.schema.inputSchema instanceof z.ZodObject) { server.tool( tool.schema.name, tool.schema.description, tool.schema.inputSchema.shape, async (params: z.infer<typeof tool.schema.inputSchema>) => { try { const result = await context.run(tool, params); return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); process.stderr.write(`[Smithery Error] ${new Date().toISOString()} Error running tool ${tool.schema.name}: ${errorMessage}\n`); throw new Error(`Failed to run tool '${tool.schema.name}': ${errorMessage}`); } } ); } else { console.warn( `Tool "${tool.schema.name}" has an input schema that is not a ZodObject. Schema type: ${tool.schema.inputSchema.constructor.name}` ); } });