| name | browsing-the-web |
| description | MUST be used when you need to browse the web, interact with websites, or automate browser tasks. Efficient browser automation designed for agents — enables intuitive web navigation, form filling, clicking buttons, taking screenshots, data scraping, and testing web apps through accessibility-based workflows using the agent-browser CLI. Triggers on: browse website, visit URL, open webpage, fill form, click button, take screenshot, scrape data, web automation, interact with website, login to site, test web app, extract data from page, navigate to URL, open a website, automate browser actions. |
| allowed-tools | Bash(dev-browser:*) |
Dev Browser
A CLI for controlling browsers with sandboxed JavaScript scripts.
Usage
Run dev-browser --help to learn more.
LLM USAGE GUIDE:
Write small, focused scripts. Each script should do ONE thing: navigate, click, fill, or check.
End each script by logging the state you need for the next decision.
Use descriptive page names like "login", "checkout", or "results" instead of "page1".
Named pages from browser.getPage("name") persist between script runs, so you usually do not need to re-navigate.
Inside page.evaluate(...), write plain JavaScript only - no TypeScript syntax in the browser context.
Quick inspection:
dev-browser --connect <<'EOF'
const tabs = await browser.listPages();
console.log(JSON.stringify(tabs, null, 2));
EOF
dev-browser --connect <<'EOF'
const page = await browser.getPage("TARGET_ID_HERE");
console.log(JSON.stringify({
url: page.url(),
title: await page.title(),
}, null, 2));
EOF
AI snapshots for element discovery:
dev-browser <<'EOF'
const page = await browser.getPage("main");
const result = await page.snapshotForAI();
console.log(result.full);
// Returns { full: string, incremental?: string }.
// Optional args: { track?: string, depth?: number, timeout?: number }.
// Read result.full to identify the right element.
// Then interact with it using Playwright:
// await page.getByRole("button", { name: "Continue" }).click();
// Re-run page.snapshotForAI({ track: "main" }) after the page changes.
EOF
Choosing your approach:
- Unknown pages: use
page.snapshotForAI() first to discover the page, then interact based on what you find.
- Known pages/selectors: skip the snapshot and use direct Playwright selectors like
page.click(), page.fill(), or page.locator() for faster, more reliable automation.
Screenshots for visual state:
dev-browser <<'EOF'
const page = await browser.getPage("main");
const buf = await page.screenshot();
const path = await saveScreenshot(buf, "debug.png");
console.log(path);
EOF
Waiting patterns:
dev-browser <<'EOF'
const page = await browser.getPage("search-results");
await page.waitForSelector(".results");
await page.waitForURL("**/success");
console.log(JSON.stringify({
url: page.url(),
title: await page.title(),
}, null, 2));
EOF
Error recovery:
If a script fails, the page usually stays where it stopped.
Reconnect to the same page name, take a screenshot, and log the URL/title:
dev-browser <<'EOF'
const page = await browser.getPage("checkout");
const path = await saveScreenshot(await page.screenshot(), "debug.png");
console.log(JSON.stringify({
screenshot: path,
url: page.url(),
title: await page.title(),
}, null, 2));
EOF
Common Playwright Page methods:
- page.goto(url) Navigate to a URL
- page.title() Get the current page title
- page.url() Get the current URL
- page.snapshotForAI(options) Get an AI-optimized snapshot; returns { full, incremental? }
Options: { track?: string, depth?: number, timeout?: number }
- page.getByRole(role, { name }) Target elements discovered from the snapshot
- page.textContent(selector) Get the text content of an element
- page.innerHTML(selector) Get the inner HTML of an element
- page.fill(selector, value) Fill an input field
- page.click(selector) Click an element
- page.type(selector, text) Type text character by character
- page.press(selector, key) Press a key such as Enter or Tab
- page.waitForSelector(selector) Wait for an element to appear
- page.waitForURL(url) Wait for navigation to a URL
- page.screenshot() Capture a screenshot buffer; save it with saveScreenshot(...)
- page.$$eval(selector, fn) Run a function on all matching elements
- page.$eval(selector, fn) Run a function on the first matching element
- page.evaluate(fn) Run JavaScript in the page context (plain JS only)
- page.locator(selector) Create a locator for chained actions
Connecting to a running Chrome instance:
Auto-discover Chrome with debugging enabled:
dev-browser --connect <<'EOF'
const page = await browser.getPage("main");
console.log(await page.title());
EOF
Connect to a specific CDP endpoint:
dev-browser --connect http://localhost:9222 <<'EOF'
const page = await browser.getPage("main");
console.log(await page.title());
EOF
To launch Chrome with debugging enabled:
chrome.exe --remote-debugging-port=9222
google-chrome --remote-debugging-port=9222
Or visit chrome://inspect/#remote-debugging to configure.
Tips:
- Use
console.log(JSON.stringify(...)) for structured output.
- Prefer
page.snapshotForAI() for structure; use screenshots when visual layout or styling matters.
- Keep page names stable across scripts so you can resume work after failures.
- Each
--browser name maps to a separate daemon-managed browser instance.
- Use
--connect to attach to an existing browser; omit the URL to auto-discover Chrome with debugging enabled.
- Use short timeouts (
--timeout 10) so scripts fail fast instead of hanging on missing elements.
- Add
--headless for unattended automation; omit it when you want to watch the browser window.