Reference

Command Reference

This is the complete cheat sheet of every chrome-use command, alias, and flag. It's organized by command group so it's easy to scan and verify. To get a feel for the overall rhythm first, read the Core Loop; when a command doesn't work, check Troubleshooting.

ℹ️ Conventions
The @e1, @e2 in interaction commands are element references (refs) from snapshot output. Run snapshot -i first to get the refs, then act on them. Any command with a @ref always targets the tab that was active when the snapshot ran.

Navigation

Open, navigate, go back/forward, and close the browser. Without a URL, open just launches the browser and stops at about:blank — handy for registering network interceptors, cookies, or init scripts before the first real navigation.

navigation
# launch the browser only, no navigation; stops at about:blank
$ chrome-use open
# launch and navigate (aliases: goto, navigate); prepends https:// when no protocol
$ chrome-use open <url>
$ chrome-use back                # go back
$ chrome-use forward             # go forward
$ chrome-use reload              # reload
# SPA client-side navigation: auto-detects Next.js router.push, falls back to history.pushState
$ chrome-use pushstate <url>
$ chrome-use close               # close the browser (aliases: quit, exit)
$ chrome-use connect 9222        # connect over a CDP port
Blocked renderer recovery
With ab-connect 0.5.18 or newer, an explicit open or navigate whose renderer-scoped Page.navigate call times out is retried through Chrome's browser-level tab API. The command returns a warning and keeps the same session instead of restarting it.

You can line up all the pre-navigation setup in one shot with batch — launch cleanly, register interceptors / cookies in order, then navigate. This suits SSR-only debugging (block everything except --resource-type script), authenticating against a protected origin, or capturing a clean react suspense / vitals state.

pre-navigation batch
$ chrome-use batch \
    '["open"]' \
    '["network","route","*","--abort","--resource-type","script"]' \
    '["cookies","set","--curl","cookies.curl","--domain","localhost"]' \
    '["navigate","http://localhost:3000/target"]'

Snapshot (page analysis)

Interactive snapshots add a bounded context annotation for controls inside nearby articles, list items, rows, or groups identified by a heading or one distinct linked product name and one action control. Named product links omit repeated context when their sibling action carries it. It preserves local text such as product prices without changing accessible names or refs. Live status receipts also remain visible in interactive snapshots and action observations, with bounded text and explicit truncation. Context may be absent or marked truncated; use a scoped or full snapshot when a required detail is missing.

snapshot gives you a structured accessibility view of the page — the starting point for all interaction. snapshot -i is recommended: it lists only interactive elements, so the output is compact and every ref is present.

snapshot
$ chrome-use snapshot            # full accessibility tree
$ chrome-use snapshot -i         # interactive elements only (recommended)
$ chrome-use snapshot -c         # compact output
$ chrome-use snapshot -d 3       # limit depth to 3
$ chrome-use snapshot -i --dom   # actionable elements from a DOM walk (pierces shadow roots; automatic when the AX tree has no refs)
$ chrome-use snapshot -s "#main" # scope to a CSS selector
$ chrome-use snapshot -i -f "SSH|Save"   # keep matching lines + their ancestors (refs intact)
$ chrome-use snapshot -i --diff       # only what changed since the last snapshot
$ chrome-use snapshot -i --max-bytes 4000  # cut between nodes, report what was omitted + a cursor
$ chrome-use snapshot -i --max-bytes 4000 --from 70  # read on from where it stopped

Actions beyond a click

actions / do
$ chrome-use actions @e15   # what this element supports right now (read live)
$ chrome-use do @e15 expand  # perform one of exactly those; anything else is refused

expand / collapse, showMenu, increment / decrement and toggle, derived from the element's accessibility properties. The set is reported again afterwards, so a control that did not move cannot read as a success. See Interacting.

But only expand / collapse can be confirmed afterwards — the element must then offer the opposite action. For showMenu, toggle, increment and decrement the tree looks the same whether the control responded or ignored the click, so those are marked · rather than and carry confirmed: null in JSON — dispatched, outcome unknown. Read the page before treating one as done; never read null as success.

