Kitsune
Kitsune is an MCP server that lets an AI agent drive a shared Firefox/Zen/LibreWolf browser—working in background tabs, interacting with pages, inspecting diagnostics, and asking you when it needs help—while keeping your own tabs protected.
Manage tabs: list, open, select, close, and request temporary handoff of a user tab with approval.
Navigate: go to URLs and move back through history.
Inspect pages: capture accessibility snapshots, search snapshots, take screenshots, and get element boxes.
Interact: click, double-click, hover, drag, type, press keys, fill forms, select dropdown options, upload/drop files, and handle dialogs.
Wait for text or time, and emulate media features such as dark mode, reduced motion, contrast, forced colors, and print.
Debug: read console messages and inspect network requests, including headers and bodies.
Run custom automation via JavaScript evaluation or Playwright code snippets.
Ask the user for sign-in, CAPTCHA/human checks, trusted input, or decisions, then resume interrupted calls once ready.
Resize or close the browser window.
Respect safety controls: background tabs, read-only user tabs unless approved, read/draft/act modes, and opt-in tool groups.
Allows AI agents to drive the Firefox-family browser you already have open, providing tools for tab management, navigation, page reading, interaction (clicking, typing, filling forms), screenshots, cookies, storage, network capture, and session save/load.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Kitsuneopen a background tab to my GitHub notifications and summarize the unread ones"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Kitsune

Let your coding agent use the browser you already have open, while you keep using it too.
Kitsune connects Claude Code, Codex, Pi, OpenCode and other MCP clients to Firefox, Zen or LibreWolf. The agent works in background tabs of its own, signed in wherever you are signed in. It can read your tabs, but it has to ask before it changes one. There is no Playwright, Chromium or WebDriver to install.

A real screen recording of Claude Code and Zen on the live Google sites, sped up while the agent thinks (full 38-second video).
Why Kitsune?
It works beside you. New tabs open in the background, so the page you are on stays in front. Your tabs, and tabs other agents opened, are read-only to the agent: it can read them, but it cannot click, type, scroll, navigate or close them. If you start typing in one of the agent's own tabs, it waits.
You stay in charge. When the agent needs one of your tabs, it asks, and you answer in Kitsune's toolbar popup. You can take the tab back at any time. The popup also shows whether the agent is connected, and closes all of the agent's tabs with one click. Tabs the agent leaves idle close by themselves after five minutes (you can change this in the popup).
The tools are familiar. The agent starts with Playwright MCP's 25 core tools, under the same names, plus
browser_ask_userandbrowser_resumefor when it needs you. Prompts written for Playwright MCP work unchanged. More tools (page text, forms, batches, downloads, …) stay off until you allow them.You decide how much to hand over.
KITSUNE_MODE=read,draftoractlimits what the agent can do. In draft mode it can fill in forms but cannot click or submit.

New in 0.7.2: the agent asks for your tab, and you approve, take it back and clean up from the toolbar popup. A real recording on Wikipedia, sped up while the agent thinks (full 45-second video).
Related MCP server: browser-control
Get started
Install uv.
Install the browser extension in Firefox, Zen or LibreWolf.
Add Kitsune to your agent. For Claude Code:
claude mcp add --scope user kitsune -- uvx --from kitsune-browser-mcp kitsuneOther clients are below.
Keep the browser open and ask in plain language:
Research these three products in background tabs and compare them with links. Leave my current tab alone.
Fill in a draft of this form. Don't submit it.
Kitsune starts its local bridge on its own. If the agent cannot connect, ask it to check the
connection: the error's hint says what to fix.
Use a separate browser profile for agent work and sign in only to the accounts it needs. Ask the agent to check with you before it sends, buys or deletes anything. Nothing in Kitsune stops prompt injection, so read the security guide before using sensitive accounts.
Your tabs and approvals
Your tabs. Writes to your tabs fail at once with
user_tab_read_only, without a prompt. The agent opens its own tab instead, or asks for yours with a reason. You see the request in the toolbar popup (its badge shows a count) and approve or decline it there; after 30 seconds the agent's client asks you instead. An approved tab is the agent's until you press Take back or its session ends. It does not give the agent your real mouse or keyboard. To let the agent write to your tabs without asking, setKITSUNE_USER_TABS=writable(Protecting your tabs).Risky actions. With the opt-in ask-before-act policy, submitting forms, payment pages, JavaScript and cookie access need your approval. Claude Code and Codex ask you in their own prompt, so the approval never passes through the agent. Other clients get a one-time token the agent should show you first; it guards against accidents, not against an agent that repeats the call on its own (Approving held actions).
Things only you can do. For a sign-in, a CAPTCHA or a choice that is yours to make, the agent asks you (
browser_ask_user) and carries on when you are done (When the agent needs you).
Benchmark

Same tasks, same model (Claude Opus 5.5), same tool allowlist, one run per task:
Your tab stays in front. While a user was in the browser, Kitsune v0.7.2 never moved their view in 28 tasks. Playwright MCP, which was not built to share a browser with a person, moved it in 26.
It costs less. On the tasks both solved, Kitsune cost 0.56 to 0.97 times as much as Playwright MCP.
It solves about as many. Kitsune solved 96 of 98 tasks, Playwright MCP 98. Kitsune's two misses are one task, "go back to the tab I was on", in two variants: the user's tab stayed in front, but the agent's own tab was still its current tab, and that is what the grader checks.
See the v0.7.2 report
and the full reports.
scripts/benchmark_chart.py draws the chart from the report's numbers.
How is it different?
If you want to… | Consider |
Hand tasks to an agent in the Firefox-family browser you are using, with background tabs and read/draft/act modes | Kitsune |
Debug or profile pages in Firefox (debugger, profiler, deep protocol access) | Mozilla Firefox DevTools MCP, which attaches to a Firefox started with remote-debugging flags |
Test across Chromium, Firefox and WebKit in browsers it launches | Playwright MCP; Kitsune uses the same core tools, so prompts carry over |
Drive the Chrome you already use | A Chromium extension MCP such as Browser MCP |
Kitsune connects through an extension and a local bridge, so Firefox needs no startup flags. Other Firefox extensions also reuse your logins; Kitsune focuses on sharing the browser with you while the agent works. Positioning has the full comparison.
MCP setup
Every client runs the same local server: uvx --from kitsune-browser-mcp kitsune. Register it
once per client. Several clients can share one browser; keep them on the same Kitsune version.
Claude Code (all projects):
claude mcp add --scope user kitsune -- uvx --from kitsune-browser-mcp kitsuneCodex CLI (writes ~/.codex/config.toml):
codex mcp add kitsune -- uvx --from kitsune-browser-mcp kitsunePi (built-in MCP support;
add --local before kitsune for the current project only, then /reload in a running session):
pi mcp add kitsune -- uvx --from kitsune-browser-mcp kitsuneOpenCode: merge this into ~/.config/opencode/opencode.json or your project's opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"kitsune": {
"type": "local",
"command": ["uvx", "--from", "kitsune-browser-mcp", "kitsune"],
"enabled": true
}
}
}Claude Desktop, Cursor and Pi's JSON config use the mcpServers format. Merge this entry
into ~/Library/Application Support/Claude/claude_desktop_config.json (Claude Desktop on macOS),
~/.cursor/mcp.json or .cursor/mcp.json (Cursor), or ~/.pi/agent/mcp.json or .pi/mcp.json (Pi):
{
"mcpServers": {
"kitsune": {
"command": "uvx",
"args": ["--from", "kitsune-browser-mcp", "kitsune"]
}
}
}Restart the client and ask it to list your tabs. A desktop app that does not see your shell's
PATH may need the full path from which uvx.
On macOS, clicks with the real mouse (for example to open a "Continue with Google" popup) also
need uvx --from 'kitsune-browser-mcp[macos]' kitsune or brew install cliclick, plus
Accessibility permission (Sign-in popups).
Installation covers
environment variables, version pinning and upgrades.
Choosing tools
Kitsune's own tools come in groups. Turn them on with KITSUNE_CAPS in the server's environment:
Group | Tools for |
| Scrolling, forward navigation, checkboxes, focus, form submits, real mouse clicks |
| Page text and Markdown, forms, DOM, links, images, metadata |
| Element bounds, computed styles, selector checks, highlights |
| Pinning, muting, zoom, windows, tab tags, keep-alive |
| Batches, retries, workflows, parallel tabs, and resuming an interrupted batch |
| Downloads, request interception and capture |
| Connection status, logs, audit, cache, policy |
| Cookies, page storage, clipboard and saved sessions; history and bookmarks. These read personal data, so |
To keep the agent's starting tool list short, allow everything but publish only the core tools. The agent can then search for the others and call them in the same session:
claude mcp add --scope user kitsune -e KITSUNE_CAPS=all -e KITSUNE_PUBLISH=core -- uvx --from kitsune-browser-mcp kitsuneIn a JSON config, add "env": {"KITSUNE_CAPS": "all", "KITSUNE_PUBLISH": "core"} next to "args".
See Tools for every tool and
Task modes for read, draft and act.
Python API
The same extension and bridge work from your own scripts. pip install kitsune-browser gives you
the Python API with every tool group:
import kitsune
browser = kitsune.connect() # starts the bridge if none runs
tab = browser.new_tab("https://news.ycombinator.com") # a background tab you don't see
for link in tab.query(".titleline > a", fields=["text", "href"], limit=3):
print(link["text"], link["href"])
tab.close()The same tab rules apply: new tabs open in the background, your tabs are read-only, and sensitive fields stay hidden. See Python API. If you installed 0.6.0 or earlier with pip, see Upgrading.
More documentation
Guide · Configuration · Troubleshooting · Updating · API reference · Philosophy · Positioning · Development · FAQ
Available Tools
27 toolsbrowser_ask_userARead-only
Ask the user to do what you cannot: sign in, pass a CAPTCHA (human_check), click a control that ignores your clicks (trusted_input), or choose (other).
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| tab_id | No | Default: current tab. | |
| message | Yes | What the user should do, addressed to them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds the human-handoff model, but does not say whether the call blocks until the user responds, whether it returns a status immediately, or what happens on timeout – the key behavioral questions for a handoff tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the core action and then the enumerated cases. No redundant restatement of the name or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations about interaction semantics, the description should say what the agent gets back and whether it waits – a real gap for a tool whose whole purpose is a blocking-style handoff. It is otherwise sufficient for a 3-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema leaves the 'reason' enum values undocumented; the description supplies meaning for three of them (human_check=CAPTCHA, trusted_input=ignored clicks, other=choose), which is genuine value beyond the schema. tab_id's default and message's purpose are already covered by schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Ask the user') plus the exact class of situations it exists for (sign in, CAPTCHA, unclickable control, free choice). That framing is distinct from every sibling, which are browser-automation actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The enumerated reasons implicitly define when to call it – when the agent cannot complete the step itself – and 'do what you cannot' sets the condition. It stops short of stating when NOT to use it (e.g. prefer retry/navigate first) or what to do after the user acts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_clickBDestructive
Perform click on a web page
| Name | Required | Description | Default |
|---|---|---|---|
| button | No | Button to click, defaults to left | |
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element | |
| modifiers | No | Modifier keys to press | |
| doubleClick | No | Whether to perform a double click instead of a single click |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true, indicating the tool mutates state and can be destructive. The description adds no further behavioral disclosure, such as possible navigation or permission requirements. It does not contradict annotations, but provides no value beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no filler. However, it is terse and omits useful context that could be added without bloat, such as the requirement for a snapshot target. It is appropriately sized but not front-loaded with any distinguishing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (5 parameters, no output schema), the description alone is minimally sufficient because the schema fully describes parameters. However, it lacks context about return values, when to use click vs other actions, and potential side effects. The schema covers parameter semantics, so a score of 3 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with every parameter documented (e.g., target is 'Exact target element reference from the page snapshot, or a unique element selector'). The description itself adds no additional parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Perform click') and the resource ('web page'), which is specific enough. However, it does not differentiate from sibling interaction tools like browser_hover or browser_drag; the agent must infer that 'click' is a distinct action without additional context. It is unambiguous about the core operation but lacks detail on the target element requirement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention prerequisites such as needing a page snapshot to obtain a valid target, nor does it contrast with browser_hover or browser_drag. An agent receives no context for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_closeBDestructive
Close the page
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation already indicates destructiveHint=true, so the agent knows the action is destructive. The description simply repeats that by saying 'close' without adding any extra context about side effects (e.g., whether it closes just the current tab, loses unsaved state, or affects other tabs). It does not contradict the annotation, but it adds no new behavioral information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, using only three words. It communicates the essential action and target without any fluff, making it easy to parse and understand quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (no parameters, no output schema), the description is functional but lacks completeness. It leaves open the scope of 'close'—does it close the current page/tab, or the entire browser? In a context with sibling tools like browser_tabs, this ambiguity could be problematic. More detail would improve it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so the schema coverage is trivially complete at 100%. The description does not need to explain any parameter semantics, and the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Close the page' clearly states the action (close) and the resource (page), making it unambiguous. It is distinct from sibling tools like browser_navigate or browser_snapshot, so an agent can easily identify it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention potential alternatives (e.g., using browser_tabs to manage multiple pages) or any conditions that would make closing appropriate. The context is minimal and leaves the decision entirely to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_console_messagesCRead-only
Returns all console messages
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Return all console messages since the beginning of the session, not just since the last navigation. Defaults to false. | |
| level | Yes | Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to "info". | info |
| filename | No | File name to save the console messages to. Relative file names are resolved against the workspace root. If not provided, messages are returned as text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The free-text adds almost no behavioral nuance beyond what annotations already provide. It does not mention the default scope of 'after navigation' versus 'from the session start' (controlled by the 'all' flag), nor the possibility of saving to a file rather than returning text. The sentence simply restates the resource name without additional procedural insight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The one-sentence description is extremely concise and free of unnecessary wording, front-loading the main idea efficiently. It could be longer, but as a brief summary it is appropriately structured and not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool's behavior is actually nuanced—console messages can be filtered by severity level and can be limited to the current page. The description fails to explain the return format ( text or file) or the existence of these parameters/capabilities. Without supplemental information from the schema, an agent might assume 'all' means all severities whereas only retrieving info-level messages by default is the actual outcome.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides complete descriptions for all 3 parameters and covers 100% of them, so the baseline is adequate. The description adds no extra meaning about level filtering, filename handling, or the interaction between 'all' and 'level'; it does not conflict but also does not compensate beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource ('console messages') and a specific action ('Returns'), and the tool name confirms this. It can be clearly distinguished from sibling tools like browser_network_requests or browser_snapshot, which address different browser features. However, the word 'all' is slightly misleading because the level parameter actually filters output.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use this tool versus alternatives, nor any mention of typical use cases, prerequisites, or exclusions. The description only states the core product and does nothing to route an agent to the correct selection between this and related browser tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_dragADestructive
Perform drag and drop between two elements
| Name | Required | Description | Default |
|---|---|---|---|
| endTarget | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| endElement | No | Human-readable target element description used to obtain the permission to interact with the element | |
| startTarget | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| startElement | No | Human-readable source element description used to obtain the permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true and readOnlyHint=false, so the destructive nature is covered. The description adds no extra behavioral context such as side effects on the DOM or event firing, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the action and provides the core information without any irrelevant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple action with well-described parameters and no output schema, the description is mostly complete. It does not mention any return values or wait behavior, but the lack of output schema makes this acceptable. It could have added a note about the order of start and end parameters, but the parameter names and descriptions handle that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with all four parameters described. The tool description adds no additional parameter semantics beyond what the schema already provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (perform drag and drop) and the resource (between two elements), distinguishing it from sibling tools like browser_click, browser_hover, and browser_drop. It is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any guidance on when to use this tool versus alternatives. It does not mention conditions such as needing to move an element or triggering drag-and-drop events, nor does it reference sibling tools like browser_drop or browser_click.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_dropADestructive
Drop files or MIME-typed data onto an element, as if dragged from outside the page. At least one of "paths" or "data" must be provided.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Data to drop, as a map of MIME type to string value (e.g. {"text/plain": "hello", "text/uri-list": "https://example.com"}). | |
| paths | No | Absolute paths to files to drop onto the element. | |
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey destructive and non-read-only behavior, so the description does not need to repeat that. The description adds useful semantic context about simulating an external drag, but does not disclose any side effects beyond the basic drop action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that concisely explains both the action and the key parameter requirement. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description, combined with the detailed schema and annotations, provides enough information to invoke the tool correctly. There is no output schema, so return-value details are not required, and the parameter permission explanation is handled by the 'element' field description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All parameters have clear schema descriptions. The tool description adds an important cross-parameter constraint that at least one of 'paths' or 'data' must be provided, which is not otherwise expressed in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: dropping files or MIME-typed data onto an element. It uses a specific verb and resource, and distinguishes itself from in-page drag operations by specifying 'as if dragged from outside the page'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a useful usage constraint ('At least one of paths or data must be provided') and hints at external drag context, but it does not explicitly name sibling tools or state when to prefer this over browser_file_upload or browser_drag.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_emulate_mediaADestructive
Emulate CSS media features for the page, for example switch between the light and dark color scheme. Omitted parameters are left unchanged; null clears an override.
| Name | Required | Description | Default |
|---|---|---|---|
| media | No | Changes the CSS media type of the page | |
| contrast | No | Emulates the prefers-contrast media feature | |
| colorScheme | No | Emulates the prefers-color-scheme media feature | |
| forcedColors | No | Emulates the forced-colors media feature | |
| reducedMotion | No | Emulates the prefers-reduced-motion media feature |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal a non-read-only, potentially destructive operation. The description adds genuine behavioral nuance: omitted parameters are left unchanged, and null clears an override, which clarifies how state mutates and how to reset it. This adds value beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences: the first states the tool's purpose with an example, and the second states the omission/null behavior. No filler is present, and the primary action is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with five optional parameters and complete schema coverage, the description is largely sufficient. It lacks explicit details about persistence scope or how to clear all overrides at once, but the null-clears-override rule and the schema fill most practical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all five parameters thoroughly, so the baseline is 3. The description adds a cross-cutting semantic not present in the schema: omitted parameters remain unchanged while null clears an override. This distinction is essential for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Emulate'), names the resource ('CSS media features for the page'), and includes a concrete light/dark example. This clearly distinguishes it from the sibling browser tools and tells an agent exactly what domain it operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides important invocation semantics: omitted parameters are left unchanged, and null clears an override. However, it does not explicitly state when to prefer this tool over alternatives, though the unique purpose among siblings makes the intended context largely inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_evaluateCDestructive
Evaluate JavaScript expression on page or element
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element | |
| filename | No | File name to save the result to. Relative file names are resolved against the workspace root. If not provided, result is returned as text. | |
| function | Yes | () => { /* code */ } or (element) => { /* code */ } when element is provided |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, indicating this is a mutating, potentially harmful operation. The description adds no additional behavioral context—no mention of side effects, permission requirements, or what exactly could be destroyed. It essentially restates the tool's name without enriching the safety profile beyond what the annotations already provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise—a single sentence. While this is efficient, it lacks any structural breakdown or additional context. It is not front-loaded with critical details like safety warnings or usage hints. It is concise but under-specified, missing the balance between brevity and informativeness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (executes arbitrary JavaScript) and destructive nature, the description is notably incomplete. It does not explain return value format, error handling, or what happens when the function mutates the page. There is no output schema, so the description must cover these aspects, but it fails to do so. The presence of a sibling like browser_run_code_unsafe further highlights the need for differentiation, which is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (target, element, filename, function) is documented in the schema. The description adds no extra semantic information about the parameters, such as how the function signature works or how target interacts with element. Since the schema fully covers parameter meanings, a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Evaluate JavaScript expression') and the target ('on page or element'). It is specific enough to convey the core function. However, it does not differentiate from the sibling tool browser_run_code_unsafe, which also executes JavaScript, so the agent might struggle to choose between them based solely on the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives. It does not mention browser_run_code_unsafe or any other relevant sibling, nor does it state any prerequisites, limitations, or conditions that would steer the agent toward or away from this tool. This leaves the agent without clear decision support.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_file_uploadBDestructive
Upload one or multiple files
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate destructive behavior and non-read-only semantics, so the description does not need to restate those. However, the description does not mention side effects beyond uploading, such as navigating away, opening or cancelling a file chooser, or potential overwrite behavior, though the parameter description partially covers the cancellation case.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise and free of filler. Every word contributes meaning, and the parameter description adds necessary details without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no output schema, the description and parameter comment cover the essential input and basic behavior. However, it does not describe what happens after the upload, what success or failure looks like, or how this fits into the broader browser automation workflow, leaving some practical context missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines an array of strings, but the parameter description adds important meaning: paths must be absolute, multiple files are allowed, and omitting the parameter cancels the file chooser. This goes beyond the raw schema and helps an agent use the parameter correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Upload') and the resource ('files'), and specifies 'one or multiple'. It does not explicitly state the destination or context, but the tool name and sibling set make the browser file-upload intent sufficiently clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives such as browser_drop or other browser interaction tools. It also does not mention prerequisites like whether the file chooser must already be open or how paths should be formatted beyond 'absolute'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_fill_formBDestructive
Fill multiple form fields
| Name | Required | Description | Default |
|---|---|---|---|
| fields | Yes | Fields to fill in |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=false and destructiveHint=true, so the write and potentially destructive nature is covered. The description adds the 'multiple form fields' detail but does not disclose additional behavior such as overwriting values or submitting the form.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence with no redundant words or boilerplate. It is appropriately short and easy to parse, though it sacrifices deeper context for brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The rich schema fully documents the nested field objects, including target references, type-specific value behavior, and permission-related element descriptions. Combined with the read-only and destructive annotations, the description is sufficient for correct invocation; only alternative-selection guidance is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%: the fields array and its nested target, name, type, value, and element properties all have descriptive text. The description itself does not add parameter-level meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Fill multiple form fields' clearly identifies the action and resource, and the word 'multiple' helps distinguish it from single-field tools like browser_type. It does not explicitly contrast with sibling tools, but the core purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided for when to use this tool instead of alternatives such as browser_type, browser_select_option, or browser_click. The term 'multiple' implies batch usage, but there is no explicit when-to-use or exclusion context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_findARead-only
Search the accessibility snapshot of the current page for text or a regular expression. Returns matching snapshot nodes with a few lines of surrounding context (like search snippets), each shown under its path from the root of the tree, which is cheaper than capturing the whole snapshot when you only need to locate an element and its ref.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Plain text to search for in the page snapshot (case-insensitive substring match). Provide either text or regex, not both. | |
| regex | No | Regular expression to search for in the page snapshot. Matching is case-sensitive by default; wrap the pattern in slashes to add flags, e.g. "/error/i" for case-insensitive. Provide either text or regex, not both. | |
| filename | No | Save results to a file instead of returning them in the response. Relative file names are resolved against the workspace root. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/non-destructive/openWorld, so the bar is lower. The description adds valuable behavioral context the annotations don't: matching nodes are returned with surrounding context snippets under their tree path, which sets expectations about result shape and relative cost.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence, front-loaded with what it searches and what it returns. It is efficient, though the third clause (cost comparison) is slightly compressed and could be its own sentence for readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but the description explains the return values (matching nodes, context snippets, tree paths), which is the key missing piece. For a read-only find tool with full annotation and schema coverage, this is essentially complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema fully documents text, regex, and filename including mutual exclusivity and case sensitivity rules. The description only restates 'text or a regular expression' and adds no syntax detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (accessibility snapshot of the current page) and even describes the return shape. It implicitly distinguishes itself from browser_snapshot by framing itself as the cheaper alternative for locating an element.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly indicates the use case: use this when you only need to locate an element and its ref rather than capture the whole snapshot. The alternative (full snapshot) is described by function but not named explicitly, so routing is clear but not fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_handle_dialogCDestructive
Handle a dialog
| Name | Required | Description | Default |
|---|---|---|---|
| accept | Yes | Whether to accept the dialog. | |
| promptText | No | The text of the prompt in case of a prompt dialog. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations indicate readOnlyHint=false and destructiveHint=true, covering the main safety aspect. However, the description adds no detail about side effects, such as submitting a form or canceling a prompt, beyond what the parameter names imply. It does not clearly disclose the consequences of accepting or rejecting.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely short and lacks necessary detail, making it under-specified. It is terse but not informative enough to guide an agent effectively, similar to a placeholder like 'Process'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema or additional context is provided. The description does not explain what happens after handling the dialog, how the parameters interact, or any post-conditions. This is insufficient for an agent to fully understand the tool's behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear descriptions for both 'accept' (boolean) and 'promptText' (string for prompt dialogs). The description does not add extra meaning, but the schema already provides adequate parameter semantics, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Handle a dialog' identifies the action and resource but is vague. It does not specify the type of dialog (alert, confirm, prompt) or the precise effect, though the 'accept' parameter implies accept/dismiss. It is distinct from sibling tools, but the purpose is under-specified.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool, such as after a dialog appears or in contrast to other browser actions. The description gives no context for the appropriate situation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_hoverADestructive
Hover over element on page
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and destructiveHint=true, so the description doesn't need to re-state them. The description adds no extra behavioral detail about side effects (e.g., triggering JavaScript events, potential menu changes). With annotations present, the bar is lower, but there's still room for more transparency about outcomes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise—six words, no redundancy, and perfectly focused on the action. It follows a clear verb-object structure with no extra fluff, making it easy to parse and understand.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple interaction tool, the description, alongside the parameter schema and annotations, is adequate. It lacks details on return values (but no output schema exists) and does not mention any prerequisites or setup. Given the simplicity, it covers essential context without being overlong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters (target and element) have descriptions in the schema, achieving 100% coverage. The tool description does not add further meaning beyond the schema; it simply restates the action. Since schema coverage is complete, a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (hover) and the target (element on page). It distinguishes itself from sibling tools like click, drag, and type by specifying the hover action. However, it lacks detail about what the hover does (e.g., showing tooltips or hover menus), but the core purpose is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use hover versus other interactions. While it's intuitive that hover is for mouse-over actions, the description doesn't mention edge cases or alternative tools (e.g., use click for activating, hover for previews). It provides minimal implicit usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_network_requestARead-only
Returns full details (headers and body) of a single network request, or a single part if part is set. Use the number from browser_network_requests.
| Name | Required | Description | Default |
|---|---|---|---|
| part | No | Return only this part of the request. Omit to return full details. | |
| index | Yes | 1-based index of the request, as printed by browser_network_requests. | |
| filename | No | File name to save the result to. Relative file names are resolved against the workspace root. If not provided, output is returned as text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so no safety disclosure is needed. The description adds that the result includes headers and body and that `part` narrows the output, but it does not describe deeper behavior such as response size, formatting, or error cases. This is acceptable for a read-only tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single focused sentence plus one essential usage pointer. No filler, and the core behavior is front-loaded before the optional part behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only retrieval tool with one required parameter and complete schema descriptions, the description covers the essential invocation path: select a request from the list, optionally choose a part, and get full details. It does not explain output structure beyond 'headers and body,' but no output schema exists and the tool's behavior is straightforward.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents index, part, and filename. The description's mention of `part` and the index reference restates schema content rather than adding new meaning. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Returns full details ... of a single network request') and immediately contrasts with the plural sibling by referencing the index from browser_network_requests. This makes the tool's singular, detail-retrieval role unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context: use an index obtained from browser_network_requests, and optionally narrow to one part via `part`. It does not explicitly state when not to use this tool versus alternatives, but the singular-vs-list relationship to the sibling is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_network_requestsARead-only
Returns a numbered list of network requests since loading the page. Use browser_network_request with the number to get full details.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | Only return requests whose URL matches this regexp (e.g. "/api/.*user"). | |
| static | Yes | Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false. | |
| filename | No | File name to save the network requests to. Relative file names are resolved against the workspace root. If not provided, requests are returned as text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds useful behavioral context by noting the list is numbered and scoped to requests since page load, plus it explicitly points to the companion tool for deeper inspection. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, with the core behavior first and the routing instruction second. Every sentence earns its place and there is no redundant wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool, the description explains what is returned, the page-load scope, and the natural next step for details. The input schema handles parameter semantics and filename behavior, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents filter, static, and filename. The tool description does not add parameter-level details, but it does not need to because the schema already carries that burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Returns a numbered list of network requests since loading the page.' It also explicitly distinguishes the tool from its sibling browser_network_request by telling the agent to use that sibling with a number for full details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear workflow: list requests here, then call browser_network_request with the number for details. This directly tells the agent when to use this tool versus the relevant alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_press_keyBDestructive
Press a key on the keyboard
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Name of the key to press or a character to generate, such as `ArrowLeft` or `a` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not mention any side effects, such as triggering keyboard events or potential destructive behavior. The annotations indicate destructiveHint: true, but the description adds no additional behavioral context beyond that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise — a single sentence that directly conveys the action. No unnecessary information or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple action with a single well-defined parameter, the description is adequate. It lacks mention of when to use this tool (e.g., for shortcuts or navigation keys) but is otherwise complete for basic invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The parameter 'key' is fully described in the schema with examples, and schema coverage is 100%. The description adds minimal extra meaning ('on the keyboard') but doesn't clarify key formats or special keys, which is already covered by the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (press) and the resource (key on the keyboard). It is distinct from broader actions like navigate or click, though it does not explicitly differentiate from browser_type (typing) or browser_click (clicking).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus its siblings (e.g., browser_type for text entry or browser_click for mouse actions). The description lacks any contextual cues for choosing this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_resizeBDestructive
Resize the browser window
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | Width of the browser window | |
| height | Yes | Height of the browser window |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not disclose any behavioral traits beyond the bare action. Annotations already indicate it is not read-only and is destructive, but the description adds no extra context about side effects like layout reflows or potential viewport changes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, short declarative sentence with no unnecessary words. It is perfectly concise and well-structured for the simple action it describes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool, the description is adequate, but it lacks any extra context such as units (e.g., pixels), constraints, or when resizing might be appropriate. Given the simplicity and schema coverage, it is minimally complete but not rich.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides descriptions for both parameters (width and height), achieving 100% coverage. The description adds no additional meaning about the parameters, so it stays at the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (resize) and the resource (browser window), making it distinct from sibling tools like navigate or click. However, it lacks any nuance about whether it resizes the viewport or the entire window, but the core purpose is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives. It does not mention scenarios like adjusting viewport for responsive testing or any conditions that would make it preferable to other navigation tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_resumeADestructive
Continue a call whose result has call and resume_token (a needs_user stop, batch, parallel or workflow); nothing that ran ok is sent again.
| Name | Required | Description | Default |
|---|---|---|---|
| call | Yes | ||
| wait | No | Seconds to wait for the user, 0-300. | |
| observed | No | Unknown container step's progress path ("0.1") -> "not_applied" (send again) or "applied" (mark ok). | |
| resume_token | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, idempotentHint=false and openWorldHint=true; the description adds the useful fact that previously successful steps are not re-sent, which is real behavioral context. However, given the destructive flag it says nothing about what the re-sent (failed) steps may do, what happens if 'wait' expires, or whether resuming twice is safe — the risk side of a destructive tool is undisclosed. No contradiction with annotations, just an incomplete behavioral picture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, no padding, and the trigger condition is front-loaded before the behavioral clause. Slightly over-compressed wording costs a bit of readability but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent tool with a nested 'observed' object and no output schema, the definition covers the happy path but omits failure handling: what happens when 'wait' elapses without user input, and how the 'observed' applied/not_applied map should be used to recover a partially-applied step. The schema covers 'observed' mechanics, which keeps this from being lower, but the operational gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50%, and the description specifically compensates for the two undocumented parameters: it tells the agent that 'call' and 'resume_token' are values taken from a previous call's result, not agent-invented inputs. The remaining 'wait' and 'observed' parameters are fully documented in the schema itself, so the combined coverage is complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Continue') on a specific resource ('a call') and pins the trigger to a prior result carrying 'call' and 'resume_token' from a needs_user stop, batch, parallel or workflow. That is enough to distinguish it from every sibling, none of which resume an interrupted call. It stops short of 5 because the compressed phrasing ('nothing that ran ok is sent again') takes a second read to parse.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use the tool: when a prior result contains 'call' and 'resume_token' from one of four interruption types. No alternatives or when-not conditions are named, but no sibling competes for this job, so the trigger alone is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_run_code_unsafeADestructive
Run a Playwright code snippet. Unsafe: executes arbitrary JavaScript in the Playwright server process and is RCE-equivalent.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction. For example: `async (page) => { await page.getByRole('button', { name: 'Submit' }).click(); return await page.title(); }` | |
| filename | No | Load code from the specified file. Relative file names are resolved against the workspace root. If both code and filename are provided, code will be ignored. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though destructiveHint=true and readOnlyHint=false already signal danger, the description adds crucial context: the code runs in the Playwright server process, can execute arbitrary JavaScript, and is RCE-equivalent. This is more transparent than the annotation alone and gives an agent a concrete safety boundary.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences deliver the action, the resource, the execution context, and a stark safety warning. Every word earns its place, and the danger is front-loaded immediately after the verb.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a dangerous arbitrary-code tool with no output schema, the description gives the critical context an agent needs: where the code runs and why it is unsafe. It does not describe the return value or error behavior, but given the open-ended nature of the tool and the complete parameter schema, this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both 'code' and 'filename' are already well documented in the schema, including the precedence rule when both are provided. The description adds no parameter-specific meaning, but it does not need to because the schema carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Run'), a specific resource ('a Playwright code snippet'), and immediately identifies the defining scope: arbitrary JavaScript in the Playwright server process. This clearly sets it apart from sibling tools like browser_evaluate, which executes in the page, even though both are code-execution tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not name alternatives explicitly, but the 'Unsafe' and 'RCE-equivalent' framing strongly implies this is a last-resort escape hatch rather than a routine tool. It gives enough context for an agent to know it should prefer the safer specialized browser sibling tools unless it truly needs arbitrary Playwright code.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_select_optionBDestructive
Select an option in a dropdown
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| values | Yes | Array of values to select in the dropdown. This can be a single value or multiple values. | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive=true, so the description does not contradict that. But the description adds no further behavioral detail (e.g., side effects on the page). With annotations present, the bar is lower, and the description is neutral.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no redundant words. It is well-structured and to the point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the schema covers all parameters. The description is short but sufficient for a basic understanding. It does not specify whether values are labels or values, but that is a minor omission given the context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear parameter descriptions for target and values. The tool description itself does not explain parameters beyond what the schema already provides, so it adds no extra semantic value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (select) and the target (option in a dropdown), distinguishing it from more general actions like click or type. However, it does not explicitly contrast with sibling tools, so it misses a bit of distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention when selecting is appropriate or when other actions (e.g., click, type) might be preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_snapshotARead-only
Capture accessibility snapshot of the current page, this is better than screenshot
| Name | Required | Description | Default |
|---|---|---|---|
| boxes | No | Include each element's bounding box as [box=x,y,width,height] in the snapshot. Coordinates are viewport-relative, in CSS pixels (Element.getBoundingClientRect) | |
| depth | No | Limit the depth of the snapshot tree | |
| target | No | Exact target element reference from the page snapshot, or a unique element selector | |
| filename | No | Save snapshot to a file instead of returning it in the response. Relative file names are resolved against the workspace root. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds that the result is an accessibility snapshot rather than a visual screenshot, which is useful behavioral context, but it does not describe the output structure or any other side effects. With annotations present, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence that front-loads the action and object. The comparative note about screenshots earns its place by helping tool selection without adding bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, read-only, and all parameters are documented in the schema. The description covers the core behavior and differentiates from screenshots, though it could be slightly more explicit about what the returned accessibility snapshot contains given there is no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all four parameters clearly documented in the input schema. The description itself adds no parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Capture') and resource ('accessibility snapshot of the current page'), making the tool's function immediately clear. It also distinguishes itself from the screenshot alternative, which is directly relevant to sibling browser_take_screenshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'this is better than screenshot' provides a clear comparison and implicit routing away from browser_take_screenshot. However, it does not explicitly state when not to use this tool or list other alternatives, so the guidance is context rather than a full routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_tabsCDestructive
Manage tabs; request a handoff.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | new: URL. | |
| index | No | Tab index (close defaults to current). | |
| action | Yes | ||
| reason | No | request: reason shown to user. | |
| tab_id | No | request: ID instead of index. | |
| confirm_token | No | request: approval token. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=true. The description adds little beyond that: it does not explain what gets destroyed on close, what a "handoff" or approval token entails, or what authorization/preconditions apply to tab selection.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loads the resource, but "request a handoff" is cryptic and does not earn its place without further explanation. This is under-specification rather than effective conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-action, destructive, open-world tab-management tool with six parameters and no output schema, the description is far too thin. It leaves the request/handoff flow, approval token, and action-specific behavior to inference from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 83%, so the baseline is 3. The description adds no parameter-level meaning beyond the schema; "request a handoff" only vaguely gestures at the request action and confirm_token/reason fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Manage tabs" gives a generic verb and the resource, but the actual operations (list/new/close/select/request) are only discoverable from the action enum in the schema. "Request a handoff" is unexplained, and there is no differentiation from siblings such as browser_navigate, browser_close, or browser_resume.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no explicit when-to-use guidance, no exclusions, and no alternatives. At best, "request a handoff" hints at a request action scenario, but an agent cannot tell when this tool should be selected over browser_navigate or browser_close.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_take_screenshotARead-only
Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Image format for the screenshot. If unset, inferred from the filename extension, otherwise png. | |
| scale | Yes | Image resolution scale. "css" produces a screenshot sized in CSS pixels (smaller, consistent across devices). "device" produces a high-resolution screenshot using device pixels (larger, accounts for the device pixel ratio). Default is css. | css |
| target | No | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element | |
| filename | No | File name to save the screenshot to. Relative file names are resolved against the workspace root. If not specified, the screenshot is saved into the output directory as `page-{timestamp}.{png|jpeg|webp}`. | |
| fullPage | No | When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false), so the bar is lower. The description adds one meaningful behavioral trait beyond annotations: the screenshot is a passive artifact that cannot drive actions. However, it leaves file-saving/output behavior to the schema's filename parameter rather than disclosing it in prose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, each earning its place: the first states the operation, the second carries the critical usage caveat and sibling routing. No filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with a 100%-coverage schema and safety annotations, the definition is nearly complete: purpose, key caveat, and alternative routing are all present. A somewhat richer description could orient agents toward element/fullPage screenshot capabilities, though the schema already documents these.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with detailed documentation for all six parameters including enum semantics (type, scale), defaults, and interaction constraints (fullPage cannot be used with element screenshots). The description adds nothing beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Take a screenshot of the current page') and distinguishes itself from a sibling by noting 'use browser_snapshot for actions.' The action and scope are unambiguous, and the read-only intent matches the title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when NOT to use this tool ('You can't perform actions based on the screenshot') and names the exact alternative ('use browser_snapshot for actions'). This is direct when/when-not routing with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_typeBDestructive
Type text into editable element
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to type into the element | |
| slowly | No | Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once. | |
| submit | No | Whether to submit entered text (press Enter after) | |
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation destructiveHint=true and readOnlyHint=false already signal that this tool can modify state, so the description does not contradict that. However, the main description adds no additional behavioral context beyond the annotations, such as whether typing overwrites existing content or triggers page events. The parameter descriptions do mention key-handler triggering and Enter submission, but the main description itself stays shallow.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no filler or repetition. It front-loads the verb and object, making the tool's primary purpose immediately obvious.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with several closely related siblings (fill_form, press_key, click), the description is too thin to fully orient an agent. It lacks any mention of when typing is appropriate, how the target is resolved, or what side effects to expect, so the agent must rely on parameter descriptions and external context to make a confident choice.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 because the input schema already documents all five parameters. The main description, 'Type text into editable element,' adds no meaning beyond the schema's parameter descriptions, which already define text, slowly, submit, target, and element clearly enough.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('Type text') and a clear target ('editable element'), which distinguishes it from many sibling tools at a high level. It is slightly vague about whether 'editable element' includes textareas, contenteditable regions, or only input fields, but the core purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to prefer this tool over sibling tools such as browser_fill_form or browser_press_key. It does not mention exclusions, prerequisites, or scenarios where typing would be inappropriate, leaving the agent to infer usage from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_wait_forBRead-only
Wait for text to appear or disappear or a specified time to pass
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | The text to wait for | |
| time | No | The time to wait in seconds, at most 30 | |
| textGone | No | The text to wait for to disappear |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The word "Wait" adds the blocking semantics that annotations do not convey, which is genuine value. However, the description says nothing about timeout failure behavior, whether the wait polls or blocks, or whether the three conditions may be combined.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the verb and covering all three modes without padding. It is efficient, though arguably too terse given the unresolved questions about parameter exclusivity and timeout behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter, zero-required tool with no output schema, the description is minimally viable. The notable gap is that it never states that at least one of text/textGone/time should be supplied, leaving open the possibility of a call with no arguments and no defined behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented in the schema with their own descriptions. The description maps each clause to a parameter (appear = text, disappear = textGone, time = time), which is mildly helpful but adds no format, range, or interaction detail beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description pairs a specific verb ("Wait for") with three concrete conditions: text appearing, text disappearing, or elapsed time. That is enough for an agent to know what the tool does without opening the schema. It does not differentiate itself from any sibling, but no sibling performs a waiting/blocking role, so the risk of confusion is low.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus other tools, no mention that it is typically used to synchronize after clicks/navigation, and no statement about what happens on timeout (error vs. silent return). The agent is left to infer all of this from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.7.2- Added
browser_ask_user - Added
browser_resume - Changed
browser_tabs7 fields changed- removed
Input schema / properties / action / descriptionRemoved value: -"Operation to perform" - changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "new", - "close", - "select" -]New value: +[ + "list", + "new", + "close", + "select", + "request" +] - added
Input schema / properties / confirm_tokenAdded value: +{ + "description": "request: approval token.", + "type": "string" +} - changed
Input schema / properties / index / descriptionPrevious value: -"Tab index, used for close/select. If omitted for close, current tab is closed."New value: +"Tab index (close defaults to current)." - added
Input schema / properties / reasonAdded value: +{ + "description": "request: reason shown to user.", + "type": "string" +} - added
Input schema / properties / tab_idAdded value: +{ + "description": "request: ID instead of index.", + "type": "integer" +} - changed
Input schema / properties / url / descriptionPrevious value: -"URL to navigate to in the new tab, used for new."New value: +"new: URL."
32 tool updates
v0.4.0- Changed
browser_click18 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / buttonAdded value: +{ + "description": "Button to click, defaults to left", + "enum": [ + "left", + "right", + "middle" + ], + "type": "string" +} - removed
Input schema / properties / confirm_tokenRemoved value: -{ - "description": "From a confirmation_required error, after the user approved this action.", - "type": "string" -} - added
Input schema / properties / doubleClickAdded value: +{ + "description": "Whether to perform a double click instead of a single click", + "type": "boolean" +} - changed
Input schema / properties / element / descriptionPrevious value: -"Audit-only description of the target."New value: +"Human-readable element description used to obtain permission to interact with the element" - removed
Input schema / properties / expectRemoved value: -{ - "additionalProperties": true, - "description": "Outcome to verify after dispatch, exactly one of {\"url\": regex}, {\"url_changed\": true}, {\"new_tab\": true}, {\"selector\": css} (visible; add \"gone\": true, \"value\": str or \"value_changed\": true), {\"text\": str} or {\"text_gone\": str}, plus \"timeout\" ms (default 5000). Unmet: ok=false, code=\"outcome_not_observed\"; the action already ran, so do not blindly repeat it.", - "type": "object" -} - removed
Input schema / properties / firstRemoved value: -{ - "default": false, - "description": "A write tool's selector matching several elements fails with ambiguous_target unless true; true acts on the first match.", - "type": "boolean" -} - added
Input schema / properties / modifiersAdded value: +{ + "description": "Modifier keys to press", + "items": { + "enum": [ + "Alt", + "Control", + "ControlOrMeta", + "Meta", + "Shift" + ], + "type": "string" + }, + "type": "array" +} - removed
Input schema / properties / refRemoved value: -{ - "description": "Prefer a ref from browser_snapshot over a selector.", - "type": "string" -} - removed
Input schema / properties / selectorRemoved value: -{ - "description": "e.g. \"#submit\", \".btn-primary\".", - "type": "string" -} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "Default: active tab.", - "type": "integer" -} - added
Input schema / properties / targetAdded value: +{ + "description": "Exact target element reference from the page snapshot, or a unique element selector", + "type": "string" +} - removed
Input schema / properties / timeoutRemoved value: -{ - "default": 10000, - "type": "integer" -} - removed
Input schema / properties / waitRemoved value: -{ - "default": false, - "description": "Wait up to timeout ms for the selector/ref target to exist first (click, double_click, hover, drag: also rendered); on timeout nothing ran (not_found, not_actionable).", - "type": "boolean" -} - removed
Input schema / properties / xRemoved value: -{ - "default": 0, - "description": "X coordinate, used without selector/ref.", - "type": "integer" -} - removed
Input schema / properties / yRemoved value: -{ - "default": 0, - "description": "Y coordinate, used without selector/ref.", - "type": "integer" -} - added
Input schema / requiredAdded value: +[ + "target" +]
- Added
browser_close - Added
browser_console_messages - Removed
browser_dom - Added
browser_drag - Added
browser_drop - Added
browser_emulate_media - Added
browser_evaluate - Added
browser_file_upload - Added
browser_fill_form - Changed
browser_find8 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / filenameAdded value: +{ + "description": "Save results to a file instead of returning them in the response. Relative file names are resolved against the workspace root.", + "type": "string" +} - removed
Input schema / properties / queryRemoved value: -{ - "description": "e.g. \"login button\", \"search bar\", \"email input\".", - "type": "string" -} - added
Input schema / properties / regexAdded value: +{ + "description": "Regular expression to search for in the page snapshot. Matching is case-sensitive by default; wrap the pattern in slashes to add flags, e.g. \"/error/i\" for case-insensitive. Provide either text or regex, not both.", + "type": "string" +} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "Default: active tab.", - "type": "integer" -} - added
Input schema / properties / textAdded value: +{ + "description": "Plain text to search for in the page snapshot (case-insensitive substring match). Provide either text or regex, not both.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "query" -]
- Removed
browser_form_fill - Removed
browser_forms - Added
browser_handle_dialog - Added
browser_hover - Changed
browser_navigate7 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / confirm_tokenRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / expectRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - removed
Input schema / properties / rawRemoved value: -{ - "default": false, - "description": "Open a bare image URL (.jpg/.png/...) raw, not in the scriptable local viewer page (image = #zlimg).", - "type": "boolean" -} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "Default: active tab.", - "type": "integer" -} - changed
Input schema / properties / url / descriptionPrevious value: -"e.g. \"https://example.com\"."New value: +"The URL to navigate to"
- Added
browser_navigate_back - Added
browser_network_request - Added
browser_network_requests - Removed
browser_page_info - Removed
browser_page_text - Added
browser_press_key - Added
browser_resize - Added
browser_run_code_unsafe - Removed
browser_screenshot - Changed
browser_select_option16 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / by_textRemoved value: -{ - "default": false, - "type": "boolean" -} - removed
Input schema / properties / confirm_tokenRemoved value: -{ - "type": "string" -} - added
Input schema / properties / element / descriptionAdded value: +"Human-readable element description used to obtain permission to interact with the element" - removed
Input schema / properties / expectRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - removed
Input schema / properties / firstRemoved value: -{ - "default": false, - "type": "boolean" -} - removed
Input schema / properties / refRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / selectorRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "Default: active tab.", - "type": "integer" -} - added
Input schema / properties / targetAdded value: +{ + "description": "Exact target element reference from the page snapshot, or a unique element selector", + "type": "string" +} - removed
Input schema / properties / timeoutRemoved value: -{ - "default": 10000, - "type": "integer" -} - removed
Input schema / properties / valueRemoved value: -{ - "type": "string" -} - added
Input schema / properties / valuesAdded value: +{ + "description": "Array of values to select in the dropdown. This can be a single value or multiple values.", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Input schema / properties / waitRemoved value: -{ - "default": false, - "type": "boolean" -} - added
Input schema / requiredAdded value: +[ + "target", + "values" +]
- Changed
browser_snapshot11 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / boxesAdded value: +{ + "description": "Include each element's bounding box as [box=x,y,width,height] in the snapshot. Coordinates are viewport-relative, in CSS pixels (Element.getBoundingClientRect)", + "type": "boolean" +} - added
Input schema / properties / depthAdded value: +{ + "description": "Limit the depth of the snapshot tree", + "type": "number" +} - added
Input schema / properties / filenameAdded value: +{ + "description": "Save snapshot to a file instead of returning it in the response. Relative file names are resolved against the workspace root.", + "type": "string" +} - removed
Input schema / properties / max_depthRemoved value: -{ - "description": "Depth (>= 0) below the subtree root (body by default); 0 is the root only, omitted all.", - "type": "integer" -} - removed
Input schema / properties / refRemoved value: -{ - "description": "Subtree root ref, resolved before refs are replaced; wins over selector.", - "type": "string" -} - removed
Input schema / properties / selectorRemoved value: -{ - "description": "CSS subtree root (included).", - "type": "string" -} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "Default: active tab.", - "type": "integer" -} - added
Input schema / properties / targetAdded value: +{ + "description": "Exact target element reference from the page snapshot, or a unique element selector", + "type": "string" +} - removed
Input schema / properties / textRemoved value: -{ - "default": false, - "description": "Visible text lines (no refs), url, title and tabId, capped at 12,000 chars with a truncation marker.", - "type": "boolean" -}
- Removed
browser_status - Changed
browser_tabs15 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / action / defaultRemoved value: -"list" - added
Input schema / properties / action / descriptionAdded value: +"Operation to perform" - removed
Input schema / properties / confirm_tokenRemoved value: -{ - "description": "new/close; see browser_click.", - "type": "string" -} - removed
Input schema / properties / forceRemoved value: -{ - "default": false, - "description": "close: disarm beforeunload.", - "type": "boolean" -} - removed
Input schema / properties / include_activeRemoved value: -{ - "default": false, - "description": "list: add active_page, the active tab's browser_snapshot(text=True).", - "type": "boolean" -} - added
Input schema / properties / indexAdded value: +{ + "description": "Tab index, used for close/select. If omitted for close, current tab is closed.", + "type": "number" +} - removed
Input schema / properties / rawRemoved value: -{ - "default": false, - "description": "new: bypass the image viewer.", - "type": "boolean" -} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "close/select (required).", - "type": "integer" -} - removed
Input schema / properties / timeoutRemoved value: -{ - "default": 15000, - "type": "integer" -} - changed
Input schema / properties / url / descriptionPrevious value: -"new (default about:blank)."New value: +"URL to navigate to in the new tab, used for new." - removed
Input schema / properties / waitRemoved value: -{ - "default": false, - "description": "new: wait up to timeout ms for the load; returns tabId, final url and status, or on timeout ok=false, timedOut=true with the tab open.", - "type": "boolean" -} - removed
Input schema / properties / window_fieldsRemoved value: -{ - "default": false, - "type": "boolean" -} - added
Input schema / requiredAdded value: +[ + "action" +]
- Added
browser_take_screenshot - Changed
browser_type18 fields changed- added
Input schema / $schemaAdded value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / clearRemoved value: -{ - "default": false, - "type": "boolean" -} - removed
Input schema / properties / confirm_tokenRemoved value: -{ - "type": "string" -} - added
Input schema / properties / element / descriptionAdded value: +"Human-readable element description used to obtain permission to interact with the element" - removed
Input schema / properties / expectRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - removed
Input schema / properties / firstRemoved value: -{ - "default": false, - "type": "boolean" -} - removed
Input schema / properties / modeRemoved value: -{ - "default": "type", - "description": "type: typing events, clearing first if clear. fill: replace the value via native setters and input/change events. editable: insert plain text into an editor/input/textarea, appending unless clear. HTML: browser_js.", - "enum": [ - "type", - "fill", - "editable" - ], - "type": "string" -} - removed
Input schema / properties / refRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / selectorRemoved value: -{ - "type": "string" -} - added
Input schema / properties / slowlyAdded value: +{ + "description": "Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.", + "type": "boolean" +} - added
Input schema / properties / submitAdded value: +{ + "description": "Whether to submit entered text (press Enter after)", + "type": "boolean" +} - removed
Input schema / properties / tab_idRemoved value: -{ - "description": "Default: active tab.", - "type": "integer" -} - added
Input schema / properties / targetAdded value: +{ + "description": "Exact target element reference from the page snapshot, or a unique element selector", + "type": "string" +} - added
Input schema / properties / text / descriptionAdded value: +"Text to type into the element" - removed
Input schema / properties / timeoutRemoved value: -{ - "default": 10000, - "type": "integer" -} - removed
Input schema / properties / waitRemoved value: -{ - "default": false, - "type": "boolean" -} - added
Input schema / requiredAdded value: +[ + "target", + "text" +]
- Added
browser_wait_for
30 tool updates
v0.3.0- Removed
browser_back - Removed
browser_check - Changed
browser_click28 fields changed- added
Input schema / properties / confirm_tokenAdded value: +{ + "description": "From a confirmation_required error, after the user approved this action.", + "type": "string" +} - removed
Input schema / properties / element / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / element / defaultRemoved value: -null - added
Input schema / properties / element / descriptionAdded value: +"Audit-only description of the target." - removed
Input schema / properties / element / titleRemoved value: -"Element" - added
Input schema / properties / element / typeAdded value: +"string" - added
Input schema / properties / expectAdded value: +{ + "additionalProperties": true, + "description": "Outcome to verify after dispatch, exactly one of {\"url\": regex}, {\"url_changed\": true}, {\"new_tab\": true}, {\"selector\": css} (visible; add \"gone\": true, \"value\": str or \"value_changed\": true), {\"text\": str} or {\"text_gone\": str}, plus \"timeout\" ms (default 5000). Unmet: ok=false, code=\"outcome_not_observed\"; the action already ran, so do not blindly repeat it.", + "type": "object" +} - added
Input schema / properties / firstAdded value: +{ + "default": false, + "description": "A write tool's selector matching several elements fails with ambiguous_target unless true; true acts on the first match.", + "type": "boolean" +} - removed
Input schema / properties / ref / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / ref / defaultRemoved value: -null - added
Input schema / properties / ref / descriptionAdded value: +"Prefer a ref from browser_snapshot over a selector." - removed
Input schema / properties / ref / titleRemoved value: -"Ref" - added
Input schema / properties / ref / typeAdded value: +"string" - removed
Input schema / properties / selector / defaultRemoved value: -"" - added
Input schema / properties / selector / descriptionAdded value: +"e.g. \"#submit\", \".btn-primary\"." - removed
Input schema / properties / selector / titleRemoved value: -"Selector" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - added
Input schema / properties / timeoutAdded value: +{ + "default": 10000, + "type": "integer" +} - added
Input schema / properties / waitAdded value: +{ + "default": false, + "description": "Wait up to timeout ms for the selector/ref target to exist first (click, double_click, hover, drag: also rendered); on timeout nothing ran (not_found, not_actionable).", + "type": "boolean" +} - added
Input schema / properties / x / descriptionAdded value: +"X coordinate, used without selector/ref." - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / y / descriptionAdded value: +"Y coordinate, used without selector/ref." - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"browser_clickArguments"
- Removed
browser_console_logs - Changed
browser_dom9 fields changed- added
Input schema / properties / max_depthAdded value: +{ + "type": "integer" +} - added
Input schema / properties / refAdded value: +{ + "type": "string" +} - added
Input schema / properties / selectorAdded value: +{ + "type": "string" +} - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_domArguments"
- Changed
browser_find8 fields changed- added
Input schema / properties / query / descriptionAdded value: +"e.g. \"login button\", \"search bar\", \"email input\"." - removed
Input schema / properties / query / titleRemoved value: -"Query" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_findArguments"
- Changed
browser_form_fill11 fields changed- added
Input schema / properties / confirm_tokenAdded value: +{ + "type": "string" +} - added
Input schema / properties / expectAdded value: +{ + "additionalProperties": true, + "type": "object" +} - added
Input schema / properties / fields / descriptionAdded value: +"e.g. {\"email\": \"foo@bar\", \"Password\": \"...\", \"#submit-target\": true}" - removed
Input schema / properties / fields / titleRemoved value: -"Fields" - added
Input schema / properties / firstAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_form_fillArguments"
- Changed
browser_forms6 fields changed- removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_formsArguments"
- Removed
browser_forward - Removed
browser_handle_dialog - Removed
browser_hover - Removed
browser_js - Removed
browser_keypress - Removed
browser_markdown - Changed
browser_navigate12 fields changed- added
Input schema / properties / confirm_tokenAdded value: +{ + "type": "string" +} - added
Input schema / properties / expectAdded value: +{ + "additionalProperties": true, + "type": "object" +} - added
Input schema / properties / raw / descriptionAdded value: +"Open a bare image URL (.jpg/.png/...) raw, not in the scriptable local viewer page (image = #zlimg)." - removed
Input schema / properties / raw / titleRemoved value: -"Raw" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - added
Input schema / properties / url / descriptionAdded value: +"e.g. \"https://example.com\"." - removed
Input schema / properties / url / titleRemoved value: -"Url" - removed
Input schema / titleRemoved value: -"browser_navigateArguments"
- Changed
browser_page_info6 fields changed- removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_page_infoArguments"
- Changed
browser_page_text6 fields changed- removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab; others are read without focusing." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_page_textArguments"
- Changed
browser_screenshot24 fields changed- removed
Input schema / properties / data_url / titleRemoved value: -"Data Url" - removed
Input schema / properties / element / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / element / defaultRemoved value: -null - removed
Input schema / properties / element / titleRemoved value: -"Element" - added
Input schema / properties / element / typeAdded value: +"string" - removed
Input schema / properties / full_page / titleRemoved value: -"Full Page" - removed
Input schema / properties / ref / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / ref / defaultRemoved value: -null - removed
Input schema / properties / ref / titleRemoved value: -"Ref" - added
Input schema / properties / ref / typeAdded value: +"string" - removed
Input schema / properties / save_to / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / save_to / defaultRemoved value: -null - removed
Input schema / properties / save_to / titleRemoved value: -"Save To" - added
Input schema / properties / save_to / typeAdded value: +"string" - removed
Input schema / properties / selector / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / selector / defaultRemoved value: -null - removed
Input schema / properties / selector / titleRemoved value: -"Selector" - added
Input schema / properties / selector / typeAdded value: +"string" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"browser_screenshotArguments"
- Removed
browser_scroll - Changed
browser_select_option24 fields changed- removed
Input schema / properties / by_text / titleRemoved value: -"By Text" - added
Input schema / properties / confirm_tokenAdded value: +{ + "type": "string" +} - removed
Input schema / properties / element / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / element / defaultRemoved value: -null - removed
Input schema / properties / element / titleRemoved value: -"Element" - added
Input schema / properties / element / typeAdded value: +"string" - added
Input schema / properties / expectAdded value: +{ + "additionalProperties": true, + "type": "object" +} - added
Input schema / properties / firstAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / ref / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / ref / defaultRemoved value: -null - removed
Input schema / properties / ref / titleRemoved value: -"Ref" - added
Input schema / properties / ref / typeAdded value: +"string" - removed
Input schema / properties / selector / defaultRemoved value: -"" - removed
Input schema / properties / selector / titleRemoved value: -"Selector" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - added
Input schema / properties / timeoutAdded value: +{ + "default": 10000, + "type": "integer" +} - removed
Input schema / properties / value / defaultRemoved value: -"" - removed
Input schema / properties / value / titleRemoved value: -"Value" - added
Input schema / properties / waitAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / titleRemoved value: -"browser_select_optionArguments"
- Changed
browser_snapshot22 fields changed- removed
Input schema / properties / max_depth / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / max_depth / defaultRemoved value: -null - added
Input schema / properties / max_depth / descriptionAdded value: +"Depth (>= 0) below the subtree root (body by default); 0 is the root only, omitted all." - removed
Input schema / properties / max_depth / titleRemoved value: -"Max Depth" - added
Input schema / properties / max_depth / typeAdded value: +"integer" - removed
Input schema / properties / ref / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / ref / defaultRemoved value: -null - added
Input schema / properties / ref / descriptionAdded value: +"Subtree root ref, resolved before refs are replaced; wins over selector." - removed
Input schema / properties / ref / titleRemoved value: -"Ref" - added
Input schema / properties / ref / typeAdded value: +"string" - removed
Input schema / properties / selector / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / selector / defaultRemoved value: -null - added
Input schema / properties / selector / descriptionAdded value: +"CSS subtree root (included)." - removed
Input schema / properties / selector / titleRemoved value: -"Selector" - added
Input schema / properties / selector / typeAdded value: +"string" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - added
Input schema / properties / textAdded value: +{ + "default": false, + "description": "Visible text lines (no refs), url, title and tabId, capped at 12,000 chars with a truncation marker.", + "type": "boolean" +} - removed
Input schema / titleRemoved value: -"browser_snapshotArguments"
- Changed
browser_status1 field changed- removed
Input schema / titleRemoved value: -"browser_statusArguments"
- Removed
browser_submit_form - Changed
browser_tabs21 fields changed- removed
Input schema / properties / action / titleRemoved value: -"Action" - added
Input schema / properties / confirm_tokenAdded value: +{ + "description": "new/close; see browser_click.", + "type": "string" +} - added
Input schema / properties / force / descriptionAdded value: +"close: disarm beforeunload." - removed
Input schema / properties / force / titleRemoved value: -"Force" - added
Input schema / properties / include_activeAdded value: +{ + "default": false, + "description": "list: add active_page, the active tab's browser_snapshot(text=True).", + "type": "boolean" +} - added
Input schema / properties / raw / descriptionAdded value: +"new: bypass the image viewer." - removed
Input schema / properties / raw / titleRemoved value: -"Raw" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"close/select (required)." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - added
Input schema / properties / timeoutAdded value: +{ + "default": 15000, + "type": "integer" +} - removed
Input schema / properties / url / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / url / defaultRemoved value: -null - added
Input schema / properties / url / descriptionAdded value: +"new (default about:blank)." - removed
Input schema / properties / url / titleRemoved value: -"Url" - added
Input schema / properties / url / typeAdded value: +"string" - added
Input schema / properties / waitAdded value: +{ + "default": false, + "description": "new: wait up to timeout ms for the load; returns tabId, final url and status, or on timeout ok=false, timedOut=true with the tab open.", + "type": "boolean" +} - added
Input schema / properties / window_fieldsAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / titleRemoved value: -"browser_tabsArguments"
- Changed
browser_type26 fields changed- removed
Input schema / properties / clear / titleRemoved value: -"Clear" - added
Input schema / properties / confirm_tokenAdded value: +{ + "type": "string" +} - removed
Input schema / properties / element / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / element / defaultRemoved value: -null - removed
Input schema / properties / element / titleRemoved value: -"Element" - added
Input schema / properties / element / typeAdded value: +"string" - added
Input schema / properties / expectAdded value: +{ + "additionalProperties": true, + "type": "object" +} - added
Input schema / properties / firstAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / properties / mode / descriptionAdded value: +"type: typing events, clearing first if clear. fill: replace the value via native setters and input/change events. editable: insert plain text into an editor/input/textarea, appending unless clear. HTML: browser_js." - removed
Input schema / properties / mode / titleRemoved value: -"Mode" - removed
Input schema / properties / ref / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / ref / defaultRemoved value: -null - removed
Input schema / properties / ref / titleRemoved value: -"Ref" - added
Input schema / properties / ref / typeAdded value: +"string" - removed
Input schema / properties / selector / defaultRemoved value: -"" - removed
Input schema / properties / selector / titleRemoved value: -"Selector" - removed
Input schema / properties / tab_id / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tab_id / defaultRemoved value: -null - added
Input schema / properties / tab_id / descriptionAdded value: +"Default: active tab." - removed
Input schema / properties / tab_id / titleRemoved value: -"Tab Id" - added
Input schema / properties / tab_id / typeAdded value: +"integer" - removed
Input schema / properties / text / defaultRemoved value: -"" - removed
Input schema / properties / text / titleRemoved value: -"Text" - added
Input schema / properties / timeoutAdded value: +{ + "default": 10000, + "type": "integer" +} - added
Input schema / properties / waitAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / titleRemoved value: -"browser_typeArguments"
- Removed
browser_upload_file - Removed
browser_wait_for - Removed
browser_watch_console - Removed
browser_workflow - Removed
browser_workflows
93 tool updates
- Removed
browser_audit - Removed
browser_batch - Removed
browser_blur - Removed
browser_bounds - Removed
browser_broadcast - Removed
browser_cache - Removed
browser_capture_network - Changed
browser_check4 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +} - added
Input schema / properties / selector / defaultAdded value: +"" - removed
Input schema / requiredRemoved value: -[ - "selector" -]
- Removed
browser_clear_browsing_data - Changed
browser_click2 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +}
- Removed
browser_click_and_wait_navigation - Removed
browser_clipboard - Removed
browser_close_tab - Removed
browser_close_window - Removed
browser_computed_style - Removed
browser_cookies - Removed
browser_create_window - Removed
browser_delete_session - Removed
browser_detach_tab - Removed
browser_double_click - Removed
browser_downloads - Removed
browser_drag - Removed
browser_duplicate_tab - Removed
browser_element_screenshot - Removed
browser_explain_selector - Removed
browser_fill - Removed
browser_focus - Removed
browser_focus_window - Removed
browser_full_page_metrics - Removed
browser_full_page_screenshot - Removed
browser_get_policy - Removed
browser_get_zoom - Added
browser_handle_dialog - Removed
browser_health - Removed
browser_highlight - Changed
browser_hover4 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +} - added
Input schema / properties / selector / defaultAdded value: +"" - removed
Input schema / requiredRemoved value: -[ - "selector" -]
- Removed
browser_html - Removed
browser_iframes - Removed
browser_images - Removed
browser_intercept - Removed
browser_keep_alive - Removed
browser_keep_alive_stop - Changed
browser_keypress2 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +}
- Removed
browser_links - Removed
browser_list_sessions - Removed
browser_list_tags - Removed
browser_load_session - Removed
browser_logs - Changed
browser_markdown2 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +}
- Removed
browser_meta - Removed
browser_move_tab - Removed
browser_mute_tab - Removed
browser_new_tab - Removed
browser_page_text_by_tab_id - Removed
browser_parallel - Removed
browser_pin_tab - Removed
browser_pool_acquire - Removed
browser_pool_release - Removed
browser_query - Removed
browser_readability - Removed
browser_reload_extension - Removed
browser_reload_tab - Removed
browser_resolve_tag - Removed
browser_retry - Removed
browser_save_session - Removed
browser_scheduler - Changed
browser_screenshot7 fields changed- added
Input schema / properties / data_urlAdded value: +{ + "default": false, + "title": "Data Url", + "type": "boolean" +} - added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / full_pageAdded value: +{ + "default": false, + "title": "Full Page", + "type": "boolean" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +} - added
Input schema / properties / save_toAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Save To" +} - added
Input schema / properties / selectorAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Selector" +} - added
Input schema / properties / tab_idAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Tab Id" +}
- Changed
browser_scroll3 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +} - added
Input schema / properties / selectorAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Selector" +}
- Changed
browser_select_option5 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +} - added
Input schema / properties / selector / defaultAdded value: +"" - added
Input schema / properties / value / defaultAdded value: +"" - removed
Input schema / requiredRemoved value: -[ - "selector", - "value" -]
- Removed
browser_set_editable_content - Removed
browser_set_policy - Removed
browser_set_zoom - Added
browser_snapshot - Removed
browser_storage - Removed
browser_structured_data - Changed
browser_submit_form2 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +}
- Removed
browser_switch_tab - Removed
browser_sync_barrier - Removed
browser_tab_pool - Changed
browser_tabs5 fields changed- added
Input schema / properties / actionAdded value: +{ + "default": "list", + "enum": [ + "list", + "new", + "close", + "select" + ], + "title": "Action", + "type": "string" +} - added
Input schema / properties / forceAdded value: +{ + "default": false, + "title": "Force", + "type": "boolean" +} - added
Input schema / properties / rawAdded value: +{ + "default": false, + "title": "Raw", + "type": "boolean" +} - added
Input schema / properties / tab_idAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Tab Id" +} - added
Input schema / properties / urlAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" +}
- Removed
browser_tag_tab - Removed
browser_trusted_click - Changed
browser_type6 fields changed- added
Input schema / properties / elementAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Element" +} - added
Input schema / properties / modeAdded value: +{ + "default": "type", + "enum": [ + "type", + "fill", + "editable" + ], + "title": "Mode", + "type": "string" +} - added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ref" +} - added
Input schema / properties / selector / defaultAdded value: +"" - added
Input schema / properties / text / defaultAdded value: +"" - removed
Input schema / requiredRemoved value: -[ - "selector", - "text" -]
- Removed
browser_untag_tab - Added
browser_wait_for - Removed
browser_wait_for_element - Removed
browser_wait_for_network_idle - Removed
browser_wait_for_result - Removed
browser_wait_for_title - Removed
browser_wait_for_url - Removed
browser_wake_tab - Removed
browser_windows - Removed
browser_wp_html
106 tool updates
v0.1.0- First observed
browser_audit - First observed
browser_back - First observed
browser_batch - First observed
browser_blur - First observed
browser_bounds - First observed
browser_broadcast - First observed
browser_cache - First observed
browser_capture_network - First observed
browser_check - First observed
browser_clear_browsing_data - First observed
browser_click - First observed
browser_click_and_wait_navigation - First observed
browser_clipboard - First observed
browser_close_tab - First observed
browser_close_window - First observed
browser_computed_style - First observed
browser_console_logs - First observed
browser_cookies - First observed
browser_create_window - First observed
browser_delete_session - First observed
browser_detach_tab - First observed
browser_dom - First observed
browser_double_click - First observed
browser_downloads - First observed
browser_drag - First observed
browser_duplicate_tab - First observed
browser_element_screenshot - First observed
browser_explain_selector - First observed
browser_fill - First observed
browser_find - First observed
browser_focus - First observed
browser_focus_window - First observed
browser_form_fill - First observed
browser_forms - First observed
browser_forward - First observed
browser_full_page_metrics - First observed
browser_full_page_screenshot - First observed
browser_get_policy - First observed
browser_get_zoom - First observed
browser_health - First observed
browser_highlight - First observed
browser_hover - First observed
browser_html - First observed
browser_iframes - First observed
browser_images - First observed
browser_intercept - First observed
browser_js - First observed
browser_keep_alive - First observed
browser_keep_alive_stop - First observed
browser_keypress - First observed
browser_links - First observed
browser_list_sessions - First observed
browser_list_tags - First observed
browser_load_session - First observed
browser_logs - First observed
browser_markdown - First observed
browser_meta - First observed
browser_move_tab - First observed
browser_mute_tab - First observed
browser_navigate - First observed
browser_new_tab - First observed
browser_page_info - First observed
browser_page_text - First observed
browser_page_text_by_tab_id - First observed
browser_parallel - First observed
browser_pin_tab - First observed
browser_pool_acquire - First observed
browser_pool_release - First observed
browser_query - First observed
browser_readability - First observed
browser_reload_extension - First observed
browser_reload_tab - First observed
browser_resolve_tag - First observed
browser_retry - First observed
browser_save_session - First observed
browser_scheduler - First observed
browser_screenshot - First observed
browser_scroll - First observed
browser_select_option - First observed
browser_set_editable_content - First observed
browser_set_policy - First observed
browser_set_zoom - First observed
browser_status - First observed
browser_storage - First observed
browser_structured_data - First observed
browser_submit_form - First observed
browser_switch_tab - First observed
browser_sync_barrier - First observed
browser_tab_pool - First observed
browser_tabs - First observed
browser_tag_tab - First observed
browser_trusted_click - First observed
browser_type - First observed
browser_untag_tab - First observed
browser_upload_file - First observed
browser_wait_for_element - First observed
browser_wait_for_network_idle - First observed
browser_wait_for_result - First observed
browser_wait_for_title - First observed
browser_wait_for_url - First observed
browser_wake_tab - First observed
browser_watch_console - First observed
browser_windows - First observed
browser_workflow - First observed
browser_workflows - First observed
browser_wp_html
TDQS
Scored across 27 tools
Most tools map cleanly to one browser action (click, hover, press_key, select_option, navigate, tabs), and the network_requests/network_request pair is explicitly documented as a two-step lookup. A few pairs have fuzzy boundaries: browser_type vs browser_fill_form, browser_drag vs browser_drop, and especially browser_evaluate vs browser_run_code_unsafe, where an agent must read carefully to pick the right one.
Every tool uses the same browser_ prefix and snake_case, which makes the set very predictable. The only minor deviation is that some names are verb-first (browser_click, browser_navigate_back) while others are noun/verb-phrase (browser_tabs, browser_snapshot, browser_network_requests, browser_console_messages).
At 27 tools this is on the heavy side and includes specialized operations (browser_emulate_media, browser_resize, browser_drop, browser_drag, browser_run_code_unsafe) that many agents will never need. For a full browser-automation surface the breadth is defensible, but the count is borderline rather than well-scoped.
Coverage is strong: navigation, tabs, forms, keyboard, dialogs, waits, snapshots, screenshots, console, network inspection, file upload, and drag/drop are all present. Gaps are minor but real: no forward-history navigation, no cookie/localStorage management, and no download handling.
Maintenance
Related MCP Connectors
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Let AI agents use your real, signed-in Chrome: tabs, clicks, forms, screenshots and video.
Cloud browsers for AI agents: saved logins, residential IPs, live human takeover, 57 browser tools.
Let your AI agent operate any website through a real, logged-in browser session.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables AI agents to drive a user-launched Firefox instance via its native Marionette protocol, providing precise DOM actuation like clicking, typing, uploading files, taking screenshots, and evaluating JavaScript.1820 npm1GPL 2.0
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to control existing Chrome and Firefox browser sessions locally, including tab management, navigation, form filling, screenshots, and persistent scripts, without remote relays or debugging ports.23 npm-
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to operate a real, logged-in Firefox session through an extension, including tab and history management, page reading, screenshots, and clicking, typing, or scrolling on domains the user approves.23 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables coding agents to control the user's real Chrome or Firefox tabs, with their existing logins, to read pages, click, type, fill forms, take screenshots, inspect network traffic and run JavaScript. It works through a paired browser extension over a local WebSocket connection, so automation happens in the browser the user is actually looking at, including shadow DOM, cross-origin iframes, dialogs and single-page apps.MIT