browser_navigate
Navigate a browser tab to a URL via CDP, bypassing address-bar clicks. Auto-guards tab readiness, then follow with wait_until for slow pages.
Instructions
Navigate a browser tab to a URL via CDP Page.navigate — more reliable than clicking the address bar. Pass tabId+port so the server auto-guards (verifies tab readyState) and returns post.perception.status. lensId is optional for advanced pinned-tab workflows. Caveats: Does not block until page load completes — the Page.navigate ack confirms only that the navigation request was accepted (frameStoppedLoading / loaderId observation is internal). Follow with wait_until({condition:'ready_state' or 'element_matches'}) or repeated browser_eval polling for slow pages. Typed errors: code:'NavigateFailed' (Page.navigate rejected — DNS failure, malformed URL, network unreachable; check URL + connectivity), code:'BrowserNotConnected' (CDP disconnect — re-attach via browser_open), code:'AutoGuardBlocked' when the auto-guard refuses (e.g. tab still loading) — the error message preserves the guard's 1-sentence recommended next step (most often wait_until({condition:'ready_state'}) then retry).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to navigate to | |
| port | No | Chrome/Edge CDP remote debugging port (default 9222; configurable via desktop-touch-config.json) | |
| tabId | No | Tab ID from browser_open. Omit to use the first page tab. | |
| lensId | No | Optional perception lens ID. Guards (target.identityStable) are evaluated before navigating, and a perception envelope is attached to post.perception on success. | |
| include | No | Optional response-shape opt-in. `['envelope']` returns the self-documenting envelope (`_version` / `data` / `as_of` / `confidence`). `['raw']` forces raw shape (overrides DESKTOP_TOUCH_ENVELOPE=1 server default). Default behaviour is raw shape (compat with existing clients). | |
| narrate | No | Narration level. "rich": include UIA diff in post.rich (appeared/disappeared/valueDeltas, and nameDeltas when an element's name changed, such as a calculator display) — usually removes the need for a verification screenshot. It is withheld, with post.rich.diffDegraded saying why, when the diff cannot be shown to describe the window that was acted on. On click_element and keyboard (and set_element_value where the server registers it), which resolve the target window before acting: another open window's title contains the text this call resolved to, whether you named the hwnd or the server did — "@active" and the dialog rescue both resolve one ("ambiguous_title"); or the target moved between the snapshot and the action ("target_changed"). On those and on mouse_click, retrying with a fixId also withholds it, because the stored fix names a window this cannot see ("fix_target_unknown") — browser tools keep their diff on a fixId retry, because theirs is a tab diff and does not depend on a window title. mouse_click and mouse_drag accept an hwnd and still take their snapshots by windowTitle, so nothing else is withheld for them: verify those with a screenshot. A window too large to read whole is withheld too ("tree_truncated"). The action itself is unaffected in every case; only the diff is. Default: "minimal". | minimal |
| waitForLoad | No | When true (default), wait for document.readyState === 'complete' before returning. Use waitForLoad:false for the legacy behavior (return immediately after Page.navigate). Accepts the strings "true"/"false". | |
| loadTimeoutMs | No | Max milliseconds to wait for page load when waitForLoad=true (default 15000). On timeout, returns ok:true with readyState set to current state and hints.warnings=['NavigateTimeout']. |