✅ Tip
snapshot -i only surfaces visible, interactive elements — it does not show hidden inputs or a control's actual submitted value. When a form "looks filled in" but won't pass validation, don't guess from the snapshot — inspect the DOM directly with eval.

Interactions

Drive the real browser with the @ref values from snapshot: click, type, check, drag, upload.

Drag mode follows the current session connection and target frame; an extension running in another Chrome profile does not change a launched browser’s drag mode.

interactions
$ chrome-use click @e1           # click
$ chrome-use click @e1 --new-tab # click and open in a new tab
$ chrome-use dblclick @e1        # double-click
$ chrome-use focus @e1           # focus the element
$ chrome-use fill @e2 "text"     # clear then type
$ chrome-use type @e2 "text"     # type directly (no clear)
$ chrome-use press Enter         # press a key (alias: key); ⚠ warns when the page has no listener for it
$ chrome-use press Control+a     # key combo
$ chrome-use keydown Shift       # hold a key down
$ chrome-use keyup Shift         # release a key
$ chrome-use hover @e1           # hover
$ chrome-use check @e1           # check a checkbox
$ chrome-use uncheck @e1         # uncheck
$ chrome-use select @e1 "value"   # pick a dropdown option
$ chrome-use select @e1 "a" "b"   # multi-select
$ chrome-use scroll down 500     # scroll the page (default down 300px)
$ chrome-use scrollintoview @e1  # scroll element into the viewport (alias: scrollinto)
$ chrome-use drag @e1 @e2        # drag and drop
$ chrome-use upload @e1 file.pdf # upload a file
$ chrome-use download @e2 ./file.pdf # download from a link or control
$ chrome-use download-url https://example.com/file.pdf ./file.pdf
$ chrome-use downloads --limit 10 --json # machine-readable Chrome downloads

fill reads the resulting control or rich-editor model value back and compares it exactly before reporting success. If Monaco hides its model API, one trusted editor paste is verified through the editor's copy handler and the browser clipboard is restored afterward. An unverifiable paste or mismatched readback is an error, not a silent success. The error quotes both values (e.g. read back "" after writing "狛江市"); when every non-ASCII character vanished while ASCII survived it says the page filtered non-Latin input (a Latin-only / masked field), so re-typing will not help. type reads the field back too: if it does not contain the typed text, a ⚠ warning is printed (exit 0, JSON gains readBack).

press probes, for keys whose only effect depends on page JavaScript (Arrow/Home/End/PageUp/PageDown on a text field, Escape, Enter on a bare input outside a form), whether any keydown/keyup/keypress listener exists from the focused element up to window. With none found it still exits 0 but prints a ⚠ warning that the page cannot react to the key and suggests clicking the option instead (JSON gains keyListeners). Chords, Tab, Backspace and printable keys are not probed.

⚠️ Click "succeeds but nothing happens"
Autocomplete / menu <li> items often close when the input loses focus. If click reports success but the page doesn't react, retry that click with AGENT_BROWSER_CLICK_MODE=dom — a plain <li> has no focusable target, so the input keeps focus and the option still gets selected. Note that a DOM-dispatched click (the relay's default for left clicks) now moves focus like a real click: the clicked element, its nearest focusable ancestor, or a label's control receives focus unless the handler already moved it, so click <input> then press Meta+a lands on that input rather than the previously focused field.

Reading information

Read text, HTML, attributes, values, bounding boxes, and computed styles from elements or the page.

get
$ chrome-use get text @e1        # element text
$ chrome-use get html @e1        # innerHTML
$ chrome-use get value @e1       # input value
$ chrome-use get attr @e1 href   # attribute
$ chrome-use get title           # page title
$ chrome-use get url             # current URL
$ chrome-use get cdp-url         # CDP WebSocket URL
$ chrome-use get count ".item"   # number of matching elements
$ chrome-use get box @e1         # bounding box
$ chrome-use get styles @e1      # computed styles (font, color, background, etc.)

Check state

