Skip to main content
Glama
xav-ie

Browser Session MCP

browser-session-mcp

CI Release License: MIT xav-ie/browser-session-mcp MCP server

Give every AI agent its own real Chrome, one that keeps its logins, records what the page did, and gets past bot checks. browser-session-mcp is an MCP server that hands each agent an isolated, long-lived browser session. When a site needs a password or passkey, the agent sends you a link, you log in on a live view of the page, and the agent carries on without ever seeing your credentials.

  • A browser per agent. Each session has its own cookies, storage and tabs. Run many agents side by side on one Chrome without them seeing each other.

  • Sessions that stick around. A session is just an id the agent passes to each tool, so it survives dropped connections and server restarts.

  • Hand logins to a human. For passwords, passkeys and 2FA, the agent sends you a link to a live view of the page. You log in, click Done, and the agent continues. Your credentials never reach it.

  • Log in once. Save a session's cookies under a name and load them into any future session.

  • Everything recorded. Every console message and network request is kept on disk, grouped by page visit, for the agent to read back while debugging.

  • Gets past bot checks. No Runtime.enable tell, a consistent User-Agent and Client Hints, no injected scripts, and real mouse and keyboard input. Stealth can be switched on and off per session.

  • 30 tools for tabs, navigation, clicks and typing, screenshots, accessibility snapshots, logs and CPU profiles.

Quick start

You need a Chrome with its DevTools port open (this server drives one, it doesn't bundle one) and an MCP client such as Claude Code.

1. Start Chrome. Any Chrome or Chromium works. No Chrome around? Get a small headless one with npx @puppeteer/browsers install chrome-headless-shell.

chrome-headless-shell --remote-debugging-port=9222 &
curl -s http://localhost:9222/json/version   # prints JSON when it's ready

2. Add the server to your MCP client. STATE_DIR is where it keeps sessions, logs and saved logins. With Nix, there's nothing to install:

claude mcp add browser-session -e BROWSER_URL=http://localhost:9222 \
  -e STATE_DIR="$HOME/.local/state/browser-session-mcp" \
  -- nix run github:xav-ie/browser-session-mcp -- mcp
brew install xav-ie/tap/browser-session-mcp

claude mcp add browser-session -e BROWSER_URL=http://localhost:9222 \
  -e STATE_DIR="$HOME/.local/state/browser-session-mcp" \
  -- browser-session mcp

Each release has a tarball per platform with the browser-session binary, the takeover page and systemd units. The Linux binaries are static and run on any distribution; the macOS one runs on Apple silicon with macOS 14 or newer.

ver=$(curl -fsSL https://api.github.com/repos/xav-ie/browser-session-mcp/releases/latest | sed -n 's/.*"tag_name": "\(.*\)".*/\1/p')
case "$(uname -sm)" in
  "Linux x86_64")  target=x86_64-unknown-linux-musl ;;
  "Linux aarch64") target=aarch64-unknown-linux-musl ;;
  "Darwin arm64")  target=aarch64-apple-darwin ;;
esac
base=https://github.com/xav-ie/browser-session-mcp/releases/download/$ver
curl -fsSLO "$base/browser-session-$ver-$target.tar.gz"
# check it (on macOS, use shasum -a 256 -c instead of sha256sum -c)
curl -fsSL "$base/SHA256SUMS" | grep "browser-session-$ver-$target.tar.gz" | sha256sum -c -
tar -xzf "browser-session-$ver-$target.tar.gz"

claude mcp add browser-session -e BROWSER_URL=http://localhost:9222 \
  -e STATE_DIR="$HOME/.local/state/browser-session-mcp" \
  -- "$PWD/browser-session-$ver-$target/browser-session" mcp

3. Ask your agent to use it.

Open a browser session, go to example.com, and take a screenshot.

The agent calls open_browser_session, gets back a sessionId, and passes it to every tool after that:

const { sessionId } = (await tools.browser_session_mcp.open_browser_session({})).structuredContent;
await tools.browser_session_mcp.navigate({ sessionId, url: "https://example.com" });
await tools.browser_session_mcp.take_screenshot({ sessionId });

That's all you need to start. The mcp role works on its own. Run the listener too if you want console and network logs, the reaper to clean up idle sessions, and takeover for human logins; Deployment shows how.

TIP

On Claude Code, install thebrowser-session plugin for a browser-session-navigator agent that already knows how to drive these tools.

Related MCP server: Umbra

Handing a login to a person

When a page needs credentials the agent must not see, it asks for a takeover link and shows it to you. The page opens a live view of the agent's tab; you log in there, click Done, and the agent picks up where it left off.

The takeover page: a bar with back, forward, the page's URL, new tab, a button to fill a username or password, and Done, above a live view of the agent's tab showing GitHub's sign-in form

The link works for one browser only: the first to open it claims it, and it expires after 30 minutes by default. Workflows has the details and the code.

All 30 tools

Most tools take a sessionId first. Tools marked ⚙ need one of the optional background roles from Deployment. Tools that return JSON declare its shape as an MCP outputSchema, so clients can type their results.

Group

Tools

Sessions

open_browser_session, close_browser_session, list_browser_sessions

Tabs

new_page, list_pages, switch_tab, close_tab

Navigation

navigate

Seeing the page

take_screenshot, take_snapshot (the accessibility tree as text)

Acting on it

click, type, press_key, scroll, move_mouse, wait_for, evaluate

Logs ⚙

list_visits, list_console_messages, list_network_requests

Profiling

start_profiling, stop_profiling

Stealth

set_stealth, get_stealth

Human takeover ⚙

request_human_takeover, await_human_takeover

Saved logins

save_browser_state, load_browser_state, list_browser_states, delete_browser_state

Sessions

  • open_browser_session({ viewport?, useMobileUA? }) → { sessionId, pageCount, activeUrl }

  • close_browser_session({ sessionId }): safe to call twice

  • list_browser_sessions()

Tabs

  • new_page({ sessionId, url? }): opens a tab; later calls act on it

  • list_pages({ sessionId }): in a stable order, the active tab marked *

  • switch_tab({ sessionId, tabIndex }): makes a tab active and brings it to the front

  • close_tab({ sessionId, tabIndex })

Navigation

  • navigate({ sessionId, url, timeout? }): returns after the load event

Seeing the page

  • take_screenshot({ sessionId, fullPage? }): a PNG

  • take_snapshot({ sessionId }): the accessibility tree as indented text

Acting on it (real CDP input, not synthetic JavaScript events)

  • click({ sessionId, selector | x,y, timeout? })

  • type({ sessionId, selector, text, delay?, clear?, timeout? })

  • press_key({ sessionId, key, selector?, timeout? }): key is a name (Enter, Tab, ArrowDown…) or a character

  • scroll({ sessionId, deltaY?, deltaX?, x?, y? })

  • move_mouse({ sessionId, x, y })

  • wait_for({ sessionId, selector? | text?, timeout? })

  • evaluate({ sessionId, expression, tabIndex? }): runs JavaScript and returns the value

Logs ⚙ (written by the listener role)

  • list_visits({ sessionId }): one entry per page visit, oldest first

  • list_console_messages({ sessionId, visit?, limit? }): limit defaults to 500

  • list_network_requests({ sessionId, visit?, limit? }): limit defaults to 500

Profiling (find the JavaScript behind a slow or hung page)

  • start_profiling({ sessionId, tabIndex?, samplingIntervalUs? }): starts the V8 CPU profiler

  • stop_profiling({ sessionId, tabIndex?, top?, terminateAfterMs?, timeout? }): saves a .cpuprofile (open it in DevTools or speedscope.app) under $STATE_DIR/logs/<sessionId>/profiles/ and returns long tasks, the hottest functions and time per script. If the page is hung, its script is stopped after terminateAfterMs (default 5000) so the profile can be collected

Stealth

  • set_stealth({ sessionId, enabled })

  • get_stealth({ sessionId }) → { stealth }

Human takeover ⚙ (needs the takeover role and TAKEOVER_BASE_URL)

  • request_human_takeover({ sessionId, ttlMinutes? }) → { url, token, expiresAtMs }: returns right away with a link

  • await_human_takeover({ token, timeout? }) → { completed }: waits until the person clicks Done

Saved logins

  • save_browser_state({ sessionId, name })

  • load_browser_state({ sessionId, name })

  • list_browser_states()

  • delete_browser_state({ name })

Learn more

  • Workflows: handing a login to a person, and saving cookies to reuse.

  • How it works: why a session outlives its connection, the four roles, how stealth works, and what's on disk.

  • Deployment: building from source, the NixOS module, systemd without Nix, and every environment variable.

  • Development: checks, diagrams and releases.

License

MIT

Available Tools

30 tools
await_human_takeoverA

Wait for the human to click Done in the takeover page. completed is true if they finished, false on timeout. STRONGLY ADVISED: run this in a BACKGROUND task and POLL — call it in a loop with a SHORT timeout (e.g. 4000ms) until completed:true — rather than one long blocking call, which can exceed your MCP client's request timeout and make you miss the Done signal. The human may take several minutes; a background poller lets you be notified and resume. On completion the session is authenticated and you can continue; consider save_browser_state so later sessions skip the login. Fails on a token that request_human_takeover didn't issue or that has already completed.

NameRequiredDescriptionDefault
tokenYesThe token returned by request_human_takeover.
timeoutNoMilliseconds to wait before returning completed: false. Default 300000, max 1800000.

Output Schema

