Browser Agent
The browserless_agent tool turns any MCP-compatible AI assistant into a browser-using agent. Unlike stateless scraping tools, the agent keeps a browser session across tool calls and exposes a snapshot-based protocol so the model can reason about what's on the page and drive it step by step.
Use it when a single scrape isn't enough — filling forms, logging in, clicking through multi-step flows, paginating search results, interacting with consent dialogs, or any task that needs the browser's state to survive between turns.
- Set up the Browserless MCP Server in your MCP client (Claude Desktop, Cursor, VS Code, Windsurf, Claude Code, etc.)
How it works
The agent follows the classic ReAct loop — Reason → Act → Observe:
- goto — navigate to a URL
- snapshot — capture every interactive and informational element on the page (buttons, links, inputs, headings, images with alt text) as a compact list with stable selectors
- plan — the model reads the snapshot and decides what to do
- act —
click,type,select,scroll, etc., using selectors taken directly from the snapshot - re-snapshot whenever the page changes (navigation, form submission)
- Repeat until the task is done, then close
The browser session means the browser keeps cookies, local storage, and navigation history across commands. State doesn't reset between tool calls — you can log in once and keep interacting with authenticated pages.
Available methods
Navigation
| Method | Purpose |
|---|---|
goto { url, waitUntil? } | Navigate to a URL. Defaults to waitUntil: "domcontentloaded". |
back { waitUntil? } | Go back in browser history. |
forward { waitUntil? } | Go forward in browser history. |
reload { waitUntil? } | Reload the current page. |
Observation
| Method | Purpose |
|---|---|
snapshot { maxElements?, full?, targetId? } | Capture the page as a list of interactive + informational elements with selectors. The first snapshot is complete; later ones return only what changed since the previous snapshot. Pass full: true to get the complete element list again. targetId snapshots a background tab without switching to it. |
text { selector? } | Extract the text of a specific element (or the whole page). |
html { selector? } | Get the raw HTML of a section (or the whole page). |
screenshot { fullPage?, selector?, clip?, type?, quality?, toDisk? } | Capture the page, an element, or a region as an image. selector, clip, and fullPage are mutually exclusive. toDisk: true saves the file and returns a file reference instead of inline image data (see Files for how references work per transport). |
evaluate { content } | Run arbitrary JavaScript in the page context (IIFE syntax). |
Interaction
| Method | Purpose |
|---|---|
click { selector } | Click an element. |
type { selector, text } | Type text into an input. |
select { selector, value } | Choose an option in a <select>. |
checkbox { selector, checked? } | Toggle a checkbox (preferred over click for checkboxes). |
hover { selector } | Hover over an element. |
scroll { selector?, direction? } | Scroll the page or a specific element. |
Secrets and CAPTCHAs
| Method | Purpose |
|---|---|
loadSecret { ref, selector? } | Inject a credential from a secrets vault (for example an op:// reference) into an input. The value is resolved server-side and typed into the field, so it never enters the model's context. Use this instead of type for vault-managed usernames and passwords. |
solve { type?, timeout?, wait? } | Solve a CAPTCHA on the page. Auto-detects the type when omitted; supports Cloudflare, reCAPTCHA (v2/v3), GeeTest, DataDome, Akamai, and more. Experimental and cloud-only: self-hosted Enterprise deployments lack the solver backend. |
Files
| Method | Purpose |
|---|---|
uploadFile { selector, files } | Attach files to an <input type="file">. Each file comes from a local path (stdio mode), a download handle, or inline base64 content. Combined size is capped (10MB default, 50MB max). |
getDownloads | List the files the page has downloaded, returned as file references you can pass back to uploadFile or save locally. |
File references are transport-specific. In stdio (local) mode they're plain filesystem paths. Over HTTP each file comes with two references: a single-use download URL for saving the bytes, and a browserless-download://<id> handle for uploadFile. The download URL is consumed on first use, so don't pass it as an upload handle; use the browserless-download:// handle instead.
Tabs
The session isn't limited to a single page. Sites that open results in new tabs (external links, OAuth popups, print views) stay reachable:
| Method | Purpose |
|---|---|
getTabs | List every open tab with its targetId, URL, and title. |
switchTab { targetId } | Make another tab the active one. |
createTab { url?, activate?, waitUntil? } | Open a new tab. Pass activate: false to open it in the background and keep the current tab active. waitUntil applies only when activating; defaults to "domcontentloaded". |
closeTab { targetId } | Close a specific tab. |
Waiting
| Method | Purpose |
|---|---|
waitForSelector { selector, timeout? } | Wait for a DOM element to appear. |
waitForNavigation { timeout? } | Wait for a page navigation to complete. |
waitForTimeout { time } | Wait for a fixed duration (ms). |
waitForRequest { url?, method?, timeout? } | Wait for a network request matching a URL glob. |
waitForResponse { url?, statuses?, timeout? } | Wait for a network response matching a URL glob and/or status codes. |
Session
| Method | Purpose |
|---|---|
liveURL { timeout?, interactable?, quality?, type?, resizable? } | Open a shareable live view of the browser that a human can watch or interact with. |
close | End the browser session. |
Batching
When multiple actions share the same page state (for example filling a form), they can be batched into a single tool call using the commands array. This is significantly faster than invoking the tool once per step.
{
"commands": [
{ "method": "type", "params": { "selector": "input#email", "text": "user@example.com" } },
{ "method": "type", "params": { "selector": "input#password", "text": "secret" } },
{ "method": "click", "params": { "selector": "input#remember-me" } },
{ "method": "click", "params": { "selector": "button[type='submit']" } }
]
}
Batching is safe for actions that don't change the page (type, hover, scroll, checkbox, non-navigating select). Page-changing actions — click on a link or submit button, goto, or anything that triggers navigation — should be the last command in the batch, because the next command would execute against the old DOM.
Error recovery
The agent protocol returns structured errors with codes the model can reason about:
| Code | Meaning | Typical recovery |
|---|---|---|
SELECTOR_NOT_FOUND | Element didn't exist or wasn't found in time | Try a deep selector (< selector) — the element may be in shadow DOM. Otherwise re-snapshot. |
NAVIGATION_TIMEOUT | Page didn't reach the requested ready state | Retry with a longer timeout or waitUntil: "domcontentloaded". |
TIMEOUT | Generic operation timeout | Retry with a longer timeout. |
BROWSER_CRASHED | Session is gone | The MCP client transparently reconnects — the agent just re-navigates. |
INVALID_PARAMS | Bad arguments | Not retryable. |
RATE_LIMITED | Too many requests | Wait and retry. |
When a selector isn't found, the error response also includes a fresh snapshot so the model can re-plan without an extra round trip.
When to use the agent vs. Smart Scraper
- Use
browserless_smartscraperwhen you need the content of a single page. It picks the best strategy (direct fetch → proxy → headless browser → CAPTCHA solving) and returns the content in your preferred format. - Use
browserless_agentwhen the task requires multiple turns, state, or interaction — logging in, filling forms, paginating, navigating menus, reacting to what's on the page.
Example tasks
Ask your AI assistant:
Find a French ratatouille recipe on Allrecipes with a 4-star rating or higher and at least 15 reviews. Note the variety of vegetables included and the overall cooking time.
Open Google Flights, search for a round-trip flight from New York to Tokyo departing March 10, 2026 and returning March 24, 2026, and list the five cheapest options.
Search for a local text-to-speech repository on GitHub updated in the last 10 days with at least 200 stars and summarize its main objective.
Go to FedEx. Calculate the shipping rates for a 10-pound package from Miami, FL to San Francisco, CA, and summarize prices and delivery dates.
FAQ & Troubleshooting
What is the Browserless browser agent MCP tool?
The browser agent tool gives AI models direct control of a browser session, allowing them to navigate, click, type, and extract information from web pages autonomously through natural language instructions.
How does the browser agent differ from REST API tools?
REST API tools call individual Browserless endpoints for specific tasks. The browser agent provides a live browser session where the AI can perform multi-step interactions, making it better suited for complex, dynamic workflows.
Can the browser agent handle login flows?
Yes. The browser agent can navigate to login pages, fill in credentials, handle multi-factor authentication prompts, and maintain session state across subsequent page interactions.
For sites you log into repeatedly, use Authenticated Profiles to save the login once and reuse it across sessions instead of logging in every time.