is
$ chrome-use is visible @e1      # is it visible
$ chrome-use is enabled @e1      # is it enabled
$ chrome-use is checked @e1      # is it checked

Screenshots & PDF

screenshot / pdf
$ chrome-use screenshot          # save to a temp directory
$ chrome-use screenshot path.png # save to a specific path
$ chrome-use screenshot --full   # full-page screenshot
$ chrome-use pdf output.pdf      # save as PDF

Headless Chromium hides native scrollbars in screenshots for consistent image output. Pass --hide-scrollbars false at launch to keep the native scrollbars.

Recording

record
$ chrome-use record start ./demo.webm    # start recording
$ chrome-use click @e1                   # perform actions
$ chrome-use record stop                 # stop and save
$ chrome-use record restart ./take2.webm # stop the current one + start a new recording

Waiting

Wait for an element, text, URL, network idle, or any JS condition before asserting state.

wait
$ chrome-use wait @e1                     # wait for an element
$ chrome-use wait 2000                    # wait a number of milliseconds
$ chrome-use wait --text "Success"        # wait for text (or -t)
$ chrome-use wait --url "**/dashboard"    # wait for a URL pattern (or -u)
$ chrome-use wait --load networkidle       # wait for network idle (or -l)
$ chrome-use wait --fn "window.ready"     # wait for a JS condition (or -f)

Mouse control

mouse
$ chrome-use mouse move 100 200      # move the mouse
$ chrome-use mouse down left         # press a button
$ chrome-use mouse up left           # release a button
$ chrome-use mouse wheel 100         # wheel

Semantic locators

An alternative to refs: locate by role, text, label, placeholder, alt, title, testid, or position, and chain the action to perform directly after it. Or pass a natural-language description to return ranked candidates without acting.

find
$ chrome-use find role button click --name "Submit"
$ chrome-use find "edit web service settings button"  # candidates only
$ chrome-use find text "Sign In" click
$ chrome-use find text "Sign In" click --exact      # exact match only
$ chrome-use find label "Email" fill "user@test.com"
$ chrome-use find placeholder "Search" type "query"
$ chrome-use find alt "Logo" click
$ chrome-use find title "Close" click
$ chrome-use find testid "submit-btn" click
$ chrome-use find first ".item" click
$ chrome-use find last ".item" click
$ chrome-use find nth 2 "a" hover

Browser settings

set
$ chrome-use set viewport 1920 1080          # viewport size
$ chrome-use set viewport 1920 1080 2        # 2x retina (CSS size unchanged, higher-res screenshots)
$ chrome-use set device "iPhone 14"          # emulate a device
$ chrome-use set geo 37.7749 -122.4194       # geolocation (alias: geolocation)
$ chrome-use set offline on                  # toggle offline mode
$ chrome-use set headers '{"X-Key":"v"}'     # extra HTTP headers
$ chrome-use set credentials user pass       # HTTP basic auth (alias: auth)
$ chrome-use set media dark                  # emulate color scheme
$ chrome-use set media light reduced-motion  # light + reduced motion

Cookies & storage

cookies / storage
$ chrome-use cookies                     # get all cookies
$ chrome-use cookies set name value      # set a cookie
$ chrome-use cookies clear               # clear cookies
$ chrome-use storage local               # all of localStorage
$ chrome-use storage local key           # a specific key
$ chrome-use storage local set k v       # set a value
$ chrome-use storage local clear         # clear everything

Import cookies from cURL

Auto-detects the format: a JSON array of {name, value}, a DevTools → Network → Copy as cURL dump, or a bare Cookie header. Cookie values are never echoed back on error.

cookies set --curl
$ chrome-use cookies set --curl <file>                       # auto-detect JSON / cURL / Cookie header
$ chrome-use cookies set --curl <file> --domain example.com  # scope to a domain

Network interception

Intercept, block, mock responses, rewrite requests, or edit real responses. For in-depth usage, see the network section in the Core Loop.