NameRequiredDescription
tokenYes
completedYesTrue once the person clicked Done; false on timeout.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by documenting timeout semantics, the risk of exceeding the MCP client's request timeout, the fact that a human may take minutes, the post-completion state (session authenticated, you can continue), and the two failure modes (token not issued by request_human_takeover, or already completed). Annotations only say non-readonly/non-idempotent, which conveys far less.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and return semantics, then the polling advice and follow-ups in a logical order. Slightly dense with capitalized emphasis, but nearly every sentence carries operational information; only the resume/notify clause is mildly redundant with the polling advice.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers what the agent needs to call this correctly: how to poll, what `completed` means, what happens on completion, and what causes failure. An output schema exists, so the description is not obligated to detail return structure and doesn't.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real guidance on `timeout` — use a short value (e.g. 4000ms) and poll, rather than the schema's 300000 default — which changes how an agent should set it. `token` is only referenced by provenance (returned by request_human_takeover), matching the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb+resource: wait for the human to click Done in the takeover page, and defines the success/failure signal (`completed` true/false). It is clearly distinct from siblings like request_human_takeover (which issues the token) and save_browser_state (suggested as a follow-up).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly prescribes patterns: run in a background task and poll in a loop with a short timeout (~4000ms) instead of one long blocking call, and explains why (client request timeout, missing the Done signal). It also notes the follow-on action (save_browser_state) and the failure condition for stale/completed tokens.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

clickA
Destructive

Click in the session's active tab with real CDP mouse input (trusted events — fires handlers reliably and grants user activation, so it can open popups/new tabs that a JS click can't). Pass a CSS selector to click the first match's center, after waiting up to timeout for it and scrolling it into view; or pass both x and y to click viewport coordinates, which are used only when there is no selector. Don't use evaluate to click: synthetic JS clicks can be ignored by pages. Coordinates outside the viewport are not rejected; the click lands on nothing. A click can submit forms or trigger purchases, like a real user's. Returns a confirmation naming what was clicked. Fails if the selector matches nothing within timeout, or if neither a selector nor both coordinates are given.

NameRequiredDescriptionDefault
xNoHorizontal viewport coordinate in CSS pixels, used with `y` when no selector is given.
yNoVertical viewport coordinate in CSS pixels, used with `x` when no selector is given.
timeoutNoMilliseconds to wait for `selector` to appear. Default 5000.
selectorNoCSS selector of the element to click; the first match is used.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructive/openWorld/non-idempotent, but the description adds substantial context: trusted events grant user activation, popups/new tabs may open, clicks can submit forms or trigger purchases, and out-of-viewport coordinates silently land on nothing. It also notes the returned confirmation and failure modes. This is rich beyond the annotations; only return-format detail is thin (no output schema exists).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded, leading with the core action and trusted-event value proposition before usage modes and cautions. A single long paragraph rather than structured bullets, but nearly every sentence carries actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still states that it returns a confirmation naming what was clicked, and it covers failure modes, side effects, and parameter interplay. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all five params are documented, but the description adds real meaning: the selector/coordinate precedence, that timeout waits for the selector and scrolls it into view, and that missing/invalid combinations cause failure. This goes beyond the schema's per-field text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Click in the session's active tab with real CDP mouse input') and immediately distinguishes its behavior from a JS/evaluate click. An agent can tell exactly what this tool does and how it differs from the sibling `evaluate`.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly prescribes the two usage modes (selector vs. x/y coordinates), states the precedence rule ('coordinates are used only when there is no selector'), gives an explicit when-not ('Don't use evaluate to click'), and names the failure conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

close_browser_sessionA
DestructiveIdempotent

Close a browser session for good: closes all its tabs, discards its cookies and storage, and deletes its console and network logs and saved .cpuprofile files. Call it when the task is done so the session doesn't sit open until the reaper closes it. Use close_tab instead to close one tab and keep the session, and save_browser_state first if the login should outlive the session. Idempotent: closing an unknown or already-closed session succeeds, so it is safe in cleanup code. Returns a confirmation.

NameRequiredDescriptionDefault
sessionIdYesThe id returned by open_browser_session. An unknown or already-closed id succeeds without error.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true and idempotentHint=true, but the description adds substantive context about exactly what is destroyed: tabs, cookies, storage, console/network logs, and saved .cpuprofile files. It also explains idempotency in operational terms, saying unknown or already-closed sessions succeed and the tool is safe in cleanup code.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and destruction scope, then moves through usage, alternatives, idempotency, and return behavior. Every sentence carries operational information, and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive cleanup tool with rich annotations and a fully documented single parameter, the description supplies what an agent needs: what is deleted, when to call it, when to use alternatives, idempotency safety, and that it returns a confirmation. No output schema is present, but the description notes the return shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single parameter already documents that sessionId comes from open_browser_session and that unknown or already-closed ids succeed. The description repeats the idempotency detail but does not add meaningful parameter syntax or format guidance 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: close a browser session. It specifies the scope beyond the name by explaining that all tabs, cookies, storage, logs, and .cpuprofile files are destroyed, and it distinguishes this from close_tab.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit timing guidance: call it when the task is done so the session does not remain open for the reaper. It also names alternatives and their conditions: use close_tab to close one tab and keep the session, and save_browser_state first if the login should outlive the session.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

close_tabA
Destructive

Close the tab at tabIndex (from list_pages). The session and its other tabs stay open; if the closed tab was active, the last remaining tab becomes active. Tabs after it shift down one index, so call list_pages again before using another index. Closing the last tab leaves the session open with no tabs; the next navigate opens a new one. To end the whole session, use close_browser_session. Returns a confirmation. Fails if the session has no tab at that index.

NameRequiredDescriptionDefault
tabIndexYesA tab's 0-based index from list_pages. Errors if the session has no tab at that index.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint=true annotation, the description discloses the key behavioral consequences: the session survives, index shifting invalidates other indices, the last-tab edge case, and the failure mode for a bad index. This is exactly the context annotations cannot convey for a destructive mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and its return, and nearly every sentence carries a distinct fact. It is somewhat dense and repeats the 'session stays open' idea in two separate sentences, but no sentence is pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive tool with no output schema, the description covers return value ('Returns a confirmation'), error behavior, side effects, and the sibling alternative. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuinely new semantics: that indices shift after a close and must be re-derived via list_pages. That is meaning the schema does not express, lifting it above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Close the tab at `tabIndex`') and immediately contrasts the scope with `close_browser_session`, so an agent can distinguish the two without reading either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives both a when-to-use-alternative ('To end the whole session, use close_browser_session') and an explicit precondition for reuse ('call list_pages again before using another index'), leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_browser_stateA
DestructiveIdempotent

Delete a saved browser state by name, permanently; open sessions that already loaded it keep their cookies. Use it to forget a login that is stale or no longer wanted; to update a state, call save_browser_state with the same name instead. Use list_browser_states to see the names. Deleting a name that doesn't exist succeeds with removed false, so it is safe to repeat.

NameRequiredDescriptionDefault
nameYesName of the saved state: letters, digits, '.', '_' and '-' only.

Output Schema

NameRequiredDescription
nameYes
removedYesFalse if no state had that name.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations, which only flag destructive=true and idempotent=true. The description adds the non-obvious operational nuance that already-open sessions keep their cookies, and explains the idempotent behavior concretely (missing name returns removed false), which is exactly the context an agent needs before repeating a destructive call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, each carrying distinct information: what it does, why to use it, the alternative, and the repeat-safety caveat. The destructive scope is front-loaded before any advisory content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter destructive tool with full schema coverage, a rich annotation set, and an output schema, nothing material is left out. The description even pre-explains the removed=false return case, which is more than the output schema alone would guarantee an agent notices.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents the allowed character set for `name`, so the description adds little syntax detail. It does supply the semantic pointer that names come from list_browser_states, but that is contextual rather than parameter-level elucidation; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope: "Delete a saved browser state by name, permanently." It actively disambiguates from the closest siblings by name (save_browser_state for updates, list_browser_states for discovery), so an agent can pick it without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States the use case ("forget a login that is stale or no longer wanted"), the explicit alternative for the adjacent intent ("to update a state, call save_browser_state with the same name instead"), and how to find valid inputs (list_browser_states). When-to-use and when-to-use-something-else are both covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

evaluateA
Destructive

Run JavaScript in a tab and return its value as JSON in { result }. A bare expression returns its value; for several statements use return ...; promises are awaited. Values that aren't JSON come back reduced: undefined as null and DOM nodes as {}. It runs in the page's main world (can read page globals like window.dataLayer); on stealth sessions (see set_stealth) it runs in an isolated world instead, which sees the DOM but not page-defined globals. tabIndex runs it in another tab without switching to it. The code can change the page like any script, so prefer take_snapshot or wait_for when they suffice, and click or type for interaction. Fails with the JS exception's message if the code throws.

NameRequiredDescriptionDefault
tabIndexNoTab to run in, by its 0-based list_pages index. Default: the active tab.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.
expressionYesJavaScript to run. Promises are awaited; the value must be JSON-serializable.

Output Schema

NameRequiredDescription
resultYesThe expression's value; null for undefined.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations covering the safety profile, the description adds substantial context beyond them: main-world vs isolated-world execution on stealth sessions, value coercion rules (undefined→null, DOM nodes→{}), promise awaiting, error behavior on thrown exceptions, and the page-mutating nature consistent with destructiveHint=true. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded, moving from core behavior to return semantics, execution-world caveats, alternatives, and failure mode without a wasted sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 3 well-documented parameters, an output schema, and rich annotations, the description still covers the critical agent-facing unknowns: execution world, stealth world isolation, tab targeting, coercion, and error signaling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: it explains that tabIndex runs the code in another tab 'without switching to it' and that the stealth world affects what globals the expression can see, both of which go beyond the schema wording.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Run JavaScript in a tab') and names the exact return shape (JSON in { result }), which lets an agent distinguish it from siblings like take_snapshot, click, or wait_for immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes the agent away from itself when simpler tools suffice: 'prefer take_snapshot or wait_for when they suffice, and click or type for interaction.' That is an explicit when-not-to-use statement with named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_stealthA
Read-only

Return whether stealth is on for a session; it changes nothing. Check it before evaluate or list_console_messages, whose behavior it changes; use set_stealth to change it. A new session starts with stealth off.

