Interaction¶
Interaction tools let an agent act on the page — clicking, typing, filling forms, selecting dropdown options, dragging elements, hovering, pressing keys, handling JavaScript dialogs, and completing file uploads. Reach for these tools any time a workflow requires manipulating page content rather than just reading it. All element-targeting tools accept a ref obtained from a prior browser_snapshot call; see Refs & snapshots for how refs work and when they become stale, and Inspection tools for the tools that produce them.
Examples below focus on tool-specific data. Registered tools also return the shared operation metadata and error fields. Page actions check for blocking modals after acquiring the instance's action lock. Dialog and upload recovery use a separate lock so they can resolve a modal while its triggering action is still waiting.
Optional page_id selects a live page without changing the selected tab; an invalid
explicit target returns page_not_found. Frame-capable calls also accept frame_id
and return frame_not_found for a detached or foreign frame. Omitted targets retain
existing behavior. See explicit targeting.
browser_click¶
Click an element by its accessibility ref from browser_snapshot.
Signature
async def browser_click(
instance: str,
ref: str,
*,
double_click: bool = False,
button: str = "left",
modifiers: list[str] | None = None,
page_id: str | None = None,
frame_id: str | None = None,
wait_for: WaitForSpec | None = None,
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
ref |
str |
— | Element ref from browser_snapshot (e.g. "e5"). See Refs & snapshots. |
double_click |
bool |
False |
Perform a double-click instead of a single click. |
button |
str |
"left" |
Mouse button: "left", "right", or "middle". |
modifiers |
list[str] \| None |
None |
Keyboard modifiers held during the click. Valid values: "Alt", "Control", "ControlOrMeta", "Meta", "Shift". |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
frame_id |
str \| None |
None |
Attached frame ID from browser_frames; explicit scope never falls back to another frame. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "clicked": "e5" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundstale_refinvalid_paramsmodal_state_blockedinternal_error
Example
Request:
{ "name": "browser_click", "arguments": { "instance": "main", "ref": "e5" } }
Response:
{ "status": "success", "instance": "main", "data": { "clicked": "e5" } }
Notes — The element is scrolled into view and clicked at its center. May trigger navigation, form submission, or open a modal. After a click that causes navigation, snapshot refs are invalidated — take a fresh snapshot before referencing page elements again.
browser_type¶
Type text into an editable element identified by its accessibility ref.
Signature
async def browser_type(
instance: str,
ref: str,
text: str,
*,
clear_first: bool = True,
submit: bool = False,
page_id: str | None = None,
frame_id: str | None = None,
wait_for: WaitForSpec | None = None,
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
ref |
str |
— | Element ref from browser_snapshot. See Refs & snapshots. |
text |
str |
— | Text to type. |
clear_first |
bool |
True |
Clear the existing value before typing (uses fill, which is instant). Set to False to append via simulated keystrokes. |
submit |
bool |
False |
Press Enter after typing and wait up to 2 s for domcontentloaded (useful for forms that navigate on submit). |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
frame_id |
str \| None |
None |
Attached frame ID from browser_frames; explicit scope never falls back to another frame. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "typed_into": "e12" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundstale_refmodal_state_blockedinternal_error
Example
Request:
{
"name": "browser_type",
"arguments": { "instance": "main", "ref": "e12", "text": "[email protected]" }
}
Response:
{ "status": "success", "instance": "main", "data": { "typed_into": "e12" } }
browser_fill_form¶
Fill multiple form fields in one call, in the order provided.
Signature
async def browser_fill_form(
instance: str,
fields: list[dict[str, Any]],
*,
page_id: str | None = None,
frame_id: str | None = None,
wait_for: WaitForSpec | None = None,
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
fields |
list[dict] |
— | Ordered list of field descriptors. Each dict must have "ref" (from browser_snapshot) and "value", plus an optional "type": "textbox" (default), "checkbox", "radio", or "combobox". See Refs & snapshots. |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
frame_id |
str \| None |
None |
Attached frame ID from browser_frames; explicit scope never falls back to another frame. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "filled_count": 3 }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundstale_refinvalid_paramsmodal_state_blockedinternal_error
Example
Request:
{
"name": "browser_fill_form",
"arguments": {
"instance": "main",
"fields": [
{ "ref": "e10", "value": "Alice" },
{ "ref": "e11", "value": "[email protected]" },
{ "ref": "e12", "value": true, "type": "checkbox" }
]
}
}
Response:
{ "status": "success", "instance": "main", "data": { "filled_count": 3 } }
Notes — Filling is sequential: if any field fails, the tool stops at that field and earlier fields retain their new values. Take a fresh snapshot to verify the form state after a partial failure. Checkbox and radio values are coerced via coerce_bool, which accepts real booleans or the strings "true"/"false"/"1"/"0"/"checked"/"unchecked"/"yes"/"no" (case-insensitive).
browser_select_option¶
Select an option in a <select> dropdown by its HTML value attribute.
Signature
async def browser_select_option(
instance: str,
ref: str,
value: str | list[str],
*,
page_id: str | None = None,
frame_id: str | None = None,
wait_for: WaitForSpec | None = None,
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
ref |
str |
— | Ref of the <select> element from browser_snapshot. See Refs & snapshots. |
value |
str \| list[str] |
— | HTML value attribute of the option to select (not the display label). Pass a list for multi-select elements. |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
frame_id |
str \| None |
None |
Attached frame ID from browser_frames; explicit scope never falls back to another frame. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "selected": "us" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundstale_refmodal_state_blockedinternal_error
Example
Request:
{
"name": "browser_select_option",
"arguments": { "instance": "main", "ref": "e20", "value": "us" }
}
Response:
{ "status": "success", "instance": "main", "data": { "selected": "us" } }
Notes — Use the snapshot to inspect option elements nested under the <select> to find the correct value attributes. To select multiple options, pass a list: "value": ["opt1", "opt2"].
browser_hover¶
Hover the mouse over an element identified by its accessibility ref.
Signature
async def browser_hover(
instance: str,
ref: str,
*,
page_id: str | None = None,
frame_id: str | None = None,
wait_for: WaitForSpec | None = None,
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
ref |
str |
— | Element ref from browser_snapshot. See Refs & snapshots. |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
frame_id |
str \| None |
None |
Attached frame ID from browser_frames; explicit scope never falls back to another frame. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "hovered": "e8" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundstale_refmodal_state_blocked
Example
Request:
{ "name": "browser_hover", "arguments": { "instance": "main", "ref": "e8" } }
Response:
{ "status": "success", "instance": "main", "data": { "hovered": "e8" } }
Notes — The element is scrolled into view and the cursor is positioned at its center. Useful for triggering hover-activated menus, tooltips, or CSS :hover styles. Take a fresh snapshot after hovering to observe any newly-revealed elements.
browser_drag¶
Drag an element to a target element using accessibility refs.
Signature
async def browser_drag(
instance: str,
source_ref: str,
target_ref: str,
*,
page_id: str | None = None,
frame_id: str | None = None,
wait_for: WaitForSpec | None = None,
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
source_ref |
str |
— | Ref of the element to drag (from browser_snapshot). See Refs & snapshots. |
target_ref |
str |
— | Ref of the drop target (from browser_snapshot). |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
frame_id |
str \| None |
None |
Attached frame ID from browser_frames; explicit scope never falls back to another frame. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "dragged": "e3", "to": "e7" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundstale_refmodal_state_blockedinternal_error
Example
Request:
{
"name": "browser_drag",
"arguments": { "instance": "main", "source_ref": "e3", "target_ref": "e7" }
}
Response:
{ "status": "success", "instance": "main", "data": { "dragged": "e3", "to": "e7" } }
Notes — Performs a full pointer-event drag sequence: mouse-down on the source, move to the target center, mouse-up. This supports drag-and-drop implementations that respond to pointer events.
Native HTML5 draggable / DataTransfer behavior depends on the application and browser backend. Check the resulting page state to confirm that the intended drop occurred.
browser_press_key¶
Press a keyboard key on the active page (sent to whatever element currently has focus).
Signature
async def browser_press_key(
instance: str, key: str, *, page_id: str | None = None, wait_for: WaitForSpec | None = None
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
key |
str |
— | Playwright key name, e.g. "Enter", "Tab", "Escape", "ArrowDown", "Control+A", "Shift+Tab". |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
wait_for |
WaitForSpec \| None |
None |
One condition armed before the action; see action observations. |
Returns — see response envelope. data shape:
{ "pressed": "Tab" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundmodal_state_blockedinternal_error
Example
Request:
{ "name": "browser_press_key", "arguments": { "instance": "main", "key": "Tab" } }
Response:
{ "status": "success", "instance": "main", "data": { "pressed": "Tab" } }
Notes — When key is "Enter", the tool waits up to 2 s for domcontentloaded in case the key triggers a form submission. See the Playwright keyboard documentation for the full list of key names.
browser_file_upload¶
Resolve a pending native file-chooser dialog by attaching files or cancelling.
Signature
async def browser_file_upload(
instance: str, paths: list[str] | None = None, *, page_id: str | None = None
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
paths |
list[str] \| None |
None |
Absolute paths of the files to attach. None or an empty list cancels the file chooser without attaching any files. |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
Returns — see response envelope. data shape (mutually exclusive):
{ "uploaded_count": 2 }
{ "cancelled": true }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundmodal_state_blockedinternal_error
Example
Request:
{ "name": "browser_file_upload", "arguments": { "instance": "main", "paths": ["/tmp/report.pdf"] } }
Response:
{ "status": "success", "instance": "main", "data": { "uploaded_count": 1 } }
Notes — A file-chooser must already be pending before calling this tool (opened by a prior browser_click on a file input). The modal-state listener captures the chooser automatically. This tool can run while the triggering action is still waiting. If resolution fails or is cancelled while the page remains alive, the chooser is retained for retry. A chooser belonging to a closed page returns modal_state_blocked. Operation metadata identifies the chooser's page, which may be a popup rather than the active tab. See Modal state for the broader dialog/chooser lifecycle.
browser_handle_dialog¶
Resolve a pending JavaScript dialog (alert, confirm, or prompt).
Signature
async def browser_handle_dialog(
instance: str, *, accept: bool, prompt_text: str | None = None, page_id: str | None = None
) -> dict[str, Any]
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
instance |
str |
— | Instance name. |
accept |
bool |
— | True to accept the dialog (calls dialog.accept); False to dismiss it. |
prompt_text |
str \| None |
None |
Text to submit with a prompt dialog. Ignored for alert and confirm dialogs. |
page_id |
str \| None |
None |
Stable page ID; omitted uses the selected page. Explicit targeting preserves selection and rejects unavailable IDs. |
Returns — see response envelope. data shape:
{ "action": "accepted", "dialog_type": "confirm", "message": "Are you sure?" }
Errors — emits error_type codes (see envelope error codes):
instance_not_foundmodal_state_blocked
Example
Request:
{ "name": "browser_handle_dialog", "arguments": { "instance": "main", "accept": true } }
Response:
{
"status": "success",
"instance": "main",
"data": { "action": "accepted", "dialog_type": "alert", "message": "Upload complete." }
}
Notes — The dialog must already be open before calling this tool; it was triggered by a prior tool call and captured automatically by the modal-state listener. The triggering action may still be waiting: dialog recovery uses an independent lock and can unblock it. This tool does not pre-register a handler for future dialogs.
If accepting or dismissing fails or is cancelled while the page remains alive, the dialog is normally retained for retry. A definitive Playwright response that the dialog was already handled discards the stale entry and returns an error with uncertain outcome; it does not claim that this call resolved the dialog. A dialog belonging to a closed page returns modal_state_blocked. Operation metadata identifies the dialog's page, including a non-active popup. See Modal state for the broader dialog lifecycle.