network
$ chrome-use network route <url>              # intercept requests
$ chrome-use network route <url> --abort      # block requests
# mock a response (fulfill)
$ chrome-use network route <url> --body '{}' --status 200 --header K=V --content-type application/json
# rewrite a request (continue)
$ chrome-use network route <url> --method POST --set-body '{}' --set-header K=V --rewrite-url <u>
# edit a real response
$ chrome-use network route <url> --edit-status 503 --edit-header K=V --replace 'from=>to'
$ chrome-use network unroute [url]            # remove a route
$ chrome-use network requests                 # view tracked requests
$ chrome-use network requests --filter api    # filter requests

Intercept by resource type

network route --resource-type
# block scripts only (SSR-lock mode)
$ chrome-use network route '*' --abort --resource-type script
# replace images and fonts with empty responses
$ chrome-use network route '*' --resource-type image,font --body ''

Tabs & windows

Tab ids are stable strings like t1, t2 and are not reused within a session. Positional integers are not accepted — tab 2 errors; use t2. You can also give a tab a readable label (docs, app), interchangeable with the id.

tab / window
$ chrome-use tab                              # list tabs (with tabId and label)
$ chrome-use tab new [url]                    # new tab
$ chrome-use tab new --label docs [url]       # new tab with a readable label
$ chrome-use tab duplicate [ref]              # native Duplicate tab; current by default
$ chrome-use tab duplicate docs --label copy # duplicate by ref and label the copy
$ chrome-use tab t2                           # switch by id
$ chrome-use tab select t2                    # explicit switch syntax
$ chrome-use tab adopt "example.com/stuck" # adopt without navigating
$ chrome-use tab inspect t2                   # browser state without page JavaScript
$ chrome-use tab docs                         # switch by label
$ chrome-use tab close                        # close the current tab
$ chrome-use tab close t2                     # close by id
$ chrome-use tab close docs                   # close by label
$ chrome-use window new                       # new window

Native duplication requires real Chrome connected through the chrome-use extension. It restores the previously visible foreground tab, while the duplicate becomes chrome-use's internal active tab. There is no same-URL fallback for launched Chrome, raw CDP, Lightpanda, or cloud providers. Chrome decides whether the background duplicate starts loading.

tab select <ref> is equivalent to tab <ref>. tab adopt <URL substring|targetId> attaches an existing tab in the current session without reloading it. On external or extension-connected Chrome, tab list marks tabs as created, adopted, or foreign. Only created/adopted tabs can be selected, and only tabs created by the current session can be closed; adopted tabs remain user-owned. Created ownership survives daemon restarts for the same named session and connected browser endpoint, so interrupted cleanup can resume safely. tab inspect <ref> reads Chrome's browser-level tab metadata, so it can still return URL, load status, discard/freeze state, and debugger attachment when page JavaScript blocks the renderer main thread. eval still cannot complete until that thread responds. On the extension relay, tab inspect requires ab-connect 0.5.16 or newer. A failed tab select liveness probe does not by itself prove that the renderer is stuck. If the warning reports a live extension older than the bundled version, update or reload it at chrome://extensions, then retry.

ℹ️ refs belong to the tab active at snapshot time
The daemon maintains a single active tab, and @eN belongs to the tab that was active when the snapshot ran. To operate on another tab, switch to it first, then snapshot. Labels are never auto-generated, aren't rewritten after navigation, and are unique within a session.

Frames (iframe)

iframes are detected automatically during a snapshot, and their contents are inlined beneath the iframe element (one level of nesting). refs inside an iframe can be operated on directly; you can also switch frame context for a scoped snapshot.

frame
$ chrome-use frames              # [0] top … [1] accessory_layer …
$ chrome-use frame 1             # switch by the index frames prints (0 = top document)
$ chrome-use frame "#iframe"     # switch to an iframe by CSS selector
$ chrome-use frame @e3           # switch to an iframe by element ref
$ chrome-use frame main          # return to the main frame

A cross-origin overlay is a separate frame — a bank/branch picker, a payment field. snapshot -i on the page shows nothing of what is inside it, and focus / press land on the iframe element itself. The path is framesframe <index>snapshot -i / click / fill inside it; eval --frame <f> is the one-off form.