NameRequiredDescriptionDefault
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
stealthYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, but the description adds concrete behavioral context beyond them: it changes nothing, it affects the behavior of evaluate and list_console_messages, and a new session starts with stealth off. These are actionable traits not captured by the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short clauses, front-loaded with what the tool does and immediately followed by when to use it and the alternative. Every sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema and read-only annotation, the description supplies everything else an agent needs: the default state, the tools whose behavior it affects, and the mutating counterpart. No gaps remain for a one-parameter read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the sessionId parameter is fully documented, including the error behavior for missing sessions. The description adds no parameter-level detail beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (returns whether stealth is on) and resource (for a session), and explicitly distinguishes it from set_stealth, which mutates the setting. An agent can identify its role without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance (check before evaluate or list_console_messages), names the mutating alternative (set_stealth), and states the default for a new session. No important routing decision is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_browser_sessionsA
Read-only

List every open browser session on the shared Chrome, sorted by sessionId, including ones opened by other agents; it takes no arguments. Use it to recover a lost sessionId or to find sessions left open; don't use it to see the tabs inside one session (list_pages) or saved logins (list_browser_states). activeUrl is null for a session with no tabs. The list is empty if none are open.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
sessionsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real context beyond them: cross-agent visibility, deterministic sort order, null activeUrl for tab-less sessions, and an empty list when nothing is open. It does not mention any cost or limit, but none is evidently needed for a zero-arg read.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and scope, then siblings, then edge cases; every sentence carries information. It is dense, packing sort order, cross-agent scope, null semantics and empty-list behavior into a few clauses, but none of it is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no prose, yet the description still clarifies the one ambiguous field (activeUrl null) and the empty-result case. For a zero-param read-only listing tool, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, which is stated explicitly ('it takes no arguments') and confirmed by an empty schema, so there is no parameter semantics to explain. Baseline for zero parameters applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List every open browser session on the shared Chrome') plus scope details (sorted by sessionId, includes sessions opened by other agents). The sibling distinction is explicit: list_pages for tabs, list_browser_states for saved logins, so an agent can route without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives both positive triggers ('recover a lost sessionId or to find sessions left open') and explicit exclusions naming the two alternative tools and what each is for. Nothing about when to choose this tool is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_browser_statesA
Read-only

List the saved browser states (cookie sets saved by save_browser_state) that load_browser_state and delete_browser_state accept, sorted by name; it takes no arguments and changes nothing. Use it to pick a name to load; these are saved logins on disk, not open sessions, so use list_browser_sessions for those. The list is empty if nothing has been saved.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
statesYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds useful context: the tool takes no arguments, changes nothing, sorts by name, returns an empty list when nothing is saved, and represents saved logins on disk rather than open sessions. This goes beyond the annotations and clarifies behavior that matters for selection.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, then adds disambiguation and edge-case behavior in a compact form. Every sentence contributes useful selection or invocation information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple no-parameter read tool with an output schema and clear annotations, the description is complete. It explains the resource, sibling distinction, usage, sorting, empty-state behavior, and lack of side effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has zero parameters at 100% coverage, so there are no parameter semantics to explain. The description correctly notes that it takes no arguments, which is the only relevant parameter-level detail; the baseline for zero parameters is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: list saved browser states, defined as cookie sets saved by save_browser_state and accepted by load_browser_state/delete_browser_state. It also distinguishes this from list_browser_sessions, so an agent can differentiate it from siblings immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use this tool to pick a name to load, and directs the agent to list_browser_sessions for open sessions. That covers the key when-to-use and when-not-to-use case among the siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_console_messagesA
Read-only

List console messages (console.log, warnings, errors, uncaught exceptions) the session's pages emitted, oldest first, from the most recent limit. Use it to debug page errors; use list_network_requests for failed requests. Pass visit (a seq from list_visits) to see one page load; without it, messages from every visit are merged and limit keeps the newest. It reads logs and changes nothing. Empty unless the listener role is running, nothing is captured while stealth is on, and logs are deleted when the session closes.

NameRequiredDescriptionDefault
limitNoReturn at most this many of the newest messages. Default 500.
visitNoOnly messages from this visit, by its `seq` from list_visits. Default: all visits.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
messagesYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnlyHint annotation by disclosing non-obvious preconditions and lifecycle behavior: results are empty unless the listener role is running, nothing is captured while stealth is on, and logs are deleted when the session closes. The merge/limit interaction ('limit keeps the newest') is also behavior an agent could easily get wrong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then the alternative, then parameter behavior, then preconditions — a sensible ordering. It is dense and the phrase 'oldest first, from the most recent `limit`' takes a beat to parse, but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema handling return values and annotations covering safety, the description fills exactly the remaining gaps: prerequisites (listener role), known blind spot (stealth), data lifecycle (deleted on close), and scoping. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter meaning the schema lacks: without `visit` the messages from every visit are merged and `limit` applies to the newest, and `visit` is sourced from list_visits' `seq`. This is a genuine increment, though it stops short of giving limits or a default reminder.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List console messages') and enumerates exactly which message kinds are included (console.log, warnings, errors, uncaught exceptions). It also explicitly separates itself from list_network_requests, so an agent can distinguish it from the nearest sibling without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit use case ('Use it to debug page errors') and names the alternative with its own condition ('use list_network_requests for failed requests'). It also explains the visit-vs-no-visit choice, so both usage decisions are resolved in the text.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_network_requestsA
Read-only

List the network requests the session's pages made, oldest first, from the most recent limit: method, URL, status (or failure reason), redirects and request body. Use it to check API calls, tracking pixels and failed loads; use list_console_messages for script errors and logs. Pass visit (a seq from list_visits) to see one page load; without it, requests from every visit are merged and limit keeps the newest. A null status means the request hadn't finished when logged. It reads logs and changes nothing. Empty unless the listener role is running, and logs are deleted when the session closes.

NameRequiredDescriptionDefault
limitNoReturn at most this many of the newest requests. Default 500.
visitNoOnly requests from this visit, by its `seq` from list_visits. Default: all visits.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
requestsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, and the description adds context annotations cannot: output is empty unless the listener role is running, logs are deleted when the session closes, and a null status means the request was still in flight. These are operationally decisive facts an agent would otherwise learn only by failing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Information is front-loaded: purpose, then alternatives, then parameter behavior, then caveats. Every sentence carries weight, though the opening clause ('from the most recent `limit`: method, URL...') packs ordering, paging and return fields into one dense phrase that takes a second read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return shape needs no explanation, and the description covers the prerequisites (listener role), lifecycle (logs deleted on session close), and the null-status edge case. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: without `visit`, requests from all visits are merged and `limit` keeps the newest. That interaction between the two optional parameters is not spelled out in the schema. It stops short of describing any format specifics for the visit seq beyond pointing at list_visits.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the network requests the session's pages made') plus ordering ('oldest first') and the fields returned (method, URL, status, redirects, body). It explicitly distinguishes itself from list_console_messages, so an agent can choose without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use cases ('check API calls, tracking pixels and failed loads') and names the alternative for the adjacent concern ('use list_console_messages for script errors and logs'). It also states when to pass `visit` versus omitting it, which is the real routing decision for this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pagesA
Read-only

List the session's tabs in a stable order; it changes nothing. The active tab (the one navigate/evaluate/screenshot/click target by default) is marked with * in the text and active: true in the structured output. Call it before switch_tab, close_tab, or evaluate/profiling with tabIndex, to get a current index; use list_browser_sessions to see sessions rather than tabs, and list_visits for navigation history. Indices stay stable until a tab is closed, after which later tabs shift down one. The list is empty if every tab was closed; the next navigate opens a new one.

NameRequiredDescriptionDefault
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
pagesYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description explains stable ordering, active-tab marking, index stability, index shifting after a tab close, the empty-list state, and that a subsequent navigate opens a new tab. These details materially affect how an agent should interpret and use the returned list.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and is dense with useful operational detail. Every sentence contributes either purpose, usage routing, active-tab semantics, or index behavior, without redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single required parameter, complete schema coverage, existing output schema, and read-only annotations, the description covers the remaining behavioral questions: ordering, active-tab identification, index stability, empty-state behavior, and when to choose this tool over siblings. Nothing essential for correct invocation appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter is sessionId, and the schema already provides a complete description of it, including that it comes from open_browser_session and errors if no open session matches. The description does not add further parameter-level meaning, so the high schema coverage supports a baseline score of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with a specific verb and resource: 'List the session's tabs in a stable order.' It also distinguishes this tool from session listing and visit-history listing by explicitly naming list_browser_sessions and list_visits as different resources.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit call conditions: use it before switch_tab, close_tab, or evaluate/profiling with tabIndex to get a current index. It also names alternatives for different needs, directing agents to list_browser_sessions for sessions and list_visits for navigation history.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_visitsA
Read-only

List the session's page visits, oldest first. Each visit is one top-level navigation in one tab, numbered by seq; pass that number as visit to list_console_messages or list_network_requests to see only that page load's logs. Use it to find which page load to inspect; use list_pages for the tabs open now. It reads logs and changes nothing. Empty unless the listener role is running, and deleted when the session closes.

NameRequiredDescriptionDefault
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
visitsYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so 'reads logs and changes nothing' is largely redundant. The description does add real behavioral context the annotations can't: ordering (oldest first), the lifecycle rule that visits are deleted when the session closes, and the empty-unless-listener-running condition. Missing only details like result caps or retention limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with what the tool lists and its ordering, then routing to related tools, safety, and preconditions. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A read-only listing tool with one fully-described parameter and an output schema. Ordering, the seq/visit contract, empty-state precondition, and lifecycle are all covered; nothing an agent needs to invoke it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With one param fully documented in the schema, the 3 baseline applies; the description goes beyond it by explaining what a visit's seq means and that the number is what should be passed as `visit` to other tools. It doesn't describe the sessionId parameter itself, but the schema already does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the specific resource (session page visits) and scope (oldest first, one top-level navigation per tab, numbered by seq). Explicitly distinguishes itself from list_pages ('for the tabs open now') and names the downstream consumers list_console_messages and list_network_requests.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit use case ('find which page load to inspect') and the alternative to pick instead (list_pages for currently open tabs). Also states the precondition 'Empty unless the listener role is running', which tells the agent when the tool will yield nothing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

load_browser_stateA
DestructiveIdempotent

Load cookies saved by save_browser_state into this session, usually right after open_browser_session and before navigate, so the session starts logged in. Pages already open need a reload or navigate to use them. Loaded cookies replace any with the same name, domain and path; others are kept. Expired logins won't work again; if the site still asks to log in, use request_human_takeover and save again. Fails if no state has that name; list_browser_states shows the names.

NameRequiredDescriptionDefault
nameYesName of the saved state: letters, digits, '.', '_' and '-' only.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
nameYes
cookieCountYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: exact replacement semantics (same name/domain/path overwritten, others kept), the fact that expired logins won't work, and the failure condition when no state exists. This directly explains the destructiveHint=true annotation rather than contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then sequencing, then edge cases. Dense but every sentence carries operational information; slightly long for a two-parameter tool but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the description covers sequencing, failure modes, cookie-overwrite behavior, and remediation. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameters are already documented; the description still adds value by stating the failure condition for an unknown 'name' and pointing to list_browser_states for valid names, plus confirming sessionId must come from an open session.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Load cookies saved by save_browser_state into this session') and anchors itself in the workflow right after open_browser_session and before navigate, which distinguishes it from siblings like navigate or request_human_takeover.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit sequencing advice, notes that already-open pages need a reload/navigate, names the fallback (request_human_takeover) when cookies fail, and points to list_browser_states for discovery. Both when-to-use and when-not/alternative paths are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_mouseA

Move the mouse to viewport coordinates x,y (CSS pixels from the top-left) in the session's active tab via CDP input (trusted move event), so the page's hover, mouseover and mousemove handlers fire. Use it to open hover menus and tooltips before reading or clicking them, and to add human-like behavioral telemetry. Don't use it to click, drag or scroll: use click and scroll. Coordinates outside the viewport are not rejected; the move just hovers nothing. Returns a confirmation with the position.

NameRequiredDescriptionDefault
xYesHorizontal position from the viewport's left edge in CSS pixels.
yYesVertical position from the viewport's top edge in CSS pixels.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real context beyond the annotations: the move is a trusted CDP input event that fires hover/mouseover/mousemove handlers, out-of-viewport coordinates are silently accepted and hover nothing, and the call returns a confirmation with the position. The non-rejection of out-of-range values is a genuinely useful non-obvious behavior. It does not state error conditions beyond the session lookup (already in schema) or whether the page is scrolled/waited on.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and coordinates, then usage, then exclusions and edge-case behavior. Every clause carries information, though the first sentence is dense with parentheticals stacked back to back.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter tool with no output schema, the definition covers action, coordinate semantics, side effects on page handlers, out-of-bounds behavior, exclusions, and the return value shape. Nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above baseline by clarifying the coordinate origin (top-left of the viewport), the unit (CSS pixels), and what happens when coordinates fall outside the viewport. Minor remaining ambiguity: behavior with fractional or negative coordinates is left implicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (move) and resource (the mouse) with precise scope: viewport CSS pixel coordinates in the session's active tab via CDP input. It distinguishes itself from click/scroll siblings by naming them, so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives positive use cases (open hover menus and tooltips before reading or clicking them, add human-like telemetry) and an explicit exclusion with the alternative named: 'Don't use it to click, drag or scroll: use click and scroll.' Both when and when-not are covered with a concrete routing rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

new_pageA

Open a new tab in the session and make it the active tab, so later navigate/click/type/screenshot calls act on it. Use navigate instead to load a URL in the current tab, and switch_tab to go back to an existing one. Tabs stay open until close_tab or close_browser_session, so close ones you no longer need. With url, the tab loads it and the call returns after the load event; if the URL fails to load, the call errors but the new tab still exists and is active. The returned index is the new tab's list_pages index.

NameRequiredDescriptionDefault
urlNoAbsolute URL to load in the new tab. Omit for about:blank.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
urlYes
indexYesThe tab's 0-based list_pages index.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (which only declare it is a non-readonly, non-idempotent, open-world, non-destructive mutation) by disclosing the load-event timing semantics, the partial-failure behavior ('the call errors but the new tab still exists and is active'), and the persistence model. The error-still-mutates detail is exactly the kind of trait that prevents an agent from retrying blindly and creating duplicate tabs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and its activation side effect in the first clause, then layers routing, lifecycle, and error semantics in decreasing order of importance. Every sentence carries distinct information — routing, cleanup, load timing, failure mode, return value — with no repetition of the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only 2 parameters and an output schema present, the description covers everything an agent needs: what is created, that it becomes active, how long it lives, what happens on load failure, and how the returned index relates to list_pages. Nothing material is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents both parameters and the about:blank default, making the baseline 3. The description adds real meaning on top: that supplying `url` blocks the call until the load event and how failure is surfaced. It does not restate sessionId semantics, which is fine since the schema covers them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Open a new tab in the session') plus the side effect that matters most ('make it the active tab'), and immediately explains the downstream consequence for navigate/click/type/screenshot calls. It explicitly names the siblings it is not (navigate, switch_tab), so an agent can route correctly without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use versus alternatives: 'Use navigate instead to load a URL in the current tab, and switch_tab to go back to an existing one.' It also names the two cleanup paths (close_tab, close_browser_session) and warns that tabs persist otherwise, covering the resource-leak avoidance case an agent would otherwise miss.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

open_browser_sessionA

Open a new isolated browser session and return its sessionId; call this first, then pass the id to every other tool. Each session is its own Chrome BrowserContext with separate cookies, storage and tabs, so sessions never see each other, and it starts with one blank tab. Don't open a new session per page: reuse one and use new_page for more tabs. To start logged in, follow with load_browser_state before navigate. Set viewport for a specific window size and useMobileUA to look like a phone; both are fixed for the session's life. Sessions persist until close_browser_session, or until the reaper role closes ones idle for MAX_IDLE_HOURS (default 24). Fails if Chrome is unreachable at BROWSER_URL.

NameRequiredDescriptionDefault
viewportNoWindow size in CSS pixels, { width, height }. Default 1280x800.
useMobileUANoSend a mobile User-Agent and client hints instead of desktop ones. Default false.

Output Schema

NameRequiredDescription
activeUrlNo
pageCountYes
sessionIdYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the generic create/side-effect profile (readOnly=false, idempotent=false). The description adds substantial context beyond that: cookie/storage isolation between contexts, a blank starting tab, immutability of viewport and useMobileUA for the session's life, lifetime rules (close_browser_session or reaper closing after MAX_IDLE_HOURS default 24), and a concrete failure mode (Chrome unreachable at BROWSER_URL).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first clause is the action and return value, the next is the mandatory next step, then escaping constraints, then lifetime, then failure. Every sentence carries a rule an agent must act on; nothing is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description covers creation semantics, isolation, sequencing, lifetime, and error behavior for a 2-optional-parameter tool. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented in structured fields. The description nevertheless adds meaning the schema lacks: that viewport and useMobileUA are fixed for the session's entire life, which affects how an agent decides when to set them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Open') and resource ('isolated browser session'), immediately follows with what it returns ('return its sessionId') and what it creates (a separate Chrome BrowserContext). An agent can distinguish it from new_page, list_browser_sessions, and close_browser_session without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit sequencing rules: 'call this first, then pass the id to every other tool', 'Don't open a new session per page: reuse one and use new_page for more tabs', and 'To start logged in, follow with load_browser_state before navigate.' It names the alternatives and the condition that selects each, including a when-not case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

press_keyA
Destructive

Press a key via CDP keyboard input in the session's active tab. key is a name (Enter, Tab, Escape, Backspace, ArrowDown, …) or a single character. With a selector, waits up to timeout for it and focuses it first (e.g. type into a field then press Enter); without, presses on whatever is focused, and timeout is unused. Use type for whole strings and click to activate buttons. Pressing Enter can submit a form, like a real user. Returns a confirmation. Fails on an unknown key name, or if the selector matches nothing within timeout.

NameRequiredDescriptionDefault
keyYesKey name in the US layout (Enter, Tab, Escape, Backspace, ArrowDown…) or one character.
timeoutNoMilliseconds to wait for `selector` to appear. Default 5000.
selectorNoCSS selector of an element to focus before pressing. Omit to press on the focused element.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real behavior beyond the annotations: focus acquisition, that `timeout` is unused without a selector, that Enter can submit a form 'like a real user', and explicit failure modes (unknown key name, selector never matching). The destructiveHint is implicitly supported by the form-submission warning, though it is not stated bluntly as a data-changing side effect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then modes, then alternatives, then failure behavior — a sensible ordering with no filler. Slightly dense in the middle clause about selector/timeout, but each sentence carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all four parameters, the two execution paths, the sibling alternatives, the notable side effect (form submission), the return signal ('a confirmation'), and the failure conditions. With no output schema, this is enough for an agent to call it correctly and anticipate outcomes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description earns above baseline by explaining the interaction between `selector` and `timeout` (timeout is dead weight without a selector) and by giving a concrete use pattern ('type into a field then press Enter') that the schema does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and mechanism ('Press a key via CDP keyboard input in the session's active tab') and immediately scopes it against siblings with 'Use type for whole strings and click to activate buttons.' An agent can distinguish press_key from type and click without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the two operating modes: with a selector it waits and focuses first, without one it presses on whatever is focused. It also names alternatives (type, click) and the condition that selects them, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

request_human_takeoverA

Hand the session's active page to a human to log in themselves (passwords/passkeys the agent must not see). Use it only when a login needs a person; for a site you've logged into before, try load_browser_state first. Show the returned url to the user and keep the token for await_human_takeover. Does NOT block. STRONGLY ADVISED: after showing the URL, run await_human_takeover in a BACKGROUND task (subagent/job) — not your main loop — because the human may take many minutes and you should stay responsive. The URL is a bearer credential that gives live control of the tab until ttlMinutes passes, so share it only with the intended person. Fails if TAKEOVER_BASE_URL isn't configured on the server.

NameRequiredDescriptionDefault
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.
ttlMinutesNoMinutes the link stays valid, 1 to 60 (larger values are capped). The link is a bearer credential, so keep it short. Default 30.

Output Schema

NameRequiredDescription
urlYesThe link to show the person who will log in.
tokenYesPass to await_human_takeover.
expiresAtMsYesWhen the link stops working, in milliseconds since the Unix epoch.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only flag it as non-read, non-idempotent, open-world and non-destructive; the description goes well beyond that by disclosing that it does NOT block, that the returned URL is a bearer credential granting live control of the tab until ttlMinutes expires, that it fails when TAKEOVER_BASE_URL is unconfigured, and that the token must be retained for await_human_takeover.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then usage gating, then operational warnings; every sentence carries actionable content. It is dense and slightly long, with the bearer-credential point and the background-task advice each taking a full clause, but nothing is expendable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail is not required, and the description still tells the agent what to do with the returned url and token. Combined with the failure mode, non-blocking behavior and concurrency guidance, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real meaning: it frames the URL/token lifecycle around ttlMinutes (short-lived because the URL is a credential) and clarifies that it acts on the session's active page rather than any page. It does not restate the 1-60 cap or default, leaving that to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: hand the session's active page to a human to log in themselves. It draws a sharp line against sibling tools by naming the parenthetical reason (passwords/passkeys the agent must not see), so it is unmistakable versus click/type/evaluate or load_browser_state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives both when-to-use ('only when a login needs a person') and an alternative to try first ('for a site you've logged into before, try load_browser_state first'). It also sequences the follow-up tool and prescribes how to run it (await_human_takeover in a background subagent/job, not the main loop).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_browser_stateA
DestructiveIdempotent

Save the session's cookies under a name so a future session can load them with load_browser_state and resume without logging in again. Call it after a successful login (for example once await_human_takeover completes). Saving under an existing name replaces that state, so use a distinct name per site or account. Only cookies are saved, not localStorage, so sites that keep their login in localStorage won't resume. States are stored on disk as plaintext and include session credentials. Fails on a name with characters other than letters, digits, '.', '_' and '-'.

NameRequiredDescriptionDefault
nameYesName of the saved state: letters, digits, '.', '_' and '-' only.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
nameYes
savedAtYes
cookieCountYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (destructive/idempotent/openWorld=false), it discloses overwrite-on-existing-name semantics, that only cookies are captured (not localStorage) so some sites won't resume, that states are stored as plaintext credentials, and that invalid names fail — all material facts an agent cannot get from the schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four compact sentences, front-loaded with the action and purpose, then prerequisites, then caveats. Every sentence carries distinct operational information with no repetition of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. For a two-parameter state-mutation tool, everything an agent needs — when to call, naming, overwrite risk, coverage limitation, and credential exposure — is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description adds meaning by explaining that 'name' acts as a key whose reuse replaces prior state, and restates the allowed character set — though it does not elaborate on sessionId beyond what the schema already says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (save session cookies under a name) plus the payoff (resume without logging in), and explicitly names the complementary sibling load_browser_state so the agent can tell it apart from list_browser_states/delete_browser_state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete triggering conditions ('after a successful login', 'once await_human_takeover completes') and a naming rule ('use a distinct name per site or account'). It also names the follow-up tool that consumes the artifact, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scrollA

Scroll the session's active tab with a real mouse-wheel event at a viewport position; whatever scrollable element is under (x,y) scrolls, so point inside a scrollable panel to scroll it rather than the page. deltaY and deltaX are in pixels; negative values scroll up or left. Useful to reveal lazy-loaded content and to generate human-like behavioral signals. Don't use it just to reach an element before clicking: click scrolls its target into view itself. Returns immediately without waiting for content to load; follow with wait_for if needed.

NameRequiredDescriptionDefault
xNoWheel position from the viewport's left edge in CSS pixels. Default 50.
yNoWheel position from the viewport's top edge in CSS pixels. Default 50.
deltaXNoHorizontal pixels to scroll; negative scrolls left. Default 0.
deltaYNoVertical pixels to scroll; negative scrolls up. Default 600.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, openWorldHint=true, non-idempotent, non-destructive), and the description adds the timing behavior that annotations cannot express: it returns immediately without waiting for content to load. It does not discuss rate limits or failure modes, but the key operational caveat is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core mechanism, then the targeting rule, then units, then use cases, then the exclusion. Every sentence carries distinct information and none repeats the schema verbatim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter interaction tool with no output schema, the description covers the mechanism, targeting, units, timing behavior, follow-up requirement, and anti-pattern. Nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the schema documents defaults and units. The description still adds real semantics beyond the schema: the delta units and sign direction, and crucially that x/y select which scrollable panel receives the wheel event rather than being arbitrary coordinates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (scroll) plus the mechanism (real mouse-wheel event at a viewport position), and explains the targeting rule that the element under (x,y) scrolls rather than the page. This is clearly distinguishable from the sibling click and move_mouse tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names both when to use it (revealing lazy-loaded content, generating human-like behavioral signals) and when not to ('Don't use it just to reach an element before clicking'), and names the alternative behavior that replaces it (click scrolls its target into view). It also prescribes the follow-up pattern with wait_for.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_stealthA
Idempotent

Toggle stealth for a session. enabled: true disables the CDP Runtime domain (removes the Runtime.enable automation tell that anti-bot systems like Cloudflare detect) — load/navigate pages in this mode to pass CDP-based bot gates; the cost is no console capture and evaluate runs in an isolated world (can't read page globals like window.dataLayer). enabled: false re-enables Runtime: console capture + main-world evaluate (reads page globals) return, but the CDP tell is present. Typical flow: set_stealth(true) → navigate → set_stealth(false) → evaluate. Leave it off for sites without bot detection.

NameRequiredDescriptionDefault
enabledYestrue turns stealth on, false turns it off.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
stealthYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations by naming the concrete costs of each mode: no console capture and an isolated-world `evaluate` that cannot read window globals while on; restoration of console capture and main-world access while off. It also explains why the tradeoff exists (Runtime.enable is an automation tell Cloudflare detects), which annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with a one-line purpose, then the true-case, then the false-case, then the typical flow. Dense but every sentence carries unique operational information; nothing is repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists, so return values need no explanation, and the mode tradeoffs and error condition (session must be open) are covered. Minor gaps: it never says whether stealth persists across navigations or how to verify current state (get_stealth), leaving the agent to guess on state inspection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds substantial meaning beyond "true turns stealth on": it explains the downstream consequences of each boolean value on console capture and `evaluate` scope. That is genuine semantics the schema does not carry.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Toggle stealth for a session" gives a specific verb (toggle) and resource (session stealth), and the body spells out exactly what the tool changes: the CDP Runtime domain. The mechanics make it unmistakable from the read-only get_stealth sibling, even though that name is never mentioned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit recipe ("set_stealth(true) → navigate → set_stealth(false) → evaluate") plus an explicit when-not ("Leave it off for sites without bot detection"). An agent knows both the sequence and the exclusion without inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

start_profilingA

Start the V8 CPU profiler on a tab (active tab by default, or tabIndex). Use to find which JavaScript makes a page slow or unresponsive: start, reproduce the problem (navigate/click/wait), then call stop_profiling on the same tab. Don't use it for network slowness; list_network_requests shows that. The 1000µs default suits most slowness; lower samplingIntervalUs (e.g. 100) only to catch functions shorter than a millisecond, at the cost of more overhead and a larger profile. Profiling continues until stop_profiling, so always stop it. Returns a confirmation. Fails if that tab is already being profiled; the running recording continues.

NameRequiredDescriptionDefault
tabIndexNoTab to profile, by its 0-based list_pages index. Default: the active tab.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.
samplingIntervalUsNoMicroseconds between stack samples; smaller is more detailed but heavier. Default 1000.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the mutation/idempotency profile; the description adds the operationally important facts an agent can't get from them: profiling keeps running until stop_profiling, calling again fails while a recording is active and the existing one continues, and higher sampling costs overhead and a larger profile. It also mentions the return value (a confirmation).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and default, then workflow, then tuning, then failure mode. Dense but nearly every clause carries information; the sampling discussion is the one place it could be trimmed slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a stateful, non-idempotent tool with no output schema, the description covers the full lifecycle (start → reproduce → stop), the failure mode, and the fact that it returns a confirmation. An agent has everything needed to call it correctly and clean up.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description still adds real meaning by explaining when to deviate from the 1000µs default and what the tradeoff is, plus that tabIndex defaults to the active tab. It adds rationale rather than restating types, though it doesn't tie advice to each parameter individually.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Start the V8 CPU profiler on a tab') with scope clarified (active tab by default, or tabIndex). Immediately distinguishes itself from list_network_requests by naming the excluded concern (network slowness) and points at stop_profiling as its pair.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit workflow (start, reproduce, then stop_profiling on the same tab), an explicit when-not (network slowness → list_network_requests), and concrete tuning advice for samplingIntervalUs. Alternatives and exclusions are both named rather than inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stop_profilingA
Destructive

Stop the CPU profiler started by start_profiling, save a .cpuprofile under $STATE_DIR/logs//profiles/ (its path is in the result; open it as a flame graph in the DevTools Performance panel or speedscope.app) and return the culprits: long tasks (>=50ms) split into JS vs browser-native (parse/style/layout) vs GC time with their top scripts, top JS functions and heaviest JS stack, top functions by self and total time (with url:line:col), and self time per script. Pass the same tabIndex given to start_profiling. If page JS is hung, the renderer can't answer until it yields, so after terminateAfterMs the running script is terminated to get the profile out (terminated in the result says so); set it to 0 to never terminate. top caps each ranked list, so raise it when the culprit isn't in the first 15, and keep timeout a few seconds above terminateAfterMs so a large profile has time to transfer. The file is deleted with the session by close_browser_session. Fails if start_profiling wasn't called on that tab.

NameRequiredDescriptionDefault
topNoHow many entries to return in each ranked list. Default 15.
timeoutNoMilliseconds the whole stop call may take before failing. Default 30000.
tabIndexNoThe tab passed to start_profiling, by its 0-based list_pages index. Default: the active tab.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.
terminateAfterMsNoMilliseconds to wait for hung page JS before terminating it; 0 never terminates. Default 5000.

Output Schema

NameRequiredDescription
pathYesWhere the .cpuprofile was saved.
busyMsYes
samplesYes
topSelfYes
topTotalYes
longTasksYes
durationMsYes
terminatedYesWhether hung page JS was terminated to collect the profile.
topScriptsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations by explaining that a .cpuprofile is saved, where it lives, how to open it, what analysis is returned, and that hung page JS may be terminated after terminateAfterMs. It also discloses lifecycle behavior: the file is deleted with the session by close_browser_session, which is important given the destructive annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and the rest is dense but mostly useful. It is longer than ideal as a single paragraph, but every sentence carries operational information for a complex tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex profiling tool with an output schema, annotations, and five parameters, the description is complete enough to call correctly. It covers prerequisites, side effects, output location, result contents, failure conditions, parameter interactions, and session-bound file lifecycle.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3. The description adds meaningful semantic detail beyond the schema: tabIndex must match start_profiling, top caps each ranked list, terminateAfterMs of 0 never terminates, and timeout should be a few seconds above terminateAfterMs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: stop the CPU profiler started by start_profiling, and describes the saved .cpuprofile plus the returned culprit analysis. It is clearly distinguishable from sibling tools like start_profiling and close_browser_session.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use it after start_profiling, requires passing the same tabIndex, and fails if start_profiling was not called on that tab. It also gives practical guidance for terminateAfterMs, top, and timeout, including when to raise `top` and how to set `timeout` relative to `terminateAfterMs`.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

switch_tabA
Idempotent

Make the tab at tabIndex the active tab, so later navigate/evaluate/screenshot/click/type calls target it, and bring it to the front in Chrome (the human-takeover live view follows it too). Use new_page to open a tab instead, and pass tabIndex straight to evaluate or the profiling tools to act on another tab without switching. Indices come from list_pages and shift when a tab closes, so list again if unsure. Fails if the session has no tab at that index.

NameRequiredDescriptionDefault
tabIndexYesA tab's 0-based index from list_pages. Errors if the session has no tab at that index.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

Output Schema

NameRequiredDescription
urlYes
indexYesThe tab's 0-based list_pages index.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description explains that switching affects later navigate/evaluate/screenshot/click/type calls, brings the tab to the front in Chrome, and moves the human-takeover live view with it. It also discloses that indices shift when tabs close and that failure occurs if no tab exists at that index.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the primary action and consequence, then adds alternatives, index volatility, and failure behavior in tight sentences. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the annotations, full schema coverage, and available output schema, the description supplies the remaining behavior an agent needs: targeting effects, tab-to-front behavior, index volatility, alternatives, and failure condition. Nothing important for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds useful semantic context about tabIndex: it comes from list_pages, shifts when a tab closes, and should be refreshed if uncertain. It also explains an alternative use of tabIndex with evaluate/profiling tools without switching.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: it makes the tab at tabIndex the active tab. It also distinguishes this from new_page and from acting on another tab via evaluate/profiling without switching.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use new_page to open a tab and to pass tabIndex directly to evaluate or profiling tools when switching is unnecessary. It also gives practical guidance to re-list pages if indices may have shifted and states the failure condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

take_screenshotA
Read-only

Capture a PNG of the session's active tab and return it as an image. Use it when visual layout, styling or images matter; use take_snapshot for a cheaper text view of the page's structure, and evaluate to read specific values. fullPage captures the whole scrollable page instead of the visible viewport, which can make a very large image on long pages. It reads the page without changing it. Returns the image plus a caption with its size in bytes.

NameRequiredDescriptionDefault
fullPageNoCapture the whole scrollable page instead of only the visible viewport. Default false.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The statement 'It reads the page without changing it' aligns with readOnlyHint=true and reinforces it for a screenshot operation an agent might suspect of side effects. It adds a genuinely useful warning that fullPage 'can make a very large image on long pages' and discloses the return format (image plus byte-size caption). Minor gap: no mention of size limits, truncation, or failure modes for pages that never finish loading.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action, then routing to alternatives, then the one behavioral caveat and the return format. Every clause carries decision-relevant information; no restatement of the tool name or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still explains the return value (image plus a caption with byte size) and covers safety and cost tradeoffs for the only optional parameter. Nothing an agent needs to invoke this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds a consequence not present in the schema: fullPage captures the whole scrollable page and may produce a very large image on long pages. That cost signal helps an agent decide whether to pass the flag, going beyond the schema's neutral 'Default false.'

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Capture a PNG of the session's active tab') and the return shape ('return it as an image'), which is distinct from take_snapshot (text structure) and evaluate (specific values). An agent can distinguish it from every sibling without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names when to use it ('when visual layout, styling or images matter') and names the two alternatives with the conditions that select them: take_snapshot for a cheaper text view, evaluate for specific values. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

take_snapshotA
Read-only

Return the accessibility tree of the session's active tab as indented text: each node's role and name (links, buttons, headings, form fields and their labels, and current values), nested by structure. Use it to find what's on the page and what to click or type into, far more cheaply than take_screenshot; use take_screenshot when visual layout matters, and evaluate for data not shown as text. It reads the page without changing it and returns the whole tree, so a large page gives long output.

NameRequiredDescriptionDefault
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safety profile is covered; the description reinforces it ('reads the page without changing it') and adds useful context the annotations don't carry: it returns the whole tree unfiltered, so large pages produce long output. No mention of any rate limits or truncation behavior beyond output length, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what is returned before the routing advice and the output-size caveat. Dense but every clause earns its place — the sibling comparisons and the long-output warning both change agent behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema, the description supplies the return shape (indented text, role + name, nested by structure) and the output-size caveat, plus the decision boundary against two siblings. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter (sessionId) with 100% schema description coverage that already explains it comes from open_browser_session and errors if missing. The description adds no parameter-level detail, which is acceptable given the schema does the work; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Return the accessibility tree of the session's active tab as indented text') and enumerates the content: roles, names, links, buttons, headings, form fields, labels, current values. This makes it immediately distinguishable from take_screenshot and evaluate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes between siblings: use this to find what's on the page and what to click or type into, 'far more cheaply than take_screenshot'; use take_screenshot when visual layout matters; use evaluate for data not shown as text. Both the when and the when-not are named with concrete alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

typeA
Destructive

Type text into the first element matching a CSS selector in the session's active tab: waits up to timeout for it, clicks it to focus, then sends real key events for each character, so the page's input handlers fire. Use press_key afterwards for Enter or Tab, and press_key alone for single keys. clear empties the field first; without it, text is appended. delay paces the characters for pages that react to typing speed. It doesn't check that the element is editable: typing into a button or plain text reports success but changes nothing, so target an input, textarea or contenteditable element. Returns how many characters were typed. Fails if the selector matches nothing within timeout.

NameRequiredDescriptionDefault
textYesThe text to type.
clearNoEmpty the field's current value before typing. Default false, which appends.
delayNoMilliseconds to pause after each character, for pages that react to typing speed. Default 0.
timeoutNoMilliseconds to wait for `selector` to appear. Default 5000.
selectorYesCSS selector of the input, textarea or editable element.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (destructive/openWorld/non-idempotent) by disclosing the wait-then-click-to-focus sequence, real key event dispatch so page handlers fire, and the failure mode of a non-matching selector. The most valuable disclosure is the silent no-op on non-editable targets — success reported but nothing changed — which no annotation conveys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and mechanism, then usage routing and caveats. It is a single dense paragraph with no filler sentences, though the caveat about non-editable elements could be its own sentence for scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by stating the return value (number of characters typed) and the failure condition. For a 6-parameter mutation tool, the description covers what an agent needs to call it correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds behavioral meaning the schema does not: timeout governs both waiting for the element and the failure condition, clear vs append semantics, and delay exists for speed-sensitive pages. It stops short of adding format details for selector/sessionId, which the schema already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and target (type text into the first element matching a CSS selector in the active tab) and explains the mechanism (focus click + real key events). It is clearly distinguished from press_key, which it names as the tool for single keys and Enter/Tab.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: use press_key afterwards for Enter or Tab, press_key alone for single keys, and target an input/textarea/contenteditable rather than a button. The clear-vs-append choice and the delay option are both framed by when you'd want them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wait_forA
Read-only

Wait until a CSS selector matches an element, or a text string appears in the page's visible text, in the session's active tab, polling every 100ms. Use it after navigate, click or scroll when content loads asynchronously, instead of sleeping. Pass selector or text; if both are given, only selector is checked. text is a case-sensitive substring of document.body.innerText, so text hidden with CSS doesn't count. It reads the page without changing it. Returns which selector or text matched. Fails with a timeout error if nothing matches within timeout, or if neither argument is given.

NameRequiredDescriptionDefault
textNoText to wait for in document.body.innerText; case-sensitive substring match.
timeoutNoMilliseconds to wait before failing. Default 10000.
selectorNoCSS selector to wait for.
sessionIdYesThe id returned by open_browser_session. Errors if no open session has it.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, and the description reinforces this with 'reads the page without changing it' plus concrete runtime traits: 100ms polling, timeout-based failure, and which value is returned. It does not cover whether the wait can be cancelled or how long the default timeout is (the schema covers the default), so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The what and the scope lead, usage guidance and precedence follow, and edge cases (case sensitivity, hidden text, timeout failure) close it out. Every sentence adds information; nothing is repetitive of the name or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter, single-required-argument wait tool with no output schema, the description covers invocation, precedence, matching semantics, failure mode, and the return value. An agent has everything needed to call it correctly on the first attempt.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns extra by documenting the precedence rule when both `selector` and `text` are given, that `text` matches case-sensitively against document.body.innerText, and that CSS-hidden text does not count. These are semantics not visible in the schema field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (wait) with two precise resources (CSS selector match / text appearing in visible page text), scoped to the session's active tab and a concrete polling interval. An agent can distinguish it from take_snapshot or evaluate without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use it 'after navigate, click or scroll when content loads asynchronously, instead of sleeping,' naming both the triggering context and the alternative behavior to avoid. Also states the failure condition when neither argument is supplied, which routes the agent away from calling it blindly.

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.

  1. 19 tool updatesv0.1.5
    • Changedawait_human_takeover1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "completed": {
        +      "description": "True once the person clicked Done; false on timeout.",
        +      "type": "boolean"
        +    },
        +    "token": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "completed",
        +    "token"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_browser_state1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "name": {
        +      "type": "string"
        +    },
        +    "removed": {
        +      "description": "False if no state had that name.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "removed"
        +  ],
        +  "type": "object"
        +}
    • Changedevaluate1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "result": {
        +      "description": "The expression's value; null for undefined."
        +    }
        +  },
        +  "required": [
        +    "result"
        +  ],
        +  "type": "object"
        +}
    • Changedget_stealth1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "stealth": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "stealth"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_browser_sessions1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "SessionInfo": {
        +      "properties": {
        +        "activeUrl": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "pageCount": {
        +          "format": "uint",
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "sessionId": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "sessionId",
        +        "pageCount"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "sessions": {
        +      "items": {
        +        "$ref": "#/$defs/SessionInfo"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "sessions"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_browser_states1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "StateSummary": {
        +      "properties": {
        +        "cookieCount": {
        +          "format": "uint",
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "name": {
        +          "type": "string"
        +        },
        +        "savedAt": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "name",
        +        "savedAt",
        +        "cookieCount"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "states": {
        +      "items": {
        +        "$ref": "#/$defs/StateSummary"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "states"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_console_messages1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "ConsoleEntry": {
        +      "properties": {
        +        "t": {
        +          "type": "string"
        +        },
        +        "text": {
        +          "type": "string"
        +        },
        +        "type": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "t",
        +        "type",
        +        "text"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "messages": {
        +      "items": {
        +        "$ref": "#/$defs/ConsoleEntry"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "messages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_network_requests1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "NetworkEntry": {
        +      "properties": {
        +        "failure": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "method": {
        +          "type": "string"
        +        },
        +        "post_data": {
        +          "description": "Request body for POST/PUT/etc., when Chrome inlines it in\n`Network.requestWillBeSent` (small bodies). Lets callers inspect what a\npage POSTed (e.g. analytics pixel payloads) without a per-page JS hook.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "redirected_to": {
        +          "description": "For a redirect hop (3xx `status`): the URL it redirected to. The next\nhop is logged as its own entry.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "status": {
        +          "format": "int64",
        +          "type": [
        +            "integer",
        +            "null"
        +          ]
        +        },
        +        "t": {
        +          "type": "string"
        +        },
        +        "url": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "t",
        +        "method",
        +        "url"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "requests": {
        +      "items": {
        +        "$ref": "#/$defs/NetworkEntry"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "requests"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_pages1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "PageSummary": {
        +      "properties": {
        +        "active": {
        +          "description": "Whether this is the tab other tools act on by default.",
        +          "type": "boolean"
        +        },
        +        "index": {
        +          "description": "0-based index to pass as `tabIndex`.",
        +          "format": "uint",
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "title": {
        +          "type": "string"
        +        },
        +        "url": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "index",
        +        "url",
        +        "title",
        +        "active"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "pages": {
        +      "items": {
        +        "$ref": "#/$defs/PageSummary"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_visits1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "VisitHeader": {
        +      "properties": {
        +        "openedAt": {
        +          "type": "string"
        +        },
        +        "seq": {
        +          "format": "uint32",
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "targetId": {
        +          "type": "string"
        +        },
        +        "url": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "seq",
        +        "targetId",
        +        "url",
        +        "openedAt"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "visits": {
        +      "items": {
        +        "$ref": "#/$defs/VisitHeader"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "visits"
        +  ],
        +  "type": "object"
        +}
    • Changedload_browser_state1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "cookieCount": {
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "name": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "cookieCount"
        +  ],
        +  "type": "object"
        +}
    • Changednavigate1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "url": {
        +      "description": "The page's URL after any redirects.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "url"
        +  ],
        +  "type": "object"
        +}
    • Changednew_page1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "index": {
        +      "description": "The tab's 0-based list_pages index.",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "url": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "index",
        +    "url"
        +  ],
        +  "type": "object"
        +}
    • Changedopen_browser_session1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "activeUrl": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "pageCount": {
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "sessionId": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "sessionId",
        +    "pageCount"
        +  ],
        +  "type": "object"
        +}
    • Changedrequest_human_takeover1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "expiresAtMs": {
        +      "description": "When the link stops working, in milliseconds since the Unix epoch.",
        +      "format": "uint128",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "token": {
        +      "description": "Pass to await_human_takeover.",
        +      "type": "string"
        +    },
        +    "url": {
        +      "description": "The link to show the person who will log in.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "url",
        +    "token",
        +    "expiresAtMs"
        +  ],
        +  "type": "object"
        +}
    • Changedsave_browser_state1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "cookieCount": {
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "savedAt": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "savedAt",
        +    "cookieCount"
        +  ],
        +  "type": "object"
        +}
    • Changedset_stealth1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "stealth": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "stealth"
        +  ],
        +  "type": "object"
        +}
    • Changedstop_profiling1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "FnStat": {
        +      "properties": {
        +        "function": {
        +          "type": "string"
        +        },
        +        "location": {
        +          "type": "string"
        +        },
        +        "ms": {
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "percent": {
        +          "format": "double",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "function",
        +        "location",
        +        "ms",
        +        "percent"
        +      ],
        +      "type": "object"
        +    },
        +    "LongTask": {
        +      "properties": {
        +        "durationMs": {
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "gcMs": {
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "nativeMs": {
        +          "description": "Browser-native work V8 can't attribute to a script: parsing, style,\nlayout, paint. A task dominated by this is layout/DOM churn, not one\nslow function.",
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "stack": {
        +          "description": "Stack of the heaviest JS frame, innermost first.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "startMs": {
        +          "description": "Offset from profile start.",
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "topJs": {
        +          "description": "JS functions with the most self time in this task (`percent` is of the\ntask).",
        +          "items": {
        +            "$ref": "#/$defs/FnStat"
        +          },
        +          "type": "array"
        +        },
        +        "topScripts": {
        +          "description": "Scripts with the most self time in this task (`percent` is of the\ntask). Usually the clearest culprit: a task's self time is often spread\nthin across many small functions of one script.",
        +          "items": {
        +            "$ref": "#/$defs/ScriptStat"
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "startMs",
        +        "durationMs",
        +        "nativeMs",
        +        "gcMs",
        +        "topJs",
        +        "topScripts",
        +        "stack"
        +      ],
        +      "type": "object"
        +    },
        +    "ScriptStat": {
        +      "properties": {
        +        "percent": {
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "selfMs": {
        +          "format": "double",
        +          "type": "number"
        +        },
        +        "url": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "url",
        +        "selfMs",
        +        "percent"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "busyMs": {
        +      "format": "double",
        +      "type": "number"
        +    },
        +    "durationMs": {
        +      "format": "double",
        +      "type": "number"
        +    },
        +    "longTasks": {
        +      "items": {
        +        "$ref": "#/$defs/LongTask"
        +      },
        +      "type": "array"
        +    },
        +    "path": {
        +      "description": "Where the .cpuprofile was saved.",
        +      "type": "string"
        +    },
        +    "samples": {
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "terminated": {
        +      "description": "Whether hung page JS was terminated to collect the profile.",
        +      "type": "boolean"
        +    },
        +    "topScripts": {
        +      "items": {
        +        "$ref": "#/$defs/ScriptStat"
        +      },
        +      "type": "array"
        +    },
        +    "topSelf": {
        +      "items": {
        +        "$ref": "#/$defs/FnStat"
        +      },
        +      "type": "array"
        +    },
        +    "topTotal": {
        +      "items": {
        +        "$ref": "#/$defs/FnStat"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "durationMs",
        +    "busyMs",
        +    "samples",
        +    "topSelf",
        +    "topTotal",
        +    "topScripts",
        +    "longTasks",
        +    "path",
        +    "terminated"
        +  ],
        +  "type": "object"
        +}
    • Changedswitch_tab1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "properties": {
        +    "index": {
        +      "description": "The tab's 0-based list_pages index.",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "url": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "index",
        +    "url"
        +  ],
        +  "type": "object"
        +}
  2. 1 tool updatev0.1.4
    • Changedclose_browser_session1 field changed
      • changedInput schema / properties / sessionId / description
        Previous value: -"The id returned by open_browser_session. Errors if no open session has it."New value: +"The id returned by open_browser_session. An unknown or already-closed id succeeds without error."
  3. 28 tool updates
    • Changedawait_human_takeover2 fields changed
      • addedInput schema / properties / timeout / description
        Added value: +"Milliseconds to wait before returning completed: false. Default 300000, max 1800000."
      • addedInput schema / properties / token / description
        Added value: +"The token returned by request_human_takeover."
    • Changedclick5 fields changed
      • addedInput schema / properties / selector / description
        Added value: +"CSS selector of the element to click; the first match is used."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / timeout / description
        Added value: +"Milliseconds to wait for `selector` to appear. Default 5000."
      • addedInput schema / properties / x / description
        Added value: +"Horizontal viewport coordinate in CSS pixels, used with `y` when no selector is given."
      • addedInput schema / properties / y / description
        Added value: +"Vertical viewport coordinate in CSS pixels, used with `x` when no selector is given."
    • Changedclose_browser_session1 field changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedclose_tab2 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / tabIndex / description
        Added value: +"A tab's 0-based index from list_pages. Errors if the session has no tab at that index."
    • Changeddelete_browser_state1 field changed
      • addedInput schema / properties / name / description
        Added value: +"Name of the saved state: letters, digits, '.', '_' and '-' only."
    • Changedevaluate3 fields changed
      • addedInput schema / properties / expression / description
        Added value: +"JavaScript to run. Promises are awaited; the value must be JSON-serializable."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / tabIndex / description
        Added value: +"Tab to run in, by its 0-based list_pages index. Default: the active tab."
    • Changedget_stealth1 field changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedlist_console_messages3 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Return at most this many of the newest messages. Default 500."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / visit / description
        Added value: +"Only messages from this visit, by its `seq` from list_visits. Default: all visits."
    • Changedlist_network_requests3 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Return at most this many of the newest requests. Default 500."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / visit / description
        Added value: +"Only requests from this visit, by its `seq` from list_visits. Default: all visits."
    • Changedlist_pages1 field changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedlist_visits1 field changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedload_browser_state2 fields changed
      • addedInput schema / properties / name / description
        Added value: +"Name of the saved state: letters, digits, '.', '_' and '-' only."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedmove_mouse3 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / x / description
        Added value: +"Horizontal position from the viewport's left edge in CSS pixels."
      • addedInput schema / properties / y / description
        Added value: +"Vertical position from the viewport's top edge in CSS pixels."
    • Changednavigate3 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / timeout / description
        Added value: +"Milliseconds to wait for the load event before failing. Default: no limit."
      • addedInput schema / properties / url / description
        Added value: +"Absolute URL to load, including the scheme."
    • Changednew_page2 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / url / description
        Added value: +"Absolute URL to load in the new tab. Omit for about:blank."
    • Changedopen_browser_session2 fields changed
      • addedInput schema / properties / useMobileUA / description
        Added value: +"Send a mobile User-Agent and client hints instead of desktop ones. Default false."
      • addedInput schema / properties / viewport / description
        Added value: +"Window size in CSS pixels, { width, height }. Default 1280x800."
    • Changedpress_key4 fields changed
      • addedInput schema / properties / key / description
        Added value: +"Key name in the US layout (Enter, Tab, Escape, Backspace, ArrowDown…) or one character."
      • addedInput schema / properties / selector / description
        Added value: +"CSS selector of an element to focus before pressing. Omit to press on the focused element."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / timeout / description
        Added value: +"Milliseconds to wait for `selector` to appear. Default 5000."
    • Changedrequest_human_takeover2 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / ttlMinutes / description
        Added value: +"Minutes the link stays valid, 1 to 60 (larger values are capped). The link is a bearer credential, so keep it short. Default 30."
    • Changedsave_browser_state2 fields changed
      • addedInput schema / properties / name / description
        Added value: +"Name of the saved state: letters, digits, '.', '_' and '-' only."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedscroll5 fields changed
      • addedInput schema / properties / deltaX / description
        Added value: +"Horizontal pixels to scroll; negative scrolls left. Default 0."
      • addedInput schema / properties / deltaY / description
        Added value: +"Vertical pixels to scroll; negative scrolls up. Default 600."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / x / description
        Added value: +"Wheel position from the viewport's left edge in CSS pixels. Default 50."
      • addedInput schema / properties / y / description
        Added value: +"Wheel position from the viewport's top edge in CSS pixels. Default 50."
    • Changedset_stealth2 fields changed
      • addedInput schema / properties / enabled / description
        Added value: +"true turns stealth on, false turns it off."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedstart_profiling3 fields changed
      • addedInput schema / properties / samplingIntervalUs / description
        Added value: +"Microseconds between stack samples; smaller is more detailed but heavier. Default 1000."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / tabIndex / description
        Added value: +"Tab to profile, by its 0-based list_pages index. Default: the active tab."
    • Changedstop_profiling5 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / tabIndex / description
        Added value: +"The tab passed to start_profiling, by its 0-based list_pages index. Default: the active tab."
      • addedInput schema / properties / terminateAfterMs / description
        Added value: +"Milliseconds to wait for hung page JS before terminating it; 0 never terminates. Default 5000."
      • addedInput schema / properties / timeout / description
        Added value: +"Milliseconds the whole stop call may take before failing. Default 30000."
      • addedInput schema / properties / top / description
        Added value: +"How many entries to return in each ranked list. Default 15."
    • Changedswitch_tab2 fields changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / tabIndex / description
        Added value: +"A tab's 0-based index from list_pages. Errors if the session has no tab at that index."
    • Changedtake_screenshot2 fields changed
      • addedInput schema / properties / fullPage / description
        Added value: +"Capture the whole scrollable page instead of only the visible viewport. Default false."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedtake_snapshot1 field changed
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
    • Changedtype6 fields changed
      • addedInput schema / properties / clear / description
        Added value: +"Empty the field's current value before typing. Default false, which appends."
      • addedInput schema / properties / delay / description
        Added value: +"Milliseconds to pause after each character, for pages that react to typing speed. Default 0."
      • addedInput schema / properties / selector / description
        Added value: +"CSS selector of the input, textarea or editable element."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / text / description
        Added value: +"The text to type."
      • addedInput schema / properties / timeout
        Added value: +{
        +  "description": "Milliseconds to wait for `selector` to appear. Default 5000.",
        +  "minimum": 1,
        +  "type": "integer"
        +}
    • Changedwait_for4 fields changed
      • addedInput schema / properties / selector / description
        Added value: +"CSS selector to wait for."
      • addedInput schema / properties / sessionId / description
        Added value: +"The id returned by open_browser_session. Errors if no open session has it."
      • addedInput schema / properties / text / description
        Added value: +"Text to wait for in document.body.innerText; case-sensitive substring match."
      • addedInput schema / properties / timeout / description
        Added value: +"Milliseconds to wait before failing. Default 10000."
  4. 30 tool updatesv0.1.2
    • First observedawait_human_takeover
    • First observedclick
    • First observedclose_browser_session
    • First observedclose_tab
    • First observeddelete_browser_state
    • First observedevaluate
    • First observedget_stealth
    • First observedlist_browser_sessions
    • First observedlist_browser_states
    • First observedlist_console_messages
    • First observedlist_network_requests
    • First observedlist_pages
    • First observedlist_visits
    • First observedload_browser_state
    • First observedmove_mouse
    • First observednavigate
    • First observednew_page
    • First observedopen_browser_session
    • First observedpress_key
    • First observedrequest_human_takeover
    • First observedsave_browser_state
    • First observedscroll
    • First observedset_stealth
    • First observedstart_profiling
    • First observedstop_profiling
    • First observedswitch_tab
    • First observedtake_screenshot
    • First observedtake_snapshot
    • First observedtype
    • First observedwait_for

TDQS

A4.5/5.0

Scored across 30 tools

Disambiguation5/5

Every tool has a sharply distinct purpose, and the descriptions explicitly cross-reference siblings to disambiguate (navigate vs new_page, list_pages vs list_browser_sessions vs list_visits vs list_browser_states, take_screenshot vs take_snapshot vs evaluate, click vs evaluate-based clicks). Even the closely-related logging and state tools each carve out a clear, non-overlapping role. An agent could reliably select the right tool without guessing.

Naming Consistency4/5

Names are uniformly snake_case and mostly use a predictable verb_noun pattern (open_browser_session, close_tab, list_pages, take_screenshot, save_browser_state, request_human_takeover). A few break the pattern as bare verbs (navigate, click, type, scroll, evaluate) and 'new_page' should arguably be 'open_page' for symmetry with open_browser_session/close_tab. Still highly readable and internally coherent.

Tool Count3/5

30 tools is heavy and stretches past a comfortable surface, though the breadth reflects genuine scope (sessions, tabs, interaction, perception, logging, profiling, stealth, takeover, cookie state). Each tool earns its place individually, but the set is large enough that an agent must navigate many options for a single task. Borderline over-scoped rather than well-scoped.

Completeness4/5

Covers the core lifecycle well: session/tab management, navigation, trusted input, multiple perception modes, JS eval, console/network logs, profiling, stealth, human takeover, and cookie persistence. Gaps remain around browser history (back/forward), file upload/download, drag, iframe targeting, and non-cookie storage (localStorage/auth beyond cookie snapshots), but these are minor workarounds rather than dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Stealth Chrome MCP server for AI agents providing 77 tools, perfect bot detection scores, proxy pools, encrypted sessions, and live human handoff via Cloudflare tunnel.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Umbra is the trust layer for AI-generated code. It scores any repo 0-100 with file:line evidence (security, slop, Docker-verified build/boot, and claim receipts that catch agents lying about tests), and guards agent file writes mid-stream blocking leaked keys, alg:none JWTs, and git-hook plants before they land. Tools: scan_repo, guard_content, get_score.
    3
    31 npm
    MIT
  • F
    license
    Not graded
    quality
    A
    maintenance
    Exposes a local MCP endpoint that lets AI agents and human operators drive isolated Chromium profiles — each with its own cookies, fingerprint, and proxy — through tools for navigation, clicking, typing, extraction, screenshots, JS evaluation, tabs, and cookie management. Persistent per-profile session state keeps logins and context alive across launches and across AI sessions, so agents can complete real authenticated workflows.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local MCP server that lets AI assistants drive your real, already-logged-in Chrome through a browser extension, so agents can read, click, type, navigate, screenshot, inspect network traffic, and manage cookies or storage on pages that require existing sessions. It works without opening a remote-debugging port and keeps all communication on your machine.
    1 npm
    ISC