Skip to main content
browse Complete guide for creating and deploying browser automation functions using the stagehand CLI
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Métiers associés SOC
Basé sur la classification professionnelle SOC
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/duclm1x1/Dive-Ai --skill browseLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt Persistent memory system for AI agents following Model Context Protocol (MCP). Use for storing long-term memories across sessions, semantic search of past knowledge, building knowledge graphs, auto-injecting context, deduplicating memories, syncing to cloud storage. Essential for agents that need to remember decisions, solutions, preferences, and learned patterns over time.
Persistent memory system for AI agents following Model Context Protocol (MCP). Use for storing long-term memories across sessions, semantic search of past knowledge, building knowledge graphs, auto-injecting context, deduplicating memories, syncing to cloud storage. Essential for agents that need to remember decisions, solutions, preferences, and learned patterns over time.
Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers. Use when designing new APIs, reviewing API specifications, or establishing API design standards.
name browse description Complete guide for creating and deploying browser automation functions using the stagehand CLI homepage https://browserbase.com metadata {"moltbot":{"emoji":"🌐","requires":{"bins":["stagehand"],"env":["BROWSERBASE_API_KEY","BROWSERBASE_PROJECT_ID"]},"primaryEnv":"BROWSERBASE_API_KEY"}}
Browser Automation & Functions Skill
Complete guide for creating and deploying browser automation functions using the stagehand CLI.
When to Use
User wants to automate a website task
User needs to scrape data from a site
User wants to create a Browserbase Function
User wants to deploy automation to run on a schedule or via webhook
Prerequisites
Set Up Credentials
stagehand fn auth status
stagehand fn auth login
Complete Workflow
Step 1: Explore the Site Interactively
Start a local browser session to understand the site structure:
stagehand session create --local
stagehand goto https://example.com
stagehand snapshot
stagehand screenshot -o page.png
Test interactions manually:
stagehand click @0-5
stagehand fill @0-6 "value"
stagehand eval "document.querySelector('.price').textContent"
stagehand session end
Step 2: Initialize Function Project stagehand fn init my-automation
cd my-automation
package.json - Dependencies
.env - Credentials (from ~/.stagehand/config.json)
index.ts - Function template
tsconfig.json - TypeScript config
Step 3: ⚠️ FIX package.json IMMEDIATELY CRITICAL BUG : stagehand fn init generates incomplete package.json that causes deployment to fail with "No functions were built."
REQUIRED FIX - Update package.json before doing anything else:
{
"name" : "my-automation" ,
"version" : "1.0.0" ,
"description" : "My automation description" ,
"main" : "index.js" ,
"type" : "module" ,
"packageManager" : "pnpm@10.14.0" ,
"scripts" : {
"dev" : "pnpm bb dev index.ts" ,
"publish" : "pnpm bb publish index.ts"
} ,
"dependencies" : {
"@browserbasehq/sdk-functions" : "^0.0.5" ,
"playwright-core" : "^1.58.0"
} ,
"devDependencies" : {
"@types/node" : "^25.0.10" ,
"typescript" : "^5.9.3"
}
}
Key changes from generated file:
✅ Add description and main fields
✅ Add packageManager field
✅ Change "latest" to pinned versions like "^0.0.5"
✅ Add devDependencies with TypeScript and types
Step 4: Write Automation Code import { defineFn } from "@browserbasehq/sdk-functions" ;
import { chromium } from "playwright-core" ;
defineFn ("my-automation" , async (context) => {
const { session, params } = context;
console .log ("Connecting to browser session:" , session.id );
const browser = await chromium.connectOverCDP (session.connectUrl );
const page = browser.contexts ()[0 ]!.pages ()[0 ]!;
await page.goto ("https://example.com" );
await page.waitForLoadState ("domcontentloaded" );
const data = await page.evaluate (() => {
return Array .from (document .querySelectorAll ('.item' )).map (el => ({
title : el.querySelector ('.title' )?.textContent ,
value : el.querySelector ('.value' )?.textContent ,
}));
});
return {
success : true ,
count : data.length ,
data,
timestamp : new Date ().toISOString (),
};
});
context.session - Browser session info (id, connectUrl)
context.params - Input parameters from invocation
Return JSON-serializable data
15 minute max execution time
Step 5: Test Locally Server runs at http://127.0.0.1:14113
curl -X POST http://127.0.0.1:14113/v1/functions/my-automation/invoke \
-H "Content-Type: application/json" \
-d '{"params": {"url": "https://example.com"}}'
Dev server auto-reloads on file changes. Check terminal for logs.
Step 6: Deploy to Browserbase ✓ Build completed successfully
Build ID: xxx-xxx-xxx
Function ID: yyy-yyy-yyy ← Save this!
If you see "No functions were built" → Your package.json is incomplete (see Step 3).
Step 7: Test Production stagehand fn invoke <function-id> -p '{"param": "value"}'
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": {}}'
Complete Working Example: Hacker News Scraper import { defineFn } from "@browserbasehq/sdk-functions" ;
import { chromium } from "playwright-core" ;
defineFn ("hn-scraper" , async (context) => {
const { session } = context;
console .log ("Connecting to browser session:" , session.id );
const browser = await chromium.connectOverCDP (session.connectUrl );
const page = browser.contexts ()[0 ]!.pages ()[0 ]!;
await page.goto ("https://news.ycombinator.com" );
await page.waitForLoadState ("domcontentloaded" );
const stories = await page.evaluate (() => {
const storyRows = Array .from (document .querySelectorAll ('.athing' )).slice (0 , 10 );
return storyRows.map ((row ) => {
const titleLine = row.querySelector ('.titleline a' );
const subtext = row.nextElementSibling ?.querySelector ('.subtext' );
const commentsLink = Array .from (subtext?.querySelectorAll ('a' ) || []).pop ();
return {
rank : row.querySelector ('.rank' )?.textContent ?.replace ('.' , '' ) || '' ,
title : titleLine?.textContent || '' ,
url : titleLine?.getAttribute ('href' ) || '' ,
points : subtext?.querySelector ('.score' )?.textContent ?.replace (' points' , '' ) || '0' ,
author : subtext?.querySelector ('.hnuser' )?.textContent || '' ,
time : subtext?.querySelector ('.age' )?.textContent || '' ,
comments : commentsLink?.textContent ?.replace (/\u00a0comments?/ , '' ).trim () || '0' ,
id : row.id ,
};
});
});
return {
success : true ,
count : stories.length ,
stories,
timestamp : new Date ().toISOString (),
};
});
Common Patterns
Parameterized Scraping defineFn ("scrape" , async (context) => {
const { session, params } = context;
const { url, selector } = params;
const browser = await chromium.connectOverCDP (session.connectUrl );
const page = browser.contexts ()[0 ]!.pages ()[0 ]!;
await page.goto (url);
const data = await page.$$eval(selector, els =>
els.map (el => el.textContent )
);
return { url, data };
});
Authentication defineFn ("auth-action" , async (context) => {
const { session, params } = context;
const { username, password } = params;
const browser = await chromium.connectOverCDP (session.connectUrl );
const page = browser.contexts ()[0 ]!.pages ()[0 ]!;
await page.goto ("https://example.com/login" );
await page.fill ('input[name="email"]' , username);
await page.fill ('input[name="password"]' , password);
await page.click ('button[type="submit"]' );
await page.waitForURL ("**/dashboard" );
const data = await page.textContent ('.user-data' );
return { success : true , data };
});
Multi-Page Workflow defineFn ("multi-page" , async (context) => {
const { session, params } = context;
const browser = await chromium.connectOverCDP (session.connectUrl );
const page = browser.contexts ()[0 ]!.pages ()[0 ]!;
const results = [];
for (const url of params.urls ) {
await page.goto (url);
await page.waitForLoadState ("domcontentloaded" );
const title = await page.title ();
results.push ({ url, title });
}
return { results };
});
Troubleshooting
🔴 "No functions were built. Please check your entrypoint and function exports." Cause: Generated package.json from stagehand fn init is incomplete.
Update package.json (see Step 3 above)
Add all required fields: description, main, packageManager
Change "latest" to pinned versions like "^0.0.5"
Add devDependencies section with TypeScript and types
Run pnpm install
Try deploying again
Quick check: Compare your package.json to bitcoin-functions/package.json in the codebase.
Local dev server won't start
stagehand fn auth status
stagehand fn auth login
pnpm add -g @browserbasehq/sdk-functions
Function works locally but fails on deploy
Missing devDependencies (TypeScript won't compile)
Using "latest" instead of pinned versions
Missing required fields in package.json
Solution: Fix package.json as described in Step 3.
Cannot extract data from page
Take screenshot: stagehand screenshot -o debug.png
Get snapshot: stagehand snapshot
Use page.evaluate() to log what's in the DOM
Check if selectors match actual HTML structure
"Invocation timed out"
Functions have 15 minute max
Use specific waits instead of long sleeps
Check if page is actually loading
Best Practices
✅ Fix package.json immediately after stagehand fn init
✅ Explore interactively first - Use local browser session to understand site
✅ Test manually - Verify each step works before writing code
✅ Test locally - Use dev server before deploying
✅ Return meaningful data - Include timestamps, counts, URLs
✅ Handle errors gracefully - Try/catch around risky operations
✅ Use specific selectors - Prefer data attributes over CSS classes
✅ Add logging - console.log() helps debug deployed functions
✅ Validate parameters - Check params before using
✅ Set reasonable timeouts - Don't wait forever
Quick Checklist
Code Fix Needed (For Maintainers) File: /src/commands/functions.ts
Lines: 146-158
Function: initFunction()
Replace the current packageJson object with:
const packageJson = {
name,
version : '1.0.0' ,
description : `${name} function` ,
main : 'index.js' ,
type : 'module' ,
packageManager : 'pnpm@10.14.0' ,
scripts : {
dev : 'pnpm bb dev index.ts' ,
publish : 'pnpm bb publish index.ts' ,
},
dependencies : {
'@browserbasehq/sdk-functions' : '^0.0.5' ,
'playwright-core' : '^1.58.0' ,
},
devDependencies : {
'@types/node' : '^25.0.10' ,
'typescript' : '^5.9.3' ,
},
};
This will eliminate the "No functions were built" error for all new projects.