# MCP tool reference

The 43 tools BrowserHive registers, in registration order, generated from `TOOL_CONTRACTS` in `@browserhive/contracts/tools`. Names, parameters, defaults and result shapes are a frozen contract. Every page-targeting tool accepts an optional `tab_id` (defaults to the active tab). Errors are returned as `[CODE] message` text; see the [error reference](/docs/reference/errors/).

Defaults shown for `launch_session` `channel` and `headless` are the contract defaults; a server started with `--defaultChannel` / `--defaultHeadless` advertises its configured values in `tools/list`.

## Catalog

| # | Tool | Pack | Title | RO | Destructive | Idempotent | Open world |
|---|---|---|---|---|---|---|---|
| 1 | [`launch_session`](#launch_session) | Lifecycle | Launch session | no | no | no | yes |
| 2 | [`close_session`](#close_session) | Lifecycle | Close session | no | yes | yes | no |
| 3 | [`list_sessions`](#list_sessions) | Lifecycle | List sessions | yes | no | yes | no |
| 4 | [`server_status`](#server_status) | Introspection | Server status | yes | no | yes | no |
| 5 | [`session_info`](#session_info) | Introspection | Session info | yes | no | yes | no |
| 6 | [`navigate`](#navigate) | Navigation | Navigate | no | no | no | yes |
| 7 | [`go_back`](#go_back) | Navigation | Go back | no | no | no | yes |
| 8 | [`go_forward`](#go_forward) | Navigation | Go forward | no | no | no | yes |
| 9 | [`reload`](#reload) | Navigation | Reload | no | no | yes | yes |
| 10 | [`wait_for_url`](#wait_for_url) | Navigation | Wait for URL | yes | no | yes | no |
| 11 | [`new_tab`](#new_tab) | Tabs | New tab | no | no | no | yes |
| 12 | [`close_tab`](#close_tab) | Tabs | Close tab | no | yes | yes | no |
| 13 | [`switch_tab`](#switch_tab) | Tabs | Switch tab | no | no | yes | no |
| 14 | [`list_tabs`](#list_tabs) | Tabs | List tabs | yes | no | yes | no |
| 15 | [`click`](#click) | Interaction | Click | no | no | no | yes |
| 16 | [`type_text`](#type_text) | Interaction | Type text | no | no | no | yes |
| 17 | [`fill`](#fill) | Interaction | Fill | no | no | yes | yes |
| 18 | [`press_key`](#press_key) | Interaction | Press key | no | no | no | yes |
| 19 | [`hover`](#hover) | Interaction | Hover | no | no | yes | yes |
| 20 | [`select_option`](#select_option) | Interaction | Select option | no | no | yes | yes |
| 21 | [`scroll`](#scroll) | Interaction | Scroll | no | no | no | yes |
| 22 | [`drag_and_drop`](#drag_and_drop) | Interaction | Drag and drop | no | no | no | yes |
| 23 | [`screenshot`](#screenshot) | Inspection | Screenshot | yes | no | yes | no |
| 24 | [`snapshot`](#snapshot) | Inspection | Snapshot | yes | no | yes | no |
| 25 | [`get_content`](#get_content) | Inspection | Get content | yes | no | yes | no |
| 26 | [`evaluate`](#evaluate) | Inspection | Evaluate | no | no | no | yes |
| 27 | [`wait_for_selector`](#wait_for_selector) | Waits | Wait for selector | yes | no | yes | no |
| 28 | [`wait_for_load_state`](#wait_for_load_state) | Waits | Wait for load state | yes | no | yes | no |
| 29 | [`accept_next_dialog`](#accept_next_dialog) | Dialogs | Accept next dialog | no | no | yes | no |
| 30 | [`dismiss_next_dialog`](#dismiss_next_dialog) | Dialogs | Dismiss next dialog | no | no | yes | no |
| 31 | [`get_cookies`](#get_cookies) | Cookies and state | Get cookies | yes | no | yes | no |
| 32 | [`set_cookies`](#set_cookies) | Cookies and state | Set cookies | no | no | yes | no |
| 33 | [`set_viewport`](#set_viewport) | Cookies and state | Set viewport | no | no | yes | no |
| 34 | [`set_extra_http_headers`](#set_extra_http_headers) | Cookies and state | Set extra HTTP headers | no | no | yes | no |
| 35 | [`upload_file`](#upload_file) | Files | Upload file | no | no | yes | no |
| 36 | [`download_file`](#download_file) | Files | Download file | no | no | no | yes |
| 37 | [`save_storage_state`](#save_storage_state) | Auth states | Save storage state | no | no | yes | no |
| 38 | [`save_full_profile`](#save_full_profile) | Auth states | Save full profile | no | no | yes | no |
| 39 | [`list_saved_auths`](#list_saved_auths) | Auth states | List saved auths | yes | no | yes | no |
| 40 | [`request_attention`](#request_attention) | Attention (HTTP transport only) | Request attention | no | no | no | no |
| 41 | [`get_attention_result`](#get_attention_result) | Attention (HTTP transport only) | Get attention result | yes | no | yes | no |
| 42 | [`vault_list_available`](#vault_list_available) | Vault | Vault: list available | yes | no | yes | no |
| 43 | [`vault_fill`](#vault_fill) | Vault | Vault: fill | no | no | no | yes |

## Lifecycle

<a id="launch_session"></a>
### `launch_session`

**Launch session** · capability `lifecycle` · since 0.1.0

> Launch a new isolated browser session. Each session owns its own Playwright driver, browser, context, and page so cookies and storage never leak between sessions. The resolved session_id is '<slug>-<nanoid8>' and is returned as the 'session_id' field.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `slug` | `string` | yes | — | pattern `^[a-z][a-z0-9-]{1,31}$` |
| `channel` | one of `chromium`, `chrome`, `edge` | no | `"chromium"` | — |
| `incognito` | `boolean` | no | `false` | — |
| `headless` | `boolean` | no | `true` | — |
| `persistence_mode` | one of `memory`, `persistent`, `storage-state` | no | — | — |
| `restore_profile` | `string` | no | — | — |
| `launch_options` | `object` | no | — | keys `args`, `executablePath`; additional keys allowed |
| `context_options` | `object` | no | — | additional keys allowed |
| `disable_evaluate` | `boolean` | no | `false` | — |
| `vault_enabled` | `boolean` | no | `true` | — |
| `stealth` | `boolean` | no | — | — |
| `fingerprint` | `boolean` | no | — | — |
| `humanize` | `boolean` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `slug` | `string` | yes |
| `channel` | one of `chromium`, `chrome`, `edge` | yes |
| `incognito` | `boolean` | yes |
| `headless` | `boolean` | yes |
| `persistence_mode` | one of `memory`, `persistent`, `storage-state` | yes |
| `current_url` | `string` or `null` | yes |
| `created_at` | `number` | yes |
| `owner` | `string` | yes |
| `lease_expires_at` | `number` | yes |
| `lease_paused_at` | `number` or `null` | yes |
| `disable_evaluate` | `boolean` | yes |
| `vault_enabled` | `boolean` | yes |
| `stealth` | `boolean` | yes |
| `fingerprint` | `boolean` | yes |
| `humanize` | `boolean` | yes |
| `identity` | `object` or `null` | yes |
| `proxy_label` | `string` or `null` | yes |

Errors: [`INVALID_SLUG`](/docs/reference/errors/#INVALID_SLUG), [`UNKNOWN_CHANNEL`](/docs/reference/errors/#UNKNOWN_CHANNEL), [`SESSION_LIMIT_REACHED`](/docs/reference/errors/#SESSION_LIMIT_REACHED), [`SESSION_ALREADY_EXISTS`](/docs/reference/errors/#SESSION_ALREADY_EXISTS), [`UNSAFE_LAUNCH_ARG`](/docs/reference/errors/#UNSAFE_LAUNCH_ARG), [`INVALID_PERSISTENCE_CONFIG`](/docs/reference/errors/#INVALID_PERSISTENCE_CONFIG), [`AUTH_STATE_NOT_FOUND`](/docs/reference/errors/#AUTH_STATE_NOT_FOUND), [`BROWSER_NOT_INSTALLED`](/docs/reference/errors/#BROWSER_NOT_INSTALLED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="close_session"></a>
### `close_session`

**Close session** · capability `lifecycle` · since 0.1.0

> Close an existing browser session and release all its resources.

Annotations: readOnly no · destructive yes · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `closed` | `boolean` | yes |

Errors: none documented. Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="list_sessions"></a>
### `list_sessions`

**List sessions** · capability `lifecycle` · since 0.1.0

> Return metadata for every live session.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters: none.

Result: a JSON array; each item has:

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `slug` | `string` | yes |
| `channel` | one of `chromium`, `chrome`, `edge` | yes |
| `incognito` | `boolean` | yes |
| `headless` | `boolean` | yes |
| `persistence_mode` | one of `memory`, `persistent`, `storage-state` | yes |
| `current_url` | `string` or `null` | yes |
| `created_at` | `number` | yes |
| `owner` | `string` | yes |
| `lease_expires_at` | `number` | yes |
| `lease_paused_at` | `number` or `null` | yes |
| `disable_evaluate` | `boolean` | yes |
| `vault_enabled` | `boolean` | yes |
| `stealth` | `boolean` | yes |
| `fingerprint` | `boolean` | yes |
| `humanize` | `boolean` | yes |
| `identity` | `object` or `null` | yes |
| `proxy_label` | `string` or `null` | yes |

Errors: none documented. Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Introspection

<a id="server_status"></a>
### `server_status`

**Server status** · capability `read` · since 0.1.0

> Report server-wide status: uptime, version, transport, live/allowed session counts, vault state, and the global default persistence mode.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters: none.

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `uptime_ms` | `number` | yes |
| `version` | `string` | yes |
| `transport` | one of `stdio`, `http` | yes |
| `sessions` | `object` | yes |
| `vault` | `object` | yes |
| `persistence_mode` | one of `memory`, `persistent`, `storage-state` | yes |

Errors: none documented. Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="session_info"></a>
### `session_info`

**Session info** · capability `read` · since 0.1.0

> Report a single session's configuration and live state: channel, headless/incognito, persistence mode, per-session evaluate/vault flags, open tab (page) count, current URL, created_at, last_tool_at, and navigation count.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `config` | `object` | yes |
| `page_count` | `number` | yes |
| `current_url` | `string` or `null` | yes |
| `created_at` | `number` | yes |
| `last_tool_at` | `number` | yes |
| `lease_expires_at` | `number` | yes |
| `navigation_count` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Navigation

<a id="navigate"></a>
### `navigate`

**Navigate** · capability `navigate` · since 0.1.0

> Navigate a tab to a URL (defaults to the active tab). The operator may maintain a URL blocklist; a blocked target fails with URL_BLOCKED and must not be retried.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `url` | `string` | yes | — | — |
| `wait_until` | one of `load`, `domcontentloaded`, `networkidle`, `commit` | no | `"load"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |
| `status` | `number` or `null` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`URL_BLOCKED`](/docs/reference/errors/#URL_BLOCKED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`NAVIGATION_TIMEOUT`](/docs/reference/errors/#NAVIGATION_TIMEOUT), [`NAVIGATION_FAILED`](/docs/reference/errors/#NAVIGATION_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="go_back"></a>
### `go_back`

**Go back** · capability `navigate` · since 0.1.0

> Navigate back in a tab's history (defaults to the active tab).

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `wait_until` | one of `load`, `domcontentloaded`, `networkidle`, `commit` | no | `"load"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`NAVIGATION_TIMEOUT`](/docs/reference/errors/#NAVIGATION_TIMEOUT), [`NAVIGATION_FAILED`](/docs/reference/errors/#NAVIGATION_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="go_forward"></a>
### `go_forward`

**Go forward** · capability `navigate` · since 0.1.0

> Navigate forward in a tab's history (defaults to the active tab).

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `wait_until` | one of `load`, `domcontentloaded`, `networkidle`, `commit` | no | `"load"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`NAVIGATION_TIMEOUT`](/docs/reference/errors/#NAVIGATION_TIMEOUT), [`NAVIGATION_FAILED`](/docs/reference/errors/#NAVIGATION_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="reload"></a>
### `reload`

**Reload** · capability `navigate` · since 0.1.0

> Reload the current page in a tab (defaults to the active tab).

Annotations: readOnly no · destructive no · idempotent yes · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `wait_until` | one of `load`, `domcontentloaded`, `networkidle`, `commit` | no | `"load"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`NAVIGATION_TIMEOUT`](/docs/reference/errors/#NAVIGATION_TIMEOUT), [`NAVIGATION_FAILED`](/docs/reference/errors/#NAVIGATION_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="wait_for_url"></a>
### `wait_for_url`

**Wait for URL** · capability `read` · since 0.1.0

> Wait until a tab's URL matches. `url` may be a string (exact/glob) or a { pattern, flags? } object compiled to a regular expression.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `url` | `string` or `object` | yes | — | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`WAIT_TIMEOUT`](/docs/reference/errors/#WAIT_TIMEOUT). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Tabs

<a id="new_tab"></a>
### `new_tab`

**New tab** · capability `navigate` · since 0.1.0

> Open a new tab in the session and make it active. Optionally navigate it to a URL. Returns the stable tab_id other tools accept via their optional tab_id argument.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `url` | `string` | no | — | — |
| `wait_until` | one of `load`, `domcontentloaded`, `networkidle`, `commit` | no | `"load"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `tab_id` | `string` | yes |
| `url` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`URL_BLOCKED`](/docs/reference/errors/#URL_BLOCKED), [`NAVIGATION_TIMEOUT`](/docs/reference/errors/#NAVIGATION_TIMEOUT), [`NAVIGATION_FAILED`](/docs/reference/errors/#NAVIGATION_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="close_tab"></a>
### `close_tab`

**Close tab** · capability `mutate` · since 0.1.0

> Close a tab by id. If it was the active tab, another open tab becomes active.

Annotations: readOnly no · destructive yes · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `tab_id` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `tab_id` | `string` | yes |
| `closed` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="switch_tab"></a>
### `switch_tab`

**Switch tab** · capability `mutate` · since 0.1.0

> Make the given tab the active tab for subsequent tab_id-less tool calls.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `tab_id` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `tab_id` | `string` | yes |
| `url` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="list_tabs"></a>
### `list_tabs`

**List tabs** · capability `read` · since 0.1.0

> List every open tab: its tab_id, current URL, title, and whether it is active.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |

Result: a JSON array; each item has:

| Field | Type | Always present |
|---|---|---|
| `tab_id` | `string` | yes |
| `url` | `string` | yes |
| `title` | `string` | yes |
| `active` | `boolean` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Interaction

<a id="click"></a>
### `click`

**Click** · capability `mutate` · since 0.1.0

> Click an element matching the selector.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `button` | one of `left`, `right`, `middle` | no | `"left"` | — |
| `click_count` | `integer` | no | `1` | ≥ 1; ≤ 3 |
| `modifiers` | array of one of `Alt`, `Control`, `ControlOrMeta`, `Meta`, `Shift` | no | — | — |
| `position` | `object` | no | — | keys `x`, `y` |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="type_text"></a>
### `type_text`

**Type text** · capability `mutate` · since 0.1.0

> Type text into the element one character at a time (simulates typing).

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `text` | `string` | yes | — | — |
| `delay` | `number` | no | `0` | ≥ 0 |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="fill"></a>
### `fill`

**Fill** · capability `mutate` · since 0.1.0

> Fill an input/textarea directly (fast, no per-character typing).

Annotations: readOnly no · destructive no · idempotent yes · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `value` | `string` | yes | — | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="press_key"></a>
### `press_key`

**Press key** · capability `mutate` · since 0.1.0

> Press a keyboard key. If a selector is given, focuses it first.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `key` | `string` | yes | — | min length 1 |
| `selector` | `string` | no | — | min length 1 |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `key` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="hover"></a>
### `hover`

**Hover** · capability `mutate` · since 0.1.0

> Hover the mouse over an element.

Annotations: readOnly no · destructive no · idempotent yes · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="select_option"></a>
### `select_option`

**Select option** · capability `mutate` · since 0.1.0

> Select one or more options in a <select> element by value.

Annotations: readOnly no · destructive no · idempotent yes · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `values` | `string[]` | yes | — | at least 1 item |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `selected` | `string[]` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="scroll"></a>
### `scroll`

**Scroll** · capability `mutate` · since 0.1.0

> Scroll a tab: mode="by" scrolls by (dx,dy); mode="to" scrolls to (x,y); mode="selector" brings an element into view. Returns the resulting scroll offset.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `mode` | one of `by`, `to`, `selector` | yes | — | — |
| `dx` | `number` | no | `0` | — |
| `dy` | `number` | no | `0` | — |
| `x` | `number` | no | — | — |
| `y` | `number` | no | — | — |
| `selector` | `string` | no | — | min length 1 |
| `behavior` | one of `auto`, `smooth` | no | `"auto"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `x` | `number` | yes |
| `y` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="drag_and_drop"></a>
### `drag_and_drop`

**Drag and drop** · capability `mutate` · since 0.1.0

> Drag the source element and drop it on the target element.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `source_selector` | `string` | yes | — | min length 1 |
| `target_selector` | `string` | yes | — | min length 1 |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`ELEMENT_NOT_ACTIONABLE`](/docs/reference/errors/#ELEMENT_NOT_ACTIONABLE). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Inspection

<a id="screenshot"></a>
### `screenshot`

**Screenshot** · capability `read` · since 0.1.0

> Take a PNG screenshot of a tab and return it as an MCP image content block so vision-capable models can see it. When save_path is set the PNG is also written to disk (sandboxed under <data-dir>) and a { saved_to } block is included.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `full_page` | `boolean` | no | `false` | — |
| `clip` | `object` | no | — | keys `x`, `y`, `width`, `height` |
| `omit_background` | `boolean` | no | `false` | — |
| `save_path` | `string` | no | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `saved_to` | `string` | no |
| `width` | `number` | yes |
| `height` | `number` | yes |
| `bytes` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`PATH_NOT_ALLOWED`](/docs/reference/errors/#PATH_NOT_ALLOWED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="snapshot"></a>
### `snapshot`

**Snapshot** · capability `read` · since 0.1.0

> Return the tab's ARIA accessibility tree (YAML) — purpose-built for LLM consumption.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |
| `tree` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="get_content"></a>
### `get_content`

**Get content** · capability `read` · since 0.1.0

> Return the current HTML content of a tab.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `url` | `string` | yes |
| `html` | `string` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="evaluate"></a>
### `evaluate`

**Evaluate** · capability `mutate` · since 0.1.0

> Evaluate a JavaScript expression in the tab context and return the result. Function-shaped strings are auto-wrapped as IIFEs. A session launched with disable_evaluate: true rejects this call with EVALUATE_DISABLED.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `expression` | `string` | yes | — | min length 1 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `result` | `any` | yes |

Errors: [`EVALUATE_DISABLED`](/docs/reference/errors/#EVALUATE_DISABLED), [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`SCRIPT_ERROR`](/docs/reference/errors/#SCRIPT_ERROR). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Waits

<a id="wait_for_selector"></a>
### `wait_for_selector`

**Wait for selector** · capability `read` · since 0.1.0

> Wait for an element to reach the given state (attached/detached/visible/hidden).

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `state` | one of `attached`, `detached`, `visible`, `hidden` | no | `"visible"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `state` | one of `attached`, `detached`, `visible`, `hidden` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`WAIT_TIMEOUT`](/docs/reference/errors/#WAIT_TIMEOUT). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="wait_for_load_state"></a>
### `wait_for_load_state`

**Wait for load state** · capability `read` · since 0.1.0

> Wait for the page to reach a load state (load/domcontentloaded/networkidle).

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `state` | one of `load`, `domcontentloaded`, `networkidle` | no | `"load"` | — |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `state` | one of `load`, `domcontentloaded`, `networkidle` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`WAIT_TIMEOUT`](/docs/reference/errors/#WAIT_TIMEOUT). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Dialogs

<a id="accept_next_dialog"></a>
### `accept_next_dialog`

**Accept next dialog** · capability `mutate` · since 0.1.0

> Arm a one-shot handler that accepts the next JavaScript dialog (alert/confirm/prompt) on the tab. For a prompt, prompt_text is entered first. Auto-disarms after one dialog or 60s.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `prompt_text` | `string` | no | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `armed` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="dismiss_next_dialog"></a>
### `dismiss_next_dialog`

**Dismiss next dialog** · capability `mutate` · since 0.1.0

> Arm a one-shot handler that dismisses (cancels) the next JavaScript dialog on the tab. Auto-disarms after one dialog or 60s.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `armed` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Cookies and state

<a id="get_cookies"></a>
### `get_cookies`

**Get cookies** · capability `read` · since 0.1.0

> Return the session context's cookies, optionally filtered to those that would be sent to the given URLs.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `urls` | `string[]` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `cookies` | `object[]` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="set_cookies"></a>
### `set_cookies`

**Set cookies** · capability `mutate` · since 0.1.0

> Add cookies to the session context. Each cookie needs name+value and either a url or a domain+path (Playwright semantics).

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `cookies` | `object[]` | yes | — | at least 1 item; each item: keys `name`, `value`, additional keys allowed |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `added` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="set_viewport"></a>
### `set_viewport`

**Set viewport** · capability `mutate` · since 0.1.0

> Set a tab's viewport size in CSS pixels.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `width` | `integer` | yes | — | — |
| `height` | `integer` | yes | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `width` | `number` | yes |
| `height` | `number` | yes |
| `clamped` | `true` | no |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="set_extra_http_headers"></a>
### `set_extra_http_headers`

**Set extra HTTP headers** · capability `mutate` · since 0.1.0

> Set extra HTTP headers sent with every request from the session context (applies to all tabs). Replaces any previously-set extra headers. On a stealth session, headers owned by the presented identity (User-Agent, Accept-Language, Sec-CH-UA*) are refused and listed in the `rejected` field, since overriding them would desync the wire from what the page sees in JavaScript.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `headers` | `object` | yes | — | additional keys allowed |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `applied` | `number` | yes |
| `rejected` | `string[]` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Files

<a id="upload_file"></a>
### `upload_file`

**Upload file** · capability `mutate` · since 0.1.0

> Set the files on a file <input> matched by selector. Every path MUST resolve under the server's uploads sandbox (<data-dir>/uploads/); out-of-tree paths fail with PATH_NOT_ALLOWED.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `selector` | `string` | yes | — | min length 1 |
| `paths` | `string[]` | yes | — | at least 1 item; each item: min length 1 |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `selector` | `string` | yes |
| `ok` | `true` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`PATH_NOT_ALLOWED`](/docs/reference/errors/#PATH_NOT_ALLOWED), [`UPLOAD_FAILED`](/docs/reference/errors/#UPLOAD_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="download_file"></a>
### `download_file`

**Download file** · capability `mutate` · since 0.1.0

> Click a trigger element and capture the resulting download into the managed downloads dir (<data-dir>/sessions/<id>/downloads/). Returns the absolute saved path, the suggested filename, and the byte size.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `trigger_selector` | `string` | yes | — | min length 1 |
| `timeout` | `integer` | no | `30000` | ≥ 0 |
| `tab_id` | `string` | no | — | — |
| `save_as` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `session_id` | `string` | yes |
| `saved_to` | `string` | yes |
| `suggested_name` | `string` | yes |
| `size` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`TAB_NOT_FOUND`](/docs/reference/errors/#TAB_NOT_FOUND), [`DOWNLOAD_FAILED`](/docs/reference/errors/#DOWNLOAD_FAILED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Auth states

<a id="save_storage_state"></a>
### `save_storage_state`

**Save storage state** · capability `mutate` · since 0.1.0

> Save the session's cookies + localStorage as a light "storage-state" snapshot for later restore via launch_session({ context_options: { storageState: name } }) in a non-persistent mode. Valid in any persistence mode.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `name` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `name` | `string` | yes |
| `path` | `string` | yes |
| `size` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`PATH_NOT_ALLOWED`](/docs/reference/errors/#PATH_NOT_ALLOWED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="save_full_profile"></a>
### `save_full_profile`

**Save full profile** · capability `mutate` · since 0.1.0

> Save the session's full on-disk Chromium profile as a heavy "profile" snapshot (zipped user-data-dir) for later restore via launch_session({ persistence_mode: "persistent", restore_profile: name }). Only valid when the source session is in persistent mode.

Annotations: readOnly no · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `name` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `name` | `string` | yes |
| `path` | `string` | yes |
| `size` | `number` | yes |

Errors: [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED), [`INVALID_PERSISTENCE_CONFIG`](/docs/reference/errors/#INVALID_PERSISTENCE_CONFIG), [`PATH_NOT_ALLOWED`](/docs/reference/errors/#PATH_NOT_ALLOWED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="list_saved_auths"></a>
### `list_saved_auths`

**List saved auths** · capability `read` · since 0.1.0

> List every saved auth snapshot (storage-state and full-profile) with kind, size, and when it was saved, most recent first.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters: none.

Result: a JSON array; each item has:

| Field | Type | Always present |
|---|---|---|
| `name` | `string` | yes |
| `kind` | one of `storage`, `profile` | yes |
| `saved_at` | `number` | yes |
| `size` | `number` | yes |

Errors: none documented. Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Attention (HTTP transport only)

<a id="request_attention"></a>
### `request_attention`

**Request attention** · capability `attention` · since 0.1.0

> Flag a session for human attention and BLOCK until an operator resolves it in the admin dashboard, it times out, or it is cancelled. Both modes (takeover and notify) block until resolved — neither is fire-and-forget. Use when the agent is stuck on something only a human can do (CAPTCHA, interactive login, consent screen). Set max_wait_seconds to 0 to wait indefinitely (up to the server limit), which is best when a human may be away. Returns the operator decision { status, message?, resolved_by?, resolved_at, request_id }. http transport only.

Annotations: readOnly no · destructive no · idempotent no · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `reason` | `string` | yes | — | min length 1 |
| `mode` | one of `takeover`, `notify` | no | `"takeover"` | Both modes BLOCK until an operator resolves the request (neither is fire-and-forget). 'takeover' lets the operator drive the session live; 'notify' is view-only — the operator still acknowledges/resolves it without driving. |
| `options` | `any` | no | — | — |
| `max_wait_seconds` | `integer` | no | — | ≥ 0 |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `status` | one of `resolved`, `rejected`, `timeout`, `cancelled` | yes |
| `message` | `string` | no |
| `resolved_by` | `string` | no |
| `resolved_at` | `number` or `null` | yes |
| `request_id` | `string` | yes |

Errors: [`ATTENTION_REQUIRES_HTTP`](/docs/reference/errors/#ATTENTION_REQUIRES_HTTP), [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="get_attention_result"></a>
### `get_attention_result`

**Get attention result** · capability `attention` · since 0.1.0

> Retrieve the outcome of a prior request_attention by its request_id. Returns immediately if the request is already resolved/rejected/timed-out; otherwise BLOCKS like request_attention until it settles. Use to recover a decision after a dropped connection. http transport only.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `request_id` | `string` | yes | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `status` | one of `resolved`, `rejected`, `timeout`, `cancelled` | yes |
| `message` | `string` | no |
| `resolved_by` | `string` | no |
| `resolved_at` | `number` or `null` | yes |
| `request_id` | `string` | yes |

Errors: [`ATTENTION_REQUIRES_HTTP`](/docs/reference/errors/#ATTENTION_REQUIRES_HTTP). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

## Vault

<a id="vault_list_available"></a>
### `vault_list_available`

**Vault: list available** · capability `credential` · since 0.1.0

> List the vault entries you may fill on the page this session is currently on. Returns { entries: [{ entry_name, allowed_origins, redact_username, require_no_evaluate }], scope, scoped_to, note? }. Results are SCOPED to the session's current page — navigate to the login page first, then call this. Pass `url` = the domain of that login page (e.g. "github.com"); if it does not match the page the session is actually on, the request is denied and reported. An entry only appears after an operator authorizes this session for it. Never returns secrets.

Annotations: readOnly yes · destructive no · idempotent yes · openWorld no

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `url` | `string` | no | — | The domain (or URL) of the login page you have navigated to, e.g. "github.com". Results are scoped to this site. Pass only the domain — not the full URL with its path/query — the session already holds the exact page. If it does not match the page the session is actually on, the request is denied and reported. |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `entries` | `object[]` | yes |
| `scope` | one of `unscoped`, `page`, `no_page`, `rejected` | yes |
| `scoped_to` | `string` or `null` | yes |
| `mismatch` | `object` | no |
| `note` | `string` | no |

Errors: [`VAULT_NOT_CONFIGURED`](/docs/reference/errors/#VAULT_NOT_CONFIGURED), [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).

<a id="vault_fill"></a>
### `vault_fill`

**Vault: fill** · capability `credential` · since 0.1.0

> Atomically inject a vault credential into a login form: origin re-check, fetch from the backend, fill username + password, optional submit, then redact. `entry_name` is the stable handle from vault_list_available. The filled values are LEFT in the form by default — pass `clear_after_fill: true` only if you want the inputs wiped after the fill (done after `after_submit_wait_ms`, so an async/AJAX submit still reads them). Returns { status: "success" | "origin_mismatch" | "auth_failed" | "blocked", redacted: true, reason? }. The credential never appears in the response, logs, events, or screenshots. The origin is checked against the entry allow-list by registrable domain.

Annotations: readOnly no · destructive no · idempotent no · openWorld yes

Parameters:

| Name | Type | Required | Default | Notes |
|---|---|---|---|---|
| `session_id` | `string` | yes | — | — |
| `entry_name` | `string` | yes | — | min length 1 |
| `username_selector` | `string` | yes | — | min length 1 |
| `password_selector` | `string` | yes | — | min length 1 |
| `submit_selector` | `string` | no | — | min length 1 |
| `after_submit_wait_ms` | `integer` | no | — | ≥ 0 |
| `clear_after_fill` | `boolean` | no | — | — |
| `tab_id` | `string` | no | — | — |

Result (JSON text block, mirrored in `structuredContent`):

| Field | Type | Always present |
|---|---|---|
| `status` | one of `success`, `origin_mismatch`, `auth_failed`, `blocked` | yes |
| `redacted` | `true` | yes |
| `reason` | `string` | no |

Errors: [`VAULT_NOT_CONFIGURED`](/docs/reference/errors/#VAULT_NOT_CONFIGURED), [`VAULT_LOCKED`](/docs/reference/errors/#VAULT_LOCKED), [`SESSION_NOT_FOUND`](/docs/reference/errors/#SESSION_NOT_FOUND), [`SESSION_DEAD`](/docs/reference/errors/#SESSION_DEAD), [`SESSION_ACCESS_DENIED`](/docs/reference/errors/#SESSION_ACCESS_DENIED). Any tool may also return [`INVALID_ARGUMENTS`](/docs/reference/errors/#INVALID_ARGUMENTS) and [`INTERNAL_ERROR`](/docs/reference/errors/#INTERNAL_ERROR).