Page tools
Read and act on web pages, and prepare and navigate browsers.
Read and act on web pages, and prepare and navigate browsers.
| Tool | Description | Platforms |
|---|---|---|
page | Legacy browser compatibility tool. | macOS, Linux, Windows |
get_browser_state | Read-only browser inspection. | macOS, Linux, Windows |
browser_prepare | Explicitly prepare an owned DevTools endpoint for a browser. | macOS, Linux, Windows |
browser_navigate | Navigate one tab of an exactly-bound browser target to a new URL (http/https/about only). | macOS, Linux, Windows |
Served by cua-driver mcp; see MCP tools for every tool.
page#Effect: mutating. Platforms: macOS, Linux, Windows.
Legacy browser compatibility tool. Prefer get_browser_state and the typed browser_* tools for exact targeting, endpoint ownership, and consent. Read-only get_text and query_dom remain available by default. Mutating actions require the daemon operator to set CUA_DRIVER_ENABLE_LEGACY_PAGE_MUTATIONS=1 before daemon startup (restart the daemon after changing it); this escape hatch does not provide the typed browser surface's exact binding or existing-profile grant guarantees. Supports Chrome, Brave, Edge, Safari (via AppleScript on macOS), Electron apps (via CDP), Chromium/Firefox on Windows (via UIA for read; CDP for execute_javascript when --remote-debugging-port is set), and WKWebView/Tauri/AT-SPI fallbacks.
Actions:
execute_javascript('el.click()') whenever you want visible cursor feedback.text at whatever currently holds DOM focus in one native operation (CDP Input.insertText); no synthesized key events, but more durable than a one-shot execute_javascript write since rich-text editors already have to treat it like an IME commit. Try this before type_keystrokes on a contenteditable that discarded an execute_javascript write. Click/focus the target field first.text via real per-character keystroke events into whatever currently holds DOM focus. Slower than insert_text but the most durable rung: use it when insert_text also gets discarded, or the editor's own keydown/keyup handlers need to see real keys. Click/focus the target field first.macOS parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
session | string | For multi-call work, prefer a short public session label and repeat it on every call that accepts it. Omit it to use the authenticated transport's implicit lifecycle session. |
Parameters on every platform
| Parameter | Type | Default | Description |
|---|---|---|---|
action | "execute_javascript" | "get_text" | "query_dom" | "click_element" | "insert_text" | "type_keystrokes" | "enable_javascript_apple_events" | required | Action to perform. |
attributes | string[] | Element attributes to include in query_dom results. | |
bundle_id | string | Bundle ID of the browser. Required for enable_javascript_apple_events (macOS only). | |
cdp_port | integer | Optional, for execute_javascript/insert_text/type_keystrokes: use this exact CDP port instead of auto-discovering one from pid. Needed when the port was opened via the browser's own remote-debugging toggle rather than a launch-time flag, since that path may not answer the auto-discovery probe. Range: 1 to 65535. | |
css_selector | string | CSS selector for query_dom (e.g. 'a', 'button', 'input', 'h1'-'h6', 'p', 'img', 'select', '*'). | |
javascript | string | JavaScript to execute. Required for execute_javascript. | |
pid | integer | Target process ID. | |
selector | string | CSS selector for click_element (e.g. 'button.submit', '#login a'). | |
target_url_contains | string | Optional, for execute_javascript/insert_text/type_keystrokes: require exactly one browser tab whose URL contains this substring. Use this on a multi-tab browser: there's no built-in link between window_id and which tab a CDP call reaches. | |
text | string | Text to insert or type. Required for insert_text and type_keystrokes. The target field must already have DOM focus (click/focus it first). | |
user_has_confirmed_enabling | boolean | Must be true to proceed with enable_javascript_apple_events. This will quit and relaunch the browser. | |
window_id | integer | Target window ID from list_windows. |
Example arguments
{"action":"execute_javascript"}get_browser_state#Read-only browser inspection. Mode 1 (bind): pass pid + window_id of a native browser window to classify it, correlate it to a CDP target (exact-or-refuse), and mint a session-scoped target id plus tab ids. Mode 2 (snapshot): pass target_id + tab_id. The dom_refs_v1 compatibility format returns composed DOM refs. semantic_v2 joins accessibility, DOM, layout, and viewport state; ranks visible content before retained/offscreen state; and returns a semantic outline, typed action refs, content refs, scoped reads, and opaque continuation. Never performs setup: a missing endpoint is a structured browser_requires_setup refusal pointing at browser_prepare.
Effect: read-only, idempotent. Platforms: macOS, Linux, Windows.
| Parameter | Type | Default | Description |
|---|---|---|---|
continuation | string | Opaque continuation minted by an earlier semantic_v2 response. | |
include_screenshot | boolean | false | Capture the exact tab viewport as PNG through CDP without selecting the tab or foregrounding its native window. The request refuses if capture cannot be completed. |
pid | integer | Native browser process id (bind mode). | |
query | string | Read-only semantic match over role, accessible name, and visible text. | |
scope_ref | string | Current semantic/content ref whose subtree should be observed. | |
session | string | For multi-call work, prefer a short public session label and repeat it on every call that accepts it. Omit it to use the authenticated transport's implicit lifecycle session. Browser targets, tabs, and refs belong to the resolved lifecycle session. | |
snapshot_format | "dom_refs_v1" | "semantic_v2" | Versioned snapshot contract. dom_refs_v1 remains the compatibility default. | |
tab_id | string | Opaque tab id from get_browser_state (session-scoped). | |
target_id | string | Opaque browser target id minted by get_browser_state (session-scoped; never a CDP id). | |
window_id | integer | Native window id owned by pid (bind mode). |
browser_prepare#Explicitly prepare an owned DevTools endpoint for a browser. pid is required for an existing process or existing-profile attachment, and optional only for allow_launch=true with an isolated profile. Existing endpoints are detected without side effects. Acting setup for an isolated profile follows the runtime permission mode and optional capability manifest. It requires allow_launch=true, launches a separate browser, and never copies, modifies, or terminates the requested user profile. Without pid, only a platform-attested system Chrome/Edge installation (or a root-owned package payload on Linux) is eligible; redirects and user-controlled locations fail closed. Existing-profile attachment is explicit and follows the runtime's immutable permission mode: standard requires an explicit --grant existing-profile launch grant or an embedding authorization host, bounded requires a launch-approved exact resource manifest, and unrestricted requires explicit trusted startup risk acceptance. Ordinary MCP transport approval never proves profile authorization. On proven platforms, an authorized request also permits one bounded exact-window setup: open the recognized browser product's fixed remote-debugging page, toggle its uniquely matched per-instance checkbox, prove the PID-owned loopback endpoint, and close the temporary tab. Every visible effect is reported; ambiguity is refused.
Effect: destructive. Platforms: macOS, Linux, Windows.
| Parameter | Type | Default | Description |
|---|---|---|---|
allow_launch | boolean | Allow a separate driver-owned isolated Chromium process to be launched (default false). | |
pid | integer | Browser process id to prepare. Required except for a driver-owned isolated_new/isolated_named launch with allow_launch=true. | |
profile | object | Driver-owned isolated Chromium profile to launch with allow_launch=true. mode=isolated_new creates a fresh throwaway profile; mode=isolated_named reuses the named driver-owned profile. Never an existing user profile. | |
profile.mode | "isolated_new" | "isolated_named" | ||
profile.name | string | Required only for isolated_named; 1-64 path-safe ASCII characters. | |
session | string | For multi-call work, prefer a short public session label and repeat it on every call that accepts it. Omit it to use the authenticated transport's implicit lifecycle session. Browser targets, tabs, and refs belong to the resolved lifecycle session. | |
strategy | object | Attach to an already-running browser instead of launching one. kind=existing_profile attaches to the user's running profile at pid/window_id and requires explicit profile authorization. | |
strategy.kind | "existing_profile" | ||
window_id | integer | Exact native window approval anchor; required for strategy.kind=existing_profile. |
browser_navigate#Navigate one tab of an exactly-bound browser target to a new URL (http/https/about only). Refused for heuristic bindings. Navigation invalidates all p<snapshot>:<index> refs for the tab.
Effect: mutating. Platforms: macOS, Linux, Windows.
| Parameter | Type | Default | Description |
|---|---|---|---|
session | string | For multi-call work, prefer a short public session label and repeat it on every call that accepts it. Omit it to use the authenticated transport's implicit lifecycle session. Browser targets, tabs, and refs belong to the resolved lifecycle session. | |
tab_id | string | required | Opaque tab id from get_browser_state (session-scoped). |
target_id | string | required | Opaque browser target id minted by get_browser_state (session-scoped; never a CDP id). |
url | string | required | Destination URL (http:, https:, or about:). |
Example arguments
{"target_id":"<target_id>","tab_id":"<tab_id>","url":"<url>"}