frame accepts three kinds of input: an element ref (frame @e3), a CSS selector (frame "#payment-iframe"), and a frame name / URL (matched against the browser's frame tree).

Dialogs

By default alert and beforeunload are accepted automatically so the agent doesn't block; confirm and prompt still need explicit handling. A click that opens either one returns a pending-dialog result immediately, so the same session can run the commands below. Use --no-auto-dialog to turn that behavior off.

dialog
$ chrome-use dialog accept [text]  # accept the dialog
$ chrome-use dialog dismiss        # dismiss the dialog
$ chrome-use dialog status         # check whether a dialog is open

Running JavaScript

eval runs in the page's MAIN world, so state persists and handlers fire. When your code contains nested quotes or special characters, -b / --stdin is more reliable — shell escaping is easy to get wrong.

eval
$ chrome-use eval "document.title"          # simple expressions only
$ chrome-use eval -b "<base64>"             # arbitrary JS (base64-encoded)
$ chrome-use eval --stdin                   # read the script from stdin

# multi-line scripts via stdin + heredoc:
$ cat <<'EOF' | chrome-use eval --stdin
const links = document.querySelectorAll('a');
Array.from(links).map(a => a.href);
EOF

Debug forms / hidden state with eval

form debugging
# dump every field's name → value, including hidden inputs and unchecked radios
$ chrome-use eval "JSON.stringify([...document.forms[0].elements].map(e=>({name:e.name,type:e.type,value:e.value,checked:e.checked})).filter(e=>e.name))"
# why won't it submit? ask the browser's own validity API
$ chrome-use eval "[...document.forms[0].elements].filter(e=>!e.validity?.valid).map(e=>e.name+': '+e.validationMessage)"

Single-pass scripting (batch / script)

Multi-step flows don't need one round-trip per command. batch runs a fixed sequence in one round-trip; script adds values between steps, loops, conditions, and asserts. See Single-pass Scripting.

script
# JSON op-list: value bus {{name.path}} + waitUntil/forEach/assert/return, --dry-run to validate
$ chrome-use script prog.json
$ chrome-use script - --dry-run < prog.json

# JS form: a synchronous JS program driven by cu.* helpers (ego's code-base idiom)
$ chrome-use script --timeout 120000 <<'JS'
  cu.open('https://news.ycombinator.com');
  const rows = cu.eval("[...document.querySelectorAll('.athing')].length");
  return { count: rows };
JS

Options: --timeout <ms>, --dry-run (validate the JSON program only), --yes (auto-confirm inside the script), --arg k=v (seed a variable). Exit codes: 0 ok, 1 runtime failure or failed assert, 2 invalid program.

State management

state
$ chrome-use state save auth.json    # save cookies, storage, and auth state
$ chrome-use state load auth.json    # restore saved state

Init scripts

init scripts
$ chrome-use open --init-script <path>       # register before the first navigation (repeatable)
$ chrome-use addinitscript <js>            # register at runtime (returns an identifier)
$ chrome-use removeinitscript <id>         # remove a registered init script

React / Web Vitals

The react ... commands require launching with --enable react-devtools; vitals and pushstate are framework-agnostic.

react / vitals
$ chrome-use open --enable react-devtools <url>    # launch with the React hook
$ chrome-use react tree                            # full component tree
$ chrome-use react inspect <fiberId>               # props / hooks / state / source
$ chrome-use react renders start                   # start recording re-renders
$ chrome-use react renders stop [--json]           # stop and print the render analysis
$ chrome-use react suspense [--only-dynamic] [--json]  # Suspense boundaries + classifier
$ chrome-use vitals [url] [--json]                 # LCP/CLS/TTFB/FCP/INP + hydration
$ chrome-use pushstate <url>                       # SPA client-side navigation (auto-detects Next router)

Accessibility audits

a11y runs the axe-core engine embedded in the chrome-use binary. It does not fetch a CDN script, works under strict page CSP, and preserves any page-owned window.axe value. The report includes same-origin and cross-origin iframe findings with their frame selector paths. Safari and iOS WebDriver sessions are not supported because the audit requires CDP.

a11y
$ chrome-use a11y                                  # audit the current page
$ chrome-use a11y https://example.com              # navigate, then audit
$ chrome-use a11y --tags wcag2a,wcag2aa            # filter by axe rule tags
$ chrome-use a11y --selector "#main"               # scope to one subtree
$ chrome-use a11y https://example.com --json        # structured output

Text output lists impact, rule id, fix guidance, and failing selectors. JSON output contains counts plus trimmed violations and incomplete arrays. MCP clients can call chrome_use_a11y from the all tool profile.

Debugging

console / errors capture is off by default — an active CDP Runtime domain is a detectable bot signal. Start the session with AGENT_BROWSER_CAPTURE_CONSOLE=1 when you need it.

debugging
$ chrome-use --headed open example.com   # show the browser window
$ chrome-use --cdp 9222 snapshot         # connect over a CDP port
$ chrome-use connect 9222                # alternative: the connect command
$ chrome-use console                     # view console messages (needs AGENT_BROWSER_CAPTURE_CONSOLE=1)
$ chrome-use console --limit 20          # only the last 20 console messages
$ chrome-use console --level error,warn  # errors and warnings only
$ chrome-use console --filter cart --limit 5  # last 5 lines mentioning cart (filter first, then tail)
$ chrome-use console --clear             # clear the console
$ chrome-use errors                      # view page errors (needs AGENT_BROWSER_CAPTURE_CONSOLE=1)
$ chrome-use errors --clear              # clear errors
$ chrome-use diagnose                    # why is the page blank: checks asset 404/MIME + mount state
$ chrome-use highlight @e1               # highlight an element
$ chrome-use inspect                     # open DevTools for this session
$ chrome-use trace start                 # start recording a trace
$ chrome-use trace stop trace.zip        # stop and save
$ chrome-use profiler start              # start profiling
$ chrome-use profiler stop trace.json    # stop and save the profile

Find pages the user saved (find-url)

Search local Chrome/Edge bookmarks by keyword — for internal systems or previously saved pages that public search can't reach. Reads locally; no browser / daemon required. Results are sorted by most recently added, and javascript: / data: bookmarks are skipped.

find-url
$ chrome-use find-url jira board          # all keywords must match (name or url)
$ chrome-use find-url --limit 10 invoices
$ chrome-use find-url --browser edge --profile "Profile 1" wiki
$ chrome-use find-url grafana --json      # {results:[{name,url,folder}], count}

Drive your real logged-in Chrome (extension)

Chrome 136 locked down --remote-debugging-port on the default profile, so to drive the user's existing logged-in window, chrome-use goes through a Chrome extension + native messaging — no port, no token, no per-use confirmation. A one-time install writes the native messaging host manifest:

extension
$ chrome-use extension install        # write the native messaging host manifest (one-time)
$ chrome-use status                   # CLI, extension, relay, profile, and session health
$ chrome-use extension connect        # auto-attach to the real logged-in tabs
$ chrome-use tab                      # list the real tabs it now controls
$ chrome-use tab t3                   # switch the session to one of them
$ chrome-use snapshot -i              # drive it like any normal session
$ chrome-use extension status         # is the host installed?
$ chrome-use extension uninstall      # remove the host manifest

# macOS: skip the policy profile that puts Chrome in managed mode
$ chrome-use extension install --no-profile
$ chrome-use extension install --all-profiles   # open the Store page in each missing profile
⚠ The macOS policy profile means a managed Chrome
The setup wizard's "silent, every profile at once" route makes Chrome "managed by your organization": the "Use secure DNS" (DoH) setting is disabled and locked (#187), and the extension becomes "installed by your administrator" with no manual update/remove button (#186). Skip it with --no-profile, or undo it with profiles remove -identifier com.leeguoo.chrome-use.connect (Chrome then uninstalls the policy-installed extension — re-add it from the Store). chrome-use extension status always reports where you stand.

chrome-use status distinguishes an installed manifest from a runnable native-host launcher. JSON output exposes the launcher result as extension.hostHealthy.

✅ Install from the Chrome Web Store (recommended)
The Store build is stable across restarts and auto-updates (store id knfcmbamhjmaonkfnjhldjedeobeafmk). A loaded unpacked dev build can be disabled / dropped when Chrome restarts, silently breaking the relay — use the Store build for unattended scenarios.
ℹ️ Security
The extension↔host link is authenticated by Chrome (the extension id); the host↔chrome-use CDP link uses an unguessable URL in a 0600 file. --extension <path> is unrelated — that loads an extension into a freshly launched browser.

Global options

These flags go before the command and apply to the whole session. Note: headless mode is forbidden (a bot signal) — it's headed by default and always (stealth); on a display-less server, use AGENT_BROWSER_ALLOW_HEADLESS=1.

global options
$ chrome-use --session <name> ...    # isolated browser session
$ chrome-use --json ...              # JSON output, easy to parse
$ chrome-use --headed ...            # default and always on (stealth)
$ chrome-use --full ...              # full-page screenshot (-f)
$ chrome-use --cdp <port> ...        # connect over CDP
$ chrome-use -p <provider> ...        # cloud browser provider (--provider)
$ chrome-use --proxy <url> ...       # use a proxy server
$ chrome-use --proxy-bypass <hosts>   # hosts that bypass the proxy
$ chrome-use --headers <json> ...    # HTTP headers scoped to the URL origin
$ chrome-use --executable-path <p>   # custom browser executable
$ chrome-use --extension <path> ...  # load an extension (repeatable)
$ chrome-use --ignore-https-errors   # ignore SSL certificate errors
$ chrome-use --hide-scrollbars false # keep native scrollbars in headless Chromium screenshots
$ chrome-use --help                  # help (-h)
$ chrome-use --version               # version (-V)
$ chrome-use <command> --help       # detailed help for a command

Environment variables

environment
AGENT_BROWSER_SESSION="mysession"            # explicit session name
AGENT_BROWSER_SESSION_ID="agent-id"           # stable runner id for auto-isolation
CODEX_THREAD_ID="thread-id"                   # recognized automatically for Codex tasks
AGENT_BROWSER_EXECUTABLE_PATH="/path/chrome" # custom browser path
AGENT_BROWSER_EXTENSIONS="/ext1,/ext2"       # comma-separated extension paths
AGENT_BROWSER_INIT_SCRIPTS="/a.js,/b.js"     # comma-separated init script paths
AGENT_BROWSER_ENABLE="react-devtools"        # comma-separated built-in init features
AGENT_BROWSER_HIDE_SCROLLBARS="false"        # keep native scrollbars
AGENT_BROWSER_PROVIDER="browserbase"         # cloud browser provider
AGENT_BROWSER_STREAM_PORT="9223"             # override the WebSocket stream port
AGENT_BROWSER_HOME="/path/to/chrome-use"     # custom install location
AGENT_BROWSER_CLICK_MODE="dom"               # click strategy: ""(default) / "coord" / "dom"

Stealth / anti-detection knobs (fork)

stealth knobs
AGENT_BROWSER_CAPTURE_CONSOLE="1"     # enable console/errors capture (off by default; the Runtime domain is a bot signal)
AGENT_BROWSER_TIMEZONE="Asia/Tokyo"   # --launch only. native timezone override (IANA id or "auto")
AGENT_BROWSER_BLOCK_WEBRTC="1"        # --launch only. hide the local IP via WebRTC
AGENT_BROWSER_HIDE_CANVAS="1"         # --launch only. session-stable canvas/audio fingerprint noise
AGENT_BROWSER_ADAPTIVE_REF="0"        # disable adaptive @ref relocation (on by default)
⚠️ console / errors return empty by default
In this stealth fork, both return {"messages":[]} / {"errors":[]} plus a hint until you start the session with AGENT_BROWSER_CAPTURE_CONSOLE=1 — this keeps the CDP Runtime domain disabled on the common automation paths. When something doesn't work, cross-check Troubleshooting.