docs blog library
github

Browser Use

The browser tools let an agent open a page in a real headless Chrome, read it, and act on it: follow links, fill forms, choose options, and sign in. Use them for pages that need JavaScript or a session. For a single readable page, web_fetch is lighter.

The tools are off until you enable them for an agent. Run jazz agent edit <agent> and enable Browser in the tool selection, or add the tool names to the agent’s config.tools:

{
  "tools": [
    "browser_navigate",
    "browser_back",
    "browser_snapshot",
    "browser_screenshot",
    "browser_act",
    "browser_close"
  ]
}

They load on demand: the agent finds them with search_tools when a task needs a real browser, so enabling them adds nothing to a turn that never browses.

How the agent uses it

Open https://news.ycombinator.com, read the top five stories, and open the first
comment thread.

The agent calls browser_navigate to open a URL, then browser_snapshot to read the page. A snapshot is a text outline of headings, text, and controls. Every link, button, field, and other interactive element ends with a ref such as [ref=e3]:

- heading "Sign in" [level=1]
- textbox "Email" [ref=e1]
- textbox "Password" [ref=e2]
- button "Continue" [ref=e3]

browser_act takes those refs to click, type, choose an option, or press a key. After the page changes, the agent takes a new snapshot. browser_screenshot saves a PNG and returns its path, which the agent passes to analyze_media when layout matters more than text.

ToolRiskWhat it does
browser_navigatelow-riskOpen an http(s) URL.
browser_backlow-riskGo back one page.
browser_snapshotread-onlyRead the page as a text outline with refs.
browser_screenshotlow-riskSave a PNG of the page and return its path.
browser_acthigh-riskClick, type, choose an option, or press a key. Gated by approval.
browser_closeread-onlyClose the browser and discard its cookies. The next call reopens it.

Clicking and typing can submit a form, so browser_act is gated like write_file. In an unattended run it parks for approval instead of acting. See Approvals.

Signing in

Collect the password with ask_user_secret. The agent receives a placeholder, passes it as the text of a browser_act type action, and Jazz substitutes the value only after you approve. The approval names the page, and Jazz enters the secret only on an https page or one served from this machine.

Which browser

Signed-in pages. On the launch path (3), the browser starts on a private snapshot of your actual profile — a copy-on-write clone, so a multi-gigabyte profile takes a few seconds. Cookies and logins carry over: the agent can read pages you are signed into without you doing anything. The clone is private, so your live profile is never touched while your browser is open; it is deleted when the run ends. Works with your default Chromium-based browser (Google Chrome, Brave, Arc/Dia, and others). Set browser.headless to false to watch the launched browser in a visible window instead of headless. If a profile cannot be found or cloned, the run falls back to a blank one.

Jazz drives a browser in this order, with no setup required:

  1. A configured endpoint (only if you set one): browser.endpoint in your global config points the browser tools at any running browser that speaks the Chrome DevTools Protocol, http(s):// or ws(s)://. Everything the agent reads and types then reaches that browser’s host, so point it only at a browser you control.
  2. A browser you run on the local DevTools port (http://127.0.0.1:9222). Start any Chromium-based browser with --remote-debugging-port=9222 and the agent drives it: headed, with your profile, and able to adopt tabs you already have open via browser_adopt_tab.
  3. A launched browser, when nothing listens on the port. Jazz launches the one you actually use: your system default web browser when it is Chromium-based (Arc, Edge, Opera, …), otherwise Google Chrome. Set PUPPETEER_EXECUTABLE_PATH to force a specific binary. The browser starts on the first call, uses a fresh temporary profile, and is closed, with the profile deleted, when the run ends. A run has one tab, and pop-ups are refused. If no Chromium-based browser can be found at all, the tools say so and point you at installing Google Chrome.

For example, Lightpanda is a lightweight browser that starts in milliseconds. Run lightpanda serve --host 127.0.0.1 --port 9222, then set:

{ "browser": { "endpoint": "ws://127.0.0.1:9222" } }

Reading pages, typing, choosing options, and clicking work there. A browser without a full layout engine clicks through the element itself, and pages that depend on rendering or anti-bot checks may behave differently from Chrome.

Flagged pages

Some pages deserve a second look before the agent types into them. Jazz flags a page when its own structure shows a password field or payment card fields. A flagged page changes two things:

  • browser_snapshot opens with a warning line, such as “Warning: this page has a password field.”
  • browser_act asks you on every call there, even under the high-risk policy or an allowlist, and the approval repeats the warning.

A flag only adds scrutiny. Nothing lowers a risk, skips an approval, or clears the untrusted-content marking. Fields inside a frame from another site are not seen by this check.

An enabled plugin can add flags, for a page that may be a human check or whose labels address an AI agent, and can reorder a snapshot so the elements relevant to your request come first under “Likely relevant to your request:”. It cannot hide an element: the whole outline follows. Both hooks are advisory, time-limited, and fall back to the plain behavior on any error or abstention. See Browser page hooks.

What the page can reach

Every request a page makes, including images, scripts, and redirects, is held to the same rules as web_fetch and read_pdf: public addresses only, unless the host is in network.allowPrivateHosts. A page cannot reach localhost, your local network, or the cloud metadata address through its own scripts. With a URL list in network.httpApproval, the browser loads only matching URLs and the origins of pages it opened from them. file: URLs are refused.

What a page shows the agent is another party’s text. It arrives inside the untrusted-content envelope and marks the run as having read external content, so outbound tools stop auto-approving afterwards. See Browser safety for what the isolation does and does not cover.

Limits

  • One snapshot call shows at most 24,000 characters. A longer page ends with a note naming the startLine that continues it, and refs stay valid across those calls. The outline of a whole page stops at 240,000 characters.
  • One page action waits at most 15 seconds, and a navigation 30 seconds.
  • Downloads are disabled where the browser supports it, and there are no file uploads.
  • WebSocket and WebRTC traffic from a page is not covered by the request rules above.

machine-readable: /docs/concepts/browser-use.md · /llms.txt · /llms-full.txt