{
  "schemaVersion": "1.0",
  "item": {
    "slug": "functions",
    "name": "Functions",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/peytoncasper/functions",
    "canonicalUrl": "https://clawhub.ai/peytoncasper/functions",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/functions",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=functions",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "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."
        },
        {
          "label": "Upgrade existing",
          "body": "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."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "functions",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-03T11:42:55.021Z",
      "expiresAt": "2026-05-10T11:42:55.021Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=functions",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=functions",
        "contentDisposition": "attachment; filename=\"functions-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "functions"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/functions"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/functions",
    "agentPageUrl": "https://openagent3.xyz/skills/functions/agent",
    "manifestUrl": "https://openagent3.xyz/skills/functions/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/functions/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "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."
      },
      {
        "label": "Upgrade existing",
        "body": "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."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Browserbase Functions Skill",
        "body": "Guide Claude through deploying serverless browser automation using the official bb CLI."
      },
      {
        "title": "When to Use",
        "body": "Use this skill when:\n\nUser wants to deploy automation to run on a schedule\nUser needs a webhook endpoint for browser automation\nUser wants to run automation in the cloud (not locally)\nUser asks about Browserbase Functions"
      },
      {
        "title": "1. Get Credentials",
        "body": "Get API key and Project ID from: https://browserbase.com/settings"
      },
      {
        "title": "2. Set Environment Variables",
        "body": "Set directly:\n\nexport BROWSERBASE_API_KEY=\"your_api_key\"\nexport BROWSERBASE_PROJECT_ID=\"your_project_id\""
      },
      {
        "title": "1. Initialize with Official CLI",
        "body": "pnpm dlx @browserbasehq/sdk-functions init my-function\ncd my-function\n\nThis creates:\n\nmy-function/\n├── package.json\n├── index.ts        # Your function code\n└── .env            # Add credentials here"
      },
      {
        "title": "2. Add Credentials to .env",
        "body": "# Copy from stored credentials\necho \"BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY\" >> .env\necho \"BROWSERBASE_PROJECT_ID=$BROWSERBASE_PROJECT_ID\" >> .env\n\nOr manually edit .env:\n\nBROWSERBASE_API_KEY=your_api_key\nBROWSERBASE_PROJECT_ID=your_project_id"
      },
      {
        "title": "3. Install Dependencies",
        "body": "pnpm install"
      },
      {
        "title": "Function Structure",
        "body": "import { defineFn } from \"@browserbasehq/sdk-functions\";\nimport { chromium } from \"playwright-core\";\n\ndefineFn(\"my-function\", async (context) => {\n  const { session, params } = context;\n  \n  // Connect to browser\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  // Your automation\n  await page.goto(params.url || \"https://example.com\");\n  const title = await page.title();\n  \n  // Return JSON-serializable result\n  return { success: true, title };\n});\n\nKey objects:\n\ncontext.session.connectUrl - CDP endpoint to connect Playwright\ncontext.params - Input parameters from invocation"
      },
      {
        "title": "1. Start Dev Server",
        "body": "pnpm bb dev index.ts\n\nServer runs at http://127.0.0.1:14113"
      },
      {
        "title": "2. Test Locally",
        "body": "curl -X POST http://127.0.0.1:14113/v1/functions/my-function/invoke \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"params\": {\"url\": \"https://news.ycombinator.com\"}}'"
      },
      {
        "title": "3. Iterate",
        "body": "The dev server auto-reloads on file changes. Use console.log() for debugging - output appears in the terminal."
      },
      {
        "title": "Publish to Browserbase",
        "body": "pnpm bb publish index.ts\n\nOutput:\n\nFunction published successfully\nBuild ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\nFunction ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\nSave the Function ID - you need it to invoke."
      },
      {
        "title": "Via curl",
        "body": "# Start invocation\ncurl -X POST \"https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"x-bb-api-key: $BROWSERBASE_API_KEY\" \\\n  -d '{\"params\": {\"url\": \"https://example.com\"}}'\n\n# Response: {\"id\": \"INVOCATION_ID\"}\n\n# Poll for result\ncurl \"https://api.browserbase.com/v1/functions/invocations/INVOCATION_ID\" \\\n  -H \"x-bb-api-key: $BROWSERBASE_API_KEY\""
      },
      {
        "title": "Via Code",
        "body": "async function invokeFunction(functionId: string, params: object) {\n  // Start invocation\n  const invokeRes = await fetch(\n    `https://api.browserbase.com/v1/functions/${functionId}/invoke`,\n    {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'x-bb-api-key': process.env.BROWSERBASE_API_KEY!,\n      },\n      body: JSON.stringify({ params }),\n    }\n  );\n  const { id: invocationId } = await invokeRes.json();\n\n  // Poll until complete\n  while (true) {\n    await new Promise(r => setTimeout(r, 5000));\n    \n    const statusRes = await fetch(\n      `https://api.browserbase.com/v1/functions/invocations/${invocationId}`,\n      { headers: { 'x-bb-api-key': process.env.BROWSERBASE_API_KEY! } }\n    );\n    const result = await statusRes.json();\n    \n    if (result.status === 'COMPLETED') return result.results;\n    if (result.status === 'FAILED') throw new Error(result.error);\n  }\n}"
      },
      {
        "title": "Parameterized Scraping",
        "body": "defineFn(\"scrape\", async ({ session, params }) => {\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  await page.goto(params.url);\n  await page.waitForSelector(params.selector);\n  \n  const items = await page.$$eval(params.selector, els => \n    els.map(el => el.textContent?.trim())\n  );\n  \n  return { url: params.url, items };\n});"
      },
      {
        "title": "With Authentication",
        "body": "defineFn(\"authenticated-action\", async ({ session, params }) => {\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  // Login\n  await page.goto(\"https://example.com/login\");\n  await page.fill('[name=\"email\"]', params.email);\n  await page.fill('[name=\"password\"]', params.password);\n  await page.click('button[type=\"submit\"]');\n  await page.waitForURL('**/dashboard');\n  \n  // Do authenticated work\n  const data = await page.textContent('.user-data');\n  return { data };\n});"
      },
      {
        "title": "Error Handling",
        "body": "defineFn(\"safe-scrape\", async ({ session, params }) => {\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  try {\n    await page.goto(params.url, { timeout: 30000 });\n    await page.waitForSelector(params.selector, { timeout: 10000 });\n    \n    const data = await page.textContent(params.selector);\n    return { success: true, data };\n  } catch (error) {\n    return { \n      success: false, \n      error: error instanceof Error ? error.message : 'Unknown error' \n    };\n  }\n});"
      },
      {
        "title": "CLI Reference",
        "body": "CommandDescriptionpnpm dlx @browserbasehq/sdk-functions init <name>Create new projectpnpm bb dev <file>Start local dev serverpnpm bb publish <file>Deploy to Browserbase"
      },
      {
        "title": "\"Missing API key\"",
        "body": "# Check .env file has credentials\ncat .env\n\n# Or set for current shell\nexport BROWSERBASE_API_KEY=\"your_key\"\nexport BROWSERBASE_PROJECT_ID=\"your_project\""
      },
      {
        "title": "Dev server won't start",
        "body": "# Make sure SDK is installed\npnpm add @browserbasehq/sdk-functions\n\n# Or use npx\nnpx @browserbasehq/sdk-functions dev index.ts"
      },
      {
        "title": "Function times out",
        "body": "Max execution time is 15 minutes\nAdd specific timeouts to page operations\nUse waitForSelector instead of sleep"
      },
      {
        "title": "Can't connect to browser",
        "body": "Check session.connectUrl is being used correctly\nEnsure you're using chromium.connectOverCDP() not chromium.launch()"
      }
    ],
    "body": "Browserbase Functions Skill\n\nGuide Claude through deploying serverless browser automation using the official bb CLI.\n\nWhen to Use\n\nUse this skill when:\n\nUser wants to deploy automation to run on a schedule\nUser needs a webhook endpoint for browser automation\nUser wants to run automation in the cloud (not locally)\nUser asks about Browserbase Functions\nPrerequisites\n1. Get Credentials\n\nGet API key and Project ID from: https://browserbase.com/settings\n\n2. Set Environment Variables\n\nSet directly:\n\nexport BROWSERBASE_API_KEY=\"your_api_key\"\nexport BROWSERBASE_PROJECT_ID=\"your_project_id\"\n\nCreating a Function Project\n1. Initialize with Official CLI\npnpm dlx @browserbasehq/sdk-functions init my-function\ncd my-function\n\n\nThis creates:\n\nmy-function/\n├── package.json\n├── index.ts        # Your function code\n└── .env            # Add credentials here\n\n2. Add Credentials to .env\n# Copy from stored credentials\necho \"BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY\" >> .env\necho \"BROWSERBASE_PROJECT_ID=$BROWSERBASE_PROJECT_ID\" >> .env\n\n\nOr manually edit .env:\n\nBROWSERBASE_API_KEY=your_api_key\nBROWSERBASE_PROJECT_ID=your_project_id\n\n3. Install Dependencies\npnpm install\n\nFunction Structure\nimport { defineFn } from \"@browserbasehq/sdk-functions\";\nimport { chromium } from \"playwright-core\";\n\ndefineFn(\"my-function\", async (context) => {\n  const { session, params } = context;\n  \n  // Connect to browser\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  // Your automation\n  await page.goto(params.url || \"https://example.com\");\n  const title = await page.title();\n  \n  // Return JSON-serializable result\n  return { success: true, title };\n});\n\n\nKey objects:\n\ncontext.session.connectUrl - CDP endpoint to connect Playwright\ncontext.params - Input parameters from invocation\nDevelopment Workflow\n1. Start Dev Server\npnpm bb dev index.ts\n\n\nServer runs at http://127.0.0.1:14113\n\n2. Test Locally\ncurl -X POST http://127.0.0.1:14113/v1/functions/my-function/invoke \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"params\": {\"url\": \"https://news.ycombinator.com\"}}'\n\n3. Iterate\n\nThe dev server auto-reloads on file changes. Use console.log() for debugging - output appears in the terminal.\n\nDeploying\nPublish to Browserbase\npnpm bb publish index.ts\n\n\nOutput:\n\nFunction published successfully\nBuild ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\nFunction ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\n\nSave the Function ID - you need it to invoke.\n\nInvoking Deployed Functions\nVia curl\n# Start invocation\ncurl -X POST \"https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"x-bb-api-key: $BROWSERBASE_API_KEY\" \\\n  -d '{\"params\": {\"url\": \"https://example.com\"}}'\n\n# Response: {\"id\": \"INVOCATION_ID\"}\n\n# Poll for result\ncurl \"https://api.browserbase.com/v1/functions/invocations/INVOCATION_ID\" \\\n  -H \"x-bb-api-key: $BROWSERBASE_API_KEY\"\n\nVia Code\nasync function invokeFunction(functionId: string, params: object) {\n  // Start invocation\n  const invokeRes = await fetch(\n    `https://api.browserbase.com/v1/functions/${functionId}/invoke`,\n    {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'x-bb-api-key': process.env.BROWSERBASE_API_KEY!,\n      },\n      body: JSON.stringify({ params }),\n    }\n  );\n  const { id: invocationId } = await invokeRes.json();\n\n  // Poll until complete\n  while (true) {\n    await new Promise(r => setTimeout(r, 5000));\n    \n    const statusRes = await fetch(\n      `https://api.browserbase.com/v1/functions/invocations/${invocationId}`,\n      { headers: { 'x-bb-api-key': process.env.BROWSERBASE_API_KEY! } }\n    );\n    const result = await statusRes.json();\n    \n    if (result.status === 'COMPLETED') return result.results;\n    if (result.status === 'FAILED') throw new Error(result.error);\n  }\n}\n\nCommon Patterns\nParameterized Scraping\ndefineFn(\"scrape\", async ({ session, params }) => {\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  await page.goto(params.url);\n  await page.waitForSelector(params.selector);\n  \n  const items = await page.$$eval(params.selector, els => \n    els.map(el => el.textContent?.trim())\n  );\n  \n  return { url: params.url, items };\n});\n\nWith Authentication\ndefineFn(\"authenticated-action\", async ({ session, params }) => {\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  // Login\n  await page.goto(\"https://example.com/login\");\n  await page.fill('[name=\"email\"]', params.email);\n  await page.fill('[name=\"password\"]', params.password);\n  await page.click('button[type=\"submit\"]');\n  await page.waitForURL('**/dashboard');\n  \n  // Do authenticated work\n  const data = await page.textContent('.user-data');\n  return { data };\n});\n\nError Handling\ndefineFn(\"safe-scrape\", async ({ session, params }) => {\n  const browser = await chromium.connectOverCDP(session.connectUrl);\n  const page = browser.contexts()[0]!.pages()[0]!;\n  \n  try {\n    await page.goto(params.url, { timeout: 30000 });\n    await page.waitForSelector(params.selector, { timeout: 10000 });\n    \n    const data = await page.textContent(params.selector);\n    return { success: true, data };\n  } catch (error) {\n    return { \n      success: false, \n      error: error instanceof Error ? error.message : 'Unknown error' \n    };\n  }\n});\n\nCLI Reference\nCommand\tDescription\npnpm dlx @browserbasehq/sdk-functions init <name>\tCreate new project\npnpm bb dev <file>\tStart local dev server\npnpm bb publish <file>\tDeploy to Browserbase\nTroubleshooting\n\"Missing API key\"\n# Check .env file has credentials\ncat .env\n\n# Or set for current shell\nexport BROWSERBASE_API_KEY=\"your_key\"\nexport BROWSERBASE_PROJECT_ID=\"your_project\"\n\nDev server won't start\n# Make sure SDK is installed\npnpm add @browserbasehq/sdk-functions\n\n# Or use npx\nnpx @browserbasehq/sdk-functions dev index.ts\n\nFunction times out\nMax execution time is 15 minutes\nAdd specific timeouts to page operations\nUse waitForSelector instead of sleep\nCan't connect to browser\nCheck session.connectUrl is being used correctly\nEnsure you're using chromium.connectOverCDP() not chromium.launch()"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/peytoncasper/functions",
    "publisherUrl": "https://clawhub.ai/peytoncasper/functions",
    "owner": "peytoncasper",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/functions",
    "downloadUrl": "https://openagent3.xyz/downloads/functions",
    "agentUrl": "https://openagent3.xyz/skills/functions/agent",
    "manifestUrl": "https://openagent3.xyz/skills/functions/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/functions/agent.md"
  }
}