Skip to main content
Glama
ampcome-mcps

Playwright Browserbase MCP Server

by ampcome-mcps

browserbase_session_close

Properly closes the current browser session by shutting down the Stagehand instance, handling browser cleanup and terminating session recording.

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
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main execution handler for the 'browserbase_session_close' tool. Retrieves the active browser read-only, closes the browser if available, calls cleanupSession helper, resets the context's currentSessionId to default, clears latest snapshot if it was a custom session, handles errors, and returns success or informational content.
    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,
      };
    }
  • Input schema using Zod (dummy 'random_string' parameter for consistent tool calls) 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,
    };
  • Tool object 'closeSessionTool' bundling the schema and handler, exported in default array for use in tool registry.
    const closeSessionTool: Tool<typeof CloseSessionInputSchema> = {
      capability: "core",
      schema: closeSessionSchema,
      handle: handleCloseSession,
    };
    
    export default [createSessionTool, closeSessionTool];
  • cleanupSession helper function called by the tool handler to remove the session from global tracking map, clear default session reference if matching, and reset active session ID.
    export function cleanupSession(sessionId: string): void {
      process.stderr.write(
        `[SessionManager] Cleaning up session: ${sessionId}\n`
      );
      
      // Remove from browsers map
      browsers.delete(sessionId);
      
      // Clear default session reference if this was the default
      if (sessionId === defaultSessionId && defaultBrowserSession) {
        defaultBrowserSession = null;
      }
      
      // Reset active session to default if this was the active one
      if (activeSessionId === sessionId) {
        process.stderr.write(
          `[SessionManager] Cleaned up active session ${sessionId}, resetting to default.\n`
        );
        setActiveSessionId(defaultSessionId);
      }
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses behavioral traits: it's a destructive operation (shuts down, terminates) and handles cleanup (browser cleanup, session recording). However, it lacks details on permissions, rate limits, or error handling. The description does not contradict annotations (none exist).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the core action ('Closes the current Browserbase session') and efficiently adds necessary context (Stagehand cleanup, recording termination). Every word earns its place without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (a session-closing operation with no parameters and no output schema) and lack of annotations, the description is mostly complete: it explains what the tool does and its cleanup behavior. However, it could benefit from mentioning potential side effects (e.g., data loss if unsaved) or confirmation of success, slightly reducing completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description appropriately does not discuss parameters, maintaining focus on the tool's action. Baseline is 4 for 0 parameters, as it avoids unnecessary details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Closes') and resource ('current Browserbase session'), distinguishing it from siblings like 'browserbase_session_create' (which opens sessions) and 'browserbase_stagehand_*' tools (which operate within sessions). It explicitly mentions 'Stagehand instance' cleanup and session recording termination, providing precise scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by specifying 'current Browserbase session' and cleanup of 'Stagehand instance', suggesting it should be used after session activities are complete. However, it does not explicitly state when-not-to-use alternatives or prerequisites (e.g., must have an active session).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/ampcome-mcps/browserbase-mcp'

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