browserbase_session_create
Create or reuse a single cloud browser session for web automation, data extraction, and form interactions with full configuration support.
Instructions
Create or reuse a single cloud browser session using Browserbase with fully initialized Stagehand. WARNING: This tool is for SINGLE browser workflows only. If you need multiple browser sessions running simultaneously (parallel scraping, A/B testing, multiple accounts), use 'multi_browserbase_stagehand_session_create' instead. This creates one browser session with all configuration flags (proxies, stealth, viewport, cookies, etc.) and initializes Stagehand to work with that session. Updates the active session.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | No | Optional session ID to use/reuse. If not provided or invalid, a new session is created. |
Implementation Reference
- src/tools/session.ts:37-122 (handler)The handler function `handleCreateSession` that executes the tool logic: creates or reuses a Browserbase session using SessionManager, connects Stagehand, logs URLs, and handles errors.async function handleCreateSession( context: Context, params: CreateSessionInput, ): Promise<ToolResult> { const action = async (): Promise<ToolActionResult> => { try { const config = context.config; // Get config from context let targetSessionId: string; if (params.sessionId) { const projectId = config.browserbaseProjectId || ""; targetSessionId = `${params.sessionId}_${projectId}`; process.stderr.write( `[tool.createSession] Attempting to create/assign session with specified ID: ${targetSessionId}`, ); } else { targetSessionId = defaultSessionId; } let session: BrowserSession; if (targetSessionId === defaultSessionId) { session = await ensureDefaultSessionInternal(config); } else { // When user provides a sessionId, we want to resume that Browserbase session session = await createNewBrowserSession( targetSessionId, config, params.sessionId, ); } if ( !session || !session.browser || !session.page || !session.sessionId || !session.stagehand ) { throw new Error( `SessionManager failed to return a valid session object with actualSessionId for ID: ${targetSessionId}`, ); } context.currentSessionId = targetSessionId; const bb = new Browserbase({ apiKey: config.browserbaseApiKey, }); const debugUrl = (await bb.sessions.debug(session.sessionId)) .debuggerFullscreenUrl; process.stderr.write( `[tool.connected] Successfully connected to Browserbase session. Internal ID: ${targetSessionId}, Actual ID: ${session.sessionId}`, ); process.stderr.write( `[SessionManager] Browserbase Live Session View URL: https://www.browserbase.com/sessions/${session.sessionId}`, ); process.stderr.write( `[SessionManager] Browserbase Live Debugger URL: ${debugUrl}`, ); return { content: [ { type: "text", text: `Browserbase Live Session View URL: https://www.browserbase.com/sessions/${session.sessionId}\nBrowserbase Live Debugger URL: ${debugUrl}`, }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); process.stderr.write( `[tool.createSession] Action failed: ${errorMessage}`, ); // Re-throw to be caught by Context.run's error handling for actions throw new Error(`Failed to create Browserbase session: ${errorMessage}`); } }; // Return the ToolResult structure expected by Context.run return { action: action, waitForNetwork: false, }; }
- src/tools/session.ts:18-34 (schema)Zod input schema and tool schema definition including name, description, and input validation for session ID.const CreateSessionInputSchema = z.object({ // Keep sessionId optional, but clarify its role sessionId: z .string() .optional() .describe( "Optional session ID to use/reuse. If not provided or invalid, a new session is created.", ), }); type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>; const createSessionSchema: ToolSchema<typeof CreateSessionInputSchema> = { name: "browserbase_session_create", description: "Create or reuse a single cloud browser session using Browserbase with fully initialized Stagehand. WARNING: This tool is for SINGLE browser workflows only. If you need multiple browser sessions running simultaneously (parallel scraping, A/B testing, multiple accounts), use 'multi_browserbase_stagehand_session_create' instead. This creates one browser session with all configuration flags (proxies, stealth, viewport, cookies, etc.) and initializes Stagehand to work with that session. Updates the active session.", inputSchema: CreateSessionInputSchema, };
- src/tools/index.ts:43-52 (registration)Registration of the session tools (including browserbase_session_create) into the main TOOLS array exported for MCP server.export const TOOLS = [ ...multiSessionTools, ...sessionTools, navigateTool, actTool, extractTool, observeTool, screenshotTool, getUrlTool, ];
- src/index.ts:192-222 (registration)MCP server registration loop that dynamically registers all tools from TOOLS array, including browserbase_session_create, using server.tool().const tools: MCPToolsArray = [...TOOLS]; // 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}`, ); } });
- src/stagehandStore.ts:12-64 (helper)Helper function `createStagehandInstance` used in session creation, configuring and initializing Stagehand with Browserbase session parameters.export const createStagehandInstance = async ( config: Config, params: CreateSessionParams = {}, sessionId: string, ): Promise<Stagehand> => { const apiKey = params.apiKey || config.browserbaseApiKey; const projectId = params.projectId || config.browserbaseProjectId; if (!apiKey || !projectId) { throw new Error("Browserbase API Key and Project ID are required"); } const stagehand = new Stagehand({ env: "BROWSERBASE", apiKey, projectId, modelName: params.modelName || config.modelName || "google/gemini-2.0-flash", modelClientOptions: { apiKey: config.modelApiKey || process.env.GEMINI_API_KEY, }, ...(params.browserbaseSessionID && { browserbaseSessionID: params.browserbaseSessionID, }), browserbaseSessionCreateParams: { projectId, proxies: config.proxies, keepAlive: config.keepAlive ?? false, browserSettings: { viewport: { width: config.viewPort?.browserWidth ?? 1024, height: config.viewPort?.browserHeight ?? 768, }, context: config.context?.contextId ? { id: config.context?.contextId, persist: config.context?.persist ?? true, } : undefined, advancedStealth: config.advancedStealth ?? undefined, }, userMetadata: { mcp: "true", }, }, logger: (logLine) => { console.error(`Stagehand[${sessionId}]: ${logLine.message}`); }, }); await stagehand.init(); return stagehand; };