Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Guide Claude through deploying serverless browser automation using the official bb CLI
Guide Claude through deploying serverless browser automation using the official bb CLI
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Guide Claude through deploying serverless browser automation using the official bb CLI.
Use this skill when: User wants to deploy automation to run on a schedule User needs a webhook endpoint for browser automation User wants to run automation in the cloud (not locally) User asks about Browserbase Functions
Get API key and Project ID from: https://browserbase.com/settings
Set directly: export BROWSERBASE_API_KEY="your_api_key" export BROWSERBASE_PROJECT_ID="your_project_id"
pnpm dlx @browserbasehq/sdk-functions init my-function cd my-function This creates: my-function/ โโโ package.json โโโ index.ts # Your function code โโโ .env # Add credentials here
# Copy from stored credentials echo "BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY" >> .env echo "BROWSERBASE_PROJECT_ID=$BROWSERBASE_PROJECT_ID" >> .env Or manually edit .env: BROWSERBASE_API_KEY=your_api_key BROWSERBASE_PROJECT_ID=your_project_id
pnpm install
import { defineFn } from "@browserbasehq/sdk-functions"; import { chromium } from "playwright-core"; defineFn("my-function", async (context) => { const { session, params } = context; // Connect to browser const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!; // Your automation await page.goto(params.url || "https://example.com"); const title = await page.title(); // Return JSON-serializable result return { success: true, title }; }); Key objects: context.session.connectUrl - CDP endpoint to connect Playwright context.params - Input parameters from invocation
pnpm bb dev index.ts Server runs at http://127.0.0.1:14113
curl -X POST http://127.0.0.1:14113/v1/functions/my-function/invoke \ -H "Content-Type: application/json" \ -d '{"params": {"url": "https://news.ycombinator.com"}}'
The dev server auto-reloads on file changes. Use console.log() for debugging - output appears in the terminal.
pnpm bb publish index.ts Output: Function published successfully Build ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Function ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Save the Function ID - you need it to invoke.
# Start invocation curl -X POST "https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke" \ -H "Content-Type: application/json" \ -H "x-bb-api-key: $BROWSERBASE_API_KEY" \ -d '{"params": {"url": "https://example.com"}}' # Response: {"id": "INVOCATION_ID"} # Poll for result curl "https://api.browserbase.com/v1/functions/invocations/INVOCATION_ID" \ -H "x-bb-api-key: $BROWSERBASE_API_KEY"
async function invokeFunction(functionId: string, params: object) { // Start invocation const invokeRes = await fetch( `https://api.browserbase.com/v1/functions/${functionId}/invoke`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-bb-api-key': process.env.BROWSERBASE_API_KEY!, }, body: JSON.stringify({ params }), } ); const { id: invocationId } = await invokeRes.json(); // Poll until complete while (true) { await new Promise(r => setTimeout(r, 5000)); const statusRes = await fetch( `https://api.browserbase.com/v1/functions/invocations/${invocationId}`, { headers: { 'x-bb-api-key': process.env.BROWSERBASE_API_KEY! } } ); const result = await statusRes.json(); if (result.status === 'COMPLETED') return result.results; if (result.status === 'FAILED') throw new Error(result.error); } }
defineFn("scrape", async ({ session, params }) => { const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!; await page.goto(params.url); await page.waitForSelector(params.selector); const items = await page.$$eval(params.selector, els => els.map(el => el.textContent?.trim()) ); return { url: params.url, items }; });
defineFn("authenticated-action", async ({ session, params }) => { const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!; // Login await page.goto("https://example.com/login"); await page.fill('[name="email"]', params.email); await page.fill('[name="password"]', params.password); await page.click('button[type="submit"]'); await page.waitForURL('**/dashboard'); // Do authenticated work const data = await page.textContent('.user-data'); return { data }; });
defineFn("safe-scrape", async ({ session, params }) => { const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!; try { await page.goto(params.url, { timeout: 30000 }); await page.waitForSelector(params.selector, { timeout: 10000 }); const data = await page.textContent(params.selector); return { success: true, data }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } });
CommandDescriptionpnpm dlx @browserbasehq/sdk-functions init <name>Create new projectpnpm bb dev <file>Start local dev serverpnpm bb publish <file>Deploy to Browserbase
# Check .env file has credentials cat .env # Or set for current shell export BROWSERBASE_API_KEY="your_key" export BROWSERBASE_PROJECT_ID="your_project"
# Make sure SDK is installed pnpm add @browserbasehq/sdk-functions # Or use npx npx @browserbasehq/sdk-functions dev index.ts
Max execution time is 15 minutes Add specific timeouts to page operations Use waitForSelector instead of sleep
Check session.connectUrl is being used correctly Ensure you're using chromium.connectOverCDP() not chromium.launch()
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.