Jump to related tools in the same category or review the original source on GitHub.

Browser & Automation @peytoncasper Updated 2/26/2026

Functions OpenClaw Skill - ClawHub

Do you want your AI agent to automate Functions workflows? This free skill from ClawHub helps with browser & automation tasks without building custom tools from scratch.

What this skill does

Guide Claude through deploying serverless browser automation using the official bb CLI

Install

npx clawhub@latest install functions

Full SKILL.md

Open original
namedescription
functionsGuide Claude through deploying serverless browser automation using the official bb CLI

Browserbase Functions Skill

Guide Claude through deploying serverless browser automation using the official bb CLI.

When to Use

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

Prerequisites

1. Get Credentials

Get API key and Project ID from: https://browserbase.com/settings

2. Set Environment Variables

Set directly:

export BROWSERBASE_API_KEY="your_api_key"
export BROWSERBASE_PROJECT_ID="your_project_id"

Creating a Function Project

1. Initialize with Official CLI

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

2. Add Credentials to .env

# 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

3. Install Dependencies

pnpm install

Function Structure

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

Development Workflow

1. Start Dev Server

pnpm bb dev index.ts

Server runs at http://127.0.0.1:14113

2. Test Locally

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"}}'

3. Iterate

The dev server auto-reloads on file changes. Use console.log() for debugging - output appears in the terminal.

Deploying

Publish to Browserbase

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.

Invoking Deployed Functions

Via curl

# 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"

Via Code

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);
  }
}

Common Patterns

Parameterized Scraping

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 };
});

With Authentication

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 };
});

Error Handling

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' 
    };
  }
});

CLI Reference

Command Description
pnpm dlx @browserbasehq/sdk-functions init <name> Create new project
pnpm bb dev <file> Start local dev server
pnpm bb publish <file> Deploy to Browserbase

Troubleshooting

"Missing API key"

# Check .env file has credentials
cat .env

# Or set for current shell
export BROWSERBASE_API_KEY="your_key"
export BROWSERBASE_PROJECT_ID="your_project"

Dev server won't start

# Make sure SDK is installed
pnpm add @browserbasehq/sdk-functions

# Or use npx
npx @browserbasehq/sdk-functions dev index.ts

Function times out

  • Max execution time is 15 minutes
  • Add specific timeouts to page operations
  • Use waitForSelector instead of sleep

Can't connect to browser

  • Check session.connectUrl is being used correctly
  • Ensure you're using chromium.connectOverCDP() not chromium.launch()
Original URL: https://github.com/openclaw/skills/blob/main/skills/peytoncasper/functions

Related skills

If this matches your use case, these are close alternatives in the same category.