Playwright MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Playwright MCPopen https://example.com and read the main heading"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Playwright MCP on Render
Deploy Playwright MCP on Render in one click. Get a hosted, headless-Chromium MCP server your AI tools can drive over HTTP — no local browser install, no npx on every machine.
https://github.com/user-attachments/assets/0f31c279-f2e0-431f-a854-50677bd800c5
What it does
Playwright MCP is a Model Context Protocol server that lets an LLM open a real browser, navigate, click, type, and read pages through structured accessibility snapshots (not screenshots). It normally runs locally via npx @playwright/mcp. This template runs it as a single Render web service instead, so any MCP client can connect to a shared HTTPS URL.
It's a thin wrapper over the official mcr.microsoft.com/playwright/mcp image (headless Chromium already baked in) — no source changes. The wrapper adds the flags Render needs (--headless, --no-sandbox, plus --port and --allowed-hosts from the environment) and a small bearer-token gate in front of the server, because Playwright MCP has no authentication of its own.
Authenticated by default. Playwright MCP has no auth in HTTP mode and ships an RCE-equivalent tool, so this template does not publish it directly: requests must carry
Authorization: Bearer $MCP_TOKEN, and Render generates that token for you at deploy time. Read Security to understand what that does and does not protect.
For the full tool list, config options, and client setup, see the upstream README.
Related MCP server: BrowserMCP Secure
Architecture
One Render web service runs the official Playwright MCP image behind a bearer-token gate. An MCP client speaks Streamable HTTP to /mcp over Render's TLS-terminating edge; the gate checks the token and forwards to the MCP server on loopback, which drives a headless Chromium in the same container and returns accessibility snapshots.
┌─────────────┐ HTTPS /mcp ┌────────────────────────────────────────────────┐
│ MCP client │ ──────────────► │ Render web service (Docker, standard plan) │
│ (Claude, │ + Bearer │ │
│ Cursor, …) │ token │ render-entrypoint.sh │
│ │ │ │ reads PORT, allowed hosts │
│ │ Streamable │ ▼ │
│ │ ◄────────────── │ render-auth-proxy.mjs :$PORT (public) │
└─────────────┘ snapshots │ │ 401 unless the Bearer token matches │
│ ▼ │
│ node /app/cli.js 127.0.0.1:8931 (loopback) │
│ │ │
│ ▼ │
│ headless Chromium (baked into base image) │
└────────────────────────────────────────────────┘How a deploy is assembled:
File | Role |
Blueprint. Declares the single Docker web service, its plan/region, the | |
Thin wrapper over | |
Reads | |
PID 1. Stdlib-only Node, no dependencies: rejects any request without | |
The gate's rate limit, kept separate because it is the one piece with state worth testing on its own: a fixed-window cap on failed authentications, counted across all clients. Imported by the proxy, so | |
Builds the image and checks the wrapper end to end: fails closed without | |
Documents the same knobs for running the container locally. |
Key properties:
Thin wrapper, no fork of the tool. The Playwright MCP version is pinned by the base-image tag in
Dockerfile.render; upgrades are a one-line tag bump (see Rolling Playwright MCP).No database, no disk, nothing to fill in. The one secret,
MCP_TOKEN, is generated by Render at deploy time. The browser keeps upstream's default persistent profile, so logins carry across requests for the life of the instance — convenient for a server that's yours alone, which is what this template assumes (see Configuration).Authenticated, and fails closed. The gate is added by this template, not upstream. If
MCP_TOKENis unset the container refuses to start, so there is no configuration in which the server is exposed anonymously (see Security).
Prerequisites
To deploy, you need:
A Render account — free to create; the service itself runs on the paid
standardinstance type (see Deploy).A GitHub account, to fork this repo (the Deploy button reads
render.yamlfrom a repo you own).
No API keys or third-party accounts are required. The one secret, MCP_TOKEN, is generated for you at deploy time — you only need to copy it into your MCP client (see Deploy).
To also run it locally (optional — see Run locally):
Docker with BuildKit (Docker Desktop 4.x+, or Docker Engine 23+).
Dockerfile.renderuses a# syntax=directive andCOPY --chmod, both BuildKit features.An MCP client to point at it (e.g. Claude Code, Cursor), or just
curl.
You do not need Node.js, Playwright, or a local Chromium — the base image bakes all of that in.
Deploy
Click Deploy to Render above (or fork this repo and create a new Blueprint from it).
Render reads
render.yamland provisions one Docker web service (playwright-mcp) on thestandardplan.Wait for the deploy to go live. Your server is at
https://<your-service>.onrender.com/mcp.Copy
MCP_TOKENfrom the service's Environment page in the Render Dashboard — Render generated it for you. Your MCP client must send it asAuthorization: Bearer <token>(see Using the app); without it every request gets a401.Read Security before pointing anything sensitive at it. The token is the only thing standing between the internet and code execution in this container, so treat it like a password — and tighten further if you can.
Plan sizing: headless Chromium OOMs on the free/
startertier (512 MB), so the Blueprint defaults tostandard(2 GB). Downgrade only if you've confirmed your workload fits in less.
Using the app
Point any MCP client at your service's /mcp endpoint, sending MCP_TOKEN as a bearer token. For example, with Claude Code:
claude mcp add --transport http playwright https://<your-service>.onrender.com/mcp \
--header "Authorization: Bearer <your-MCP_TOKEN>"Or add it to a client config directly:
{
"mcpServers": {
"playwright": {
"url": "https://<your-service>.onrender.com/mcp",
"headers": {
"Authorization": "Bearer <your-MCP_TOKEN>"
}
}
}
}If the client reports a 401, the header is missing or the token doesn't match the current value in the Dashboard.
Then ask your assistant to browse — e.g. "Open example.com and give me the page title and the main heading." It will call the Playwright MCP tools against your hosted browser and return the result.
Run locally
Optional — the deploy path above needs none of this. Useful if you want to change render-entrypoint.sh and see the effect before pushing.
git clone https://github.com/render-examples/playwright-mcp-render.git
cd playwright-mcp-render
cp .env.example .env # then set MCP_TOKEN, e.g. to `openssl rand -hex 32`
docker build -f Dockerfile.render -t playwright-mcp-render .
docker run --rm --env-file .env -p 10000:10000 playwright-mcp-renderOnce ready, the container prints upstream's own Listening on … and then the gate's [auth] Bearer-token gate listening … — in that order, because the gate holds the public port closed until the server behind it accepts, so the last line is the one that means the service is reachable. (The [startup] line above it prints an https:// URL — that scheme is for the deployed service; locally, use http.) Verify the server with an MCP handshake — export the same token you put in .env first, so the header below resolves:
curl -sS -X POST http://localhost:10000/mcp \
-H "Authorization: Bearer $MCP_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'You should get back a serverInfo block naming Playwright; drop the Authorization header and you should get 401 Unauthorized. Point a client at http://localhost:10000/mcp the same way you would the deployed URL.
MCP_TOKENis the one variable you must supply — the container exits immediately without it. The rest of.envis convenience: outside Render there's noRENDER_EXTERNAL_HOSTNAME, so the entrypoint already falls back toPORT=10000and--allowed-hosts *.
Prefer to skip Docker entirely? Upstream runs the same server directly: npx @playwright/mcp@latest --port 10000 — note that resolves to whatever npm publishes, not the image tag this template pins, and it has no auth gate (that's this template's addition). That path is also not what Render deploys, so verify changes in the container before you push.
Configuration
Everything is set in render.yaml; .env.example documents the same knobs for running locally.
Env var | Default | What it's for |
|
| Port the auth gate binds to; Render routes to it. |
| generated by Render | Required. Bearer token every request must present. The container refuses to start without it. Rotate by editing the value (or clicking Generate again) in the Dashboard and updating your clients. |
|
| Loopback port the MCP server listens on behind the gate. Change only if it collides with something inside the container. |
.env.example also lists PLAYWRIGHT_MCP_HOST, PLAYWRIGHT_MCP_HEADLESS, and PLAYWRIGHT_MCP_NO_SANDBOX. These matter only when you run the server directly (outside this image) — on Render, render-entrypoint.sh always passes the equivalent CLI flags, and CLI flags win, so setting them in the Render dashboard has no effect. The one exception is PLAYWRIGHT_MCP_ALLOWED_HOSTS, which the entrypoint does honor.
The entrypoint scopes the server's host check to your service's own onrender.com hostname automatically via Render's RENDER_EXTERNAL_HOSTNAME. If you add a custom domain, requests to it will be rejected by the host check until you set PLAYWRIGHT_MCP_ALLOWED_HOSTS (comma-separated, e.g. myapp.com,myapp.onrender.com; * disables the check).
Browser profile state
The entrypoint passes no profile flags, so you get Playwright MCP's default: a persistent profile on the container's filesystem (~/.cache/ms-playwright/mcp-*). Two consequences worth knowing:
Logins survive between calls — usually what you want. Authenticate once through the hosted browser and later sessions reuse the session. Every client pointed at the URL shares that one profile, so this assumes the service is yours (see Security). No Disk is attached, so the profile is wiped on restart or redeploy.
Concurrent clients can conflict. Upstream notes a persistent profile "can only be used by one browser instance at a time, so concurrent MCP clients sharing the same workspace will conflict" — so two editors on one URL may collide. Scaling past one instance also gives each instance its own profile.
To change either, edit render-entrypoint.sh:
Want | Add |
A fresh in-memory profile per session, discarded on close |
|
A profile that survives redeploys (saved logins) | a Render Disk plus |
Security
What you're actually running
Playwright MCP exposes browser_run_code_unsafe, described upstream as: "Run a Playwright code snippet. Unsafe: executes arbitrary JavaScript in the Playwright server process and is RCE-equivalent." On the pinned version it is listed under Core automation, not one of the opt-in capabilities, and --caps only enables additional capabilities (vision, pdf, devtools) — so it cannot drop this tool, and no flag excludes individual tools. Whoever can call this server can run code in your container as the container user, and reach your other Render services over the private network.
Upstream ships no authentication in HTTP mode, which is defensible when the server is npx on your laptop's loopback. On Render it gets a public URL, so this template adds the missing door.
What the template does about it
render-auth-proxy.mjs is the only thing listening on $PORT. It answers 401 to any request without Authorization: Bearer $MCP_TOKEN and forwards the rest to the MCP server, which binds to 127.0.0.1 and is never published. Specifically:
Fails closed. No
MCP_TOKEN, no start — there is deliberately no flag to disable the check, so no misconfiguration leaves the server anonymous.Generated secret, not a default.
render.yamlusesgenerateValue: true, so each service gets its own token — generated once when the service is created and stable across redeploys, so clients keep working — and there is no shared credential in this repo to leak.Constant-time comparison of SHA-256 digests, so the check doesn't leak the token a byte at a time, and a token prefix is not accepted.
Never logs the token. Rejections log method, path, and
401— nothing presented by the client.Rate-limits guessing. Failed attempts share one global budget: 10 in a minute and the rest of that window gets
429with aRetry-After, plus one log line rather than one per attempt. The budget is spent only by requests that were going to be refused anyway, so a valid token is never subject to it — the lockout can't be aimed at you, and you can always get back in while an attacker is locked out. It's deliberately not per client: this gate fronts a single shared secret, so what's worth guaranteeing is a ceiling on the total guess rate, and a per-address limit doesn't provide one — an attacker rotating source addresses just gets a fresh budget each time.Stops the token at the door. The
Authorizationheader is not forwarded to the MCP server, along with the hop-by-hop headers a proxy is required to drop. Connection upgrades (WebSocket and the like) are answered501rather than proxied, since the MCP transport never needs one.
What it does not do
This is one door, not defense in depth. It does not sandbox the RCE, cap what an authenticated caller can do, or give you per-client identity — everyone who has the token is the same principal, and the rate limit above slows guessing, not misuse of a token that already leaked. If you can, layer something stronger on top:
Restrict who can reach the service at all. Inbound IP rules scoped to your known addresses (Scale and Enterprise plans) mean a stolen token isn't usable from anywhere else.
Don't expose it publicly at all. If your MCP client is another Render service, change
type: webtotype: pservinrender.yamlto make it a private service — no public URL, strictly safer, and the token still applies. Note it gets noRENDER_EXTERNAL_HOSTNAME, so the host check falls back to*and the startup banner prints alocalhostURL; reach it over the private network.Treat the token as a password. Keep it out of shared configs and issue trackers, rotate it in the Dashboard if it may have leaked (a redeploy picks up the new value), and suspend or delete the service when you're done with it.
Watch it. The service's logs and metrics are how you'd notice use you didn't initiate;
401lines mean someone is knocking.
One consequence of that shared budget is worth knowing before you debug against it: while someone is exhausting it, a request carrying the wrong token gets 429 rather than 401. Anyone can hold it empty indefinitely — ten refused requests a minute is all it takes — so on a service that attracts background scanning this may be the normal state rather than an unusual one. If you're testing with a token that turns out to be stale (rotated in the Dashboard, or copied from an older service), the status code won't tell you that, and the fix is to check the token rather than to wait out the Retry-After. A request with the right token is unaffected either way, which is the reason this trade is acceptable: the budget can be emptied by anyone, but the lockout it produces can't be aimed at you.
The host check the entrypoint sets up (see Configuration) is a Host-header check against DNS rebinding — not access control. It does nothing to stop a direct request carrying a valid token.
Rolling Playwright MCP
The version is pinned in exactly one place: the base-image tag in Dockerfile.render. To bump, change that tag, commit, and redeploy. (runtime: docker images don't auto-deploy when a tag moves — a fresh deploy pulls the new base.)
Then re-check the two claims in Security against the new tag's upstream README: whether browser_run_code_unsafe is still a non-opt-in Core automation tool, and whether --caps still only adds capabilities. Update that section's permalink to the new tag either way — it's the only other place a version literal appears, because a permalink has to carry one.
Then re-verify the gate, since it depends on upstream's HTTP surface. npm run test:wrapper covers the gate's own logic in seconds without Docker (the failure budget, and the proxy answering 401/429/200 over a stub upstream), and ./render-smoke-test.sh builds the new image and checks it end to end (401 without the header, 429 after repeated bad tokens, a handshake with the right one, a real tool call through the SSE path, clean shutdown). CI runs both on every PR, so opening one is equivalent. If upstream ever ships real authentication, prefer it and delete render-auth-proxy.mjs — this file exists only to fill that gap.
Not a version to keep in sync: the
versionfield inpackage.json. This repo is a fork of microsoft/playwright-mcp, so that field is upstream's own npm release marker — and the deploy never uses it (Dockerfile.rendercopies onlyrender-entrypoint.sh,render-auth-proxy.mjs, andrender-auth-limiter.mjs). Expect it to differ from the image tag; leave it alone.
Based on microsoft/playwright-mcp · Deploys on Render.
Available Tools
23 toolsbrowser_clickCDestructive
Perform click on a web page
| Name | Required | Description | Default |
|---|---|---|---|
| button | No | Button to click, defaults to left | |
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element | |
| modifiers | No | Modifier keys to press | |
| doubleClick | No | Whether to perform a double click instead of a single click |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds no behavioral context beyond what the annotations already state; it doesn't note that clicking can trigger navigation, dialogs, or state changes. The destructiveHint and openWorldHint annotations are present, but the description itself contributes nothing new about side effects or requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence and is easy to scan, but it is under-specified: 'on a web page' is largely redundant for a browser tool and the sentence doesn't convey why or how the click is performed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, no usage guidance, and no behavioral notes, the description is too thin for an agent to fully understand invocation context. The parameter schema fills in target details, but important interaction semantics and when to choose this tool are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents target, button, modifiers, and doubleClick. The description adds no parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description says the tool performs a click on a web page, so the core action is clear, but it never mentions targets, snapshots, or click variants, making it generic. It also doesn't meaningfully distinguish this from the many sibling browser interaction tools beyond the name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use browser_click versus browser_hover, browser_press_key, browser_drag, or browser_select_option. No context, exclusions, or alternative tool recommendations are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_closeBDestructive
Close the page
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, and the description adds the specific affected resource ('the page'), which is useful. However, it does not disclose whether the browser session also ends, whether unsaved state is lost, or whether the operation is reversible, leaving some behavioral ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, short sentence with no filler. Every word contributes to the meaning, and the action is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter destructive action, the description plus annotations cover the core meaning. The main gap is scope ambiguity: whether 'the page' means the current tab or the entire browser, and what happens after the close. Given the simplicity of the tool, this is acceptable but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter documentation burden. The description correctly implies that no arguments are needed, and the baseline for zero-parameter tools is a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Close') and resource ('the page'), making the action clear and distinct from the sibling navigation or manipulation tools. However, it is slightly ambiguous whether it closes only the current tab or the entire browser, especially since the annotation title says 'Close browser' rather than 'Close page'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives like browser_navigate_back or browser_tabs. It does not state that this is the final cleanup action or mention prerequisites, so an agent must infer when closing the page is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_console_messagesCRead-only
Returns all console messages
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Return all console messages since the beginning of the session, not just since the last navigation. Defaults to false. | |
| level | Yes | Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to "info". | info |
| filename | No | Filename to save the console messages to. If not provided, messages are returned as text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is minimal and potentially misleading: 'all console messages' suggests no filtering, but the schema shows the tool filters by level (default info) and recency (since last navigation unless all=true). It discloses no default behavior or file-saving option, and adds no context beyond what the annotations (readOnlyHint=true) already provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no unnecessary words. It is efficient, but it only restates what the tool name implies and does not pack in distinguishing or behavioral context that would earn the highest score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, has readOnlyHint=true, and a complete input schema that explains each parameter. However, with no output schema, the description does not clarify the return format beyond the filename parameter note, and the lack of usage guidance leaves some gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters with defaults and behaviors. The main description adds no parameter-level meaning, and its use of 'all' could be confused with the `all` boolean parameter. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Returns') and resource ('console messages'), making the tool's core function clear. However, it does not differentiate from sibling tools like browser_network_requests or browser_snapshot, and the word 'all' is ambiguous about whether it means all levels or all messages since session start.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives. It does not mention sibling tools, mention prerequisites, or state exclusions, leaving the agent to infer usage purely from the tool name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_dragBDestructive
Perform drag and drop between two elements
| Name | Required | Description | Default |
|---|---|---|---|
| endTarget | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| endElement | No | Human-readable target element description used to obtain the permission to interact with the element | |
| startTarget | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| startElement | No | Human-readable source element description used to obtain the permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already communicate that this is not read-only and may be destructive. The description adds no extra behavioral context beyond the bare action, such as what the drag causes, whether elements move, whether drop events fire, or whether user permission is required for the source and target elements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler. It front-loads the action and the object, every word earns its place, and it is immediately scannable by an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple action tool, the schema and annotations cover the required parameters and safety profile, and there is no output schema to document. However, the description leaves some ambiguity around when to use this tool versus the sibling browser_drop, and it does not mention the optional permission-related element descriptions that appear in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already well-documented in the input schema. The description's phrase 'between two elements' loosely maps to startTarget and endTarget, but it does not add meaning beyond the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('drag and drop') and the resources involved ('between two elements'), so an agent can understand the tool's core function. It does not explicitly differentiate from the sibling tool browser_drop, but the compound phrase 'drag and drop' and tool name convey the full gesture.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied: an agent should use this tool when a drag-and-drop interaction between two elements is needed. However, there is no explicit when-to-use guidance, no exclusions, and no mention of alternatives such as browser_drop, browser_click, or browser_hover.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_dropADestructive
Drop files or MIME-typed data onto an element, as if dragged from outside the page. At least one of "paths" or "data" must be provided.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Data to drop, as a map of MIME type to string value (e.g. {"text/plain": "hello", "text/uri-list": "https://example.com"}). | |
| paths | No | Absolute paths to files to drop onto the element. | |
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true and readOnlyHint=false, so the description is not responsible for repeating that. It adds useful context about simulating an external drag, but does not disclose any additional behavioral details such as triggered page handlers or side effects. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler. The core action is front-loaded, and the essential constraint about paths/data is placed directly after. Every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 100% schema coverage and the annotations covering destructive behavior, the description is sufficiently complete for correct invocation. It covers the critical constraint and the simulation semantics, though it does not elaborate on edge cases like providing both paths and data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful parameter semantics beyond the schema by stating 'At least one of paths or data must be provided', which is a cross-parameter constraint not expressed in the JSON schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Drop files or MIME-typed data onto an element') and adds the key distinction 'as if dragged from outside the page', which separates it from siblings like browser_drag. It clearly identifies the resource and the mechanism.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool: when an external drag-and-drop simulation is needed. However, it does not explicitly compare against alternatives such as browser_file_upload or browser_drag, nor does it state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_evaluateBDestructive
Evaluate JavaScript expression on page or element
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element | |
| filename | No | Filename to save the result to. If not provided, result is returned as text. | |
| function | Yes | () => { /* code */ } or (element) => { /* code */ } when element is provided |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry destructiveHint=true and readOnlyHint=false, so the risk profile is partially disclosed. The description adds the behavioral nuance that evaluation can target a page or an element, but it does not explain side effects, execution context, or what happens to the page state. With annotations covering the main safety signals, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise, front-loaded sentence with no wasted words. It is minimally sufficient as a title-like summary, though it could be slightly expanded to improve other dimensions without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool that executes arbitrary JavaScript and is marked as destructive, this description is thin. It does not explain return behavior, the role of the filename parameter, or how this differs from browser_run_code_unsafe. The schema fills in parameter details, but the overall operational context remains incomplete for an agent deciding whether and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented structurally. The description adds no additional meaning beyond recognizing page or element targeting, which matches the existing schema descriptions. The baseline of 3 applies because the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Evaluate') and resource ('JavaScript expression on page or element'), making the core operation clear. It does not explicitly differentiate itself from the closely related sibling browser_run_code_unsafe, which also executes JavaScript, but it does convey that evaluation can be scoped to a page or a particular element.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use this tool versus alternatives like browser_run_code_unsafe, nor any mention of when it is appropriate to evaluate on the page versus on an element. The description implies JavaScript execution but provides no context, exclusions, or selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_file_uploadCDestructive
Upload one or multiple files
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=true, but the description adds no behavioral context beyond the act of uploading. The schema notes that omitting paths cancels the file chooser, but the description itself does not explain side effects, what gets overwritten, or how the upload interacts with the current page.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler words. It is appropriately brief for such a simple tool, though the brevity sacrifices useful usage and behavior guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema and annotations cover the core parameter and safety profile, making this minimally viable for a one-parameter tool. However, the description lacks guidance on when to use upload vs browser_drop, how the target file input is determined, and what observable effects occur, so it is not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the paths parameter is documented as absolute paths, single or multiple, and omitting it cancels the file chooser. The description does not add any semantics beyond what the schema already provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description says 'Upload one or multiple files,' giving a clear action and object with multi-file scope. It is not a tautology and is distinguishable from siblings like browser_drop, though it does not specify that this operates through the browser file chooser or how the target element is selected.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus sibling tools such as browser_drop or browser_fill_form. The description does not mention prerequisites, target element requirements, or alternatives, so the agent must infer usage from the tool name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_fill_formCDestructive
Fill multiple form fields
| Name | Required | Description | Default |
|---|---|---|---|
| fields | Yes | Fields to fill in |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal that this is a mutating operation (readOnlyHint=false, destructiveHint=true), but the description adds no behavioral context beyond the action itself. It does not mention clearing existing field values, requiring a page snapshot's target references, or what the tool returns after filling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four words and contains no filler or unnecessary repetition. The action and resource are front-loaded, making it easy to scan and understand.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although the schema is thorough, the overall definition is weak on when to use this tool among many browser interaction siblings and on behavioral expectations there is no output schema and no guidance on side effects. An agent could likely call it with a valid schema, but the description alone does not provide enough surrounding context for confident use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with detailed descriptions for target, name, type, value, and element. The description itself adds no parameter-level detail, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('fill') and resource ('multiple form fields'), clearly identifying the action. It is more informative than the title and helps distinguish it from single-interaction siblings like browser_type or browser_click, though it does not explicitly name those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use browser_fill_form versus related tools such as browser_type, browser_select_option, or browser_drop. It does not state that this tool is intended for batch form filling or mention any exclusions or prerequisites, leaving tool selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_handle_dialogCDestructive
Handle a dialog
| Name | Required | Description | Default |
|---|---|---|---|
| accept | Yes | Whether to accept the dialog. | |
| promptText | No | The text of the prompt in case of a prompt dialog. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds no behavioral transparency beyond the annotations. Annotations already indicate destructiveHint=true and readOnlyHint=false, but the description does not explain what handling a dialog actually does, what side effects occur, or how promptText is used. It discloses no additional behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short, but it earns no place because it repeats the tool name and title. This is under-specification rather than effective conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and minimal guidance, 'Handle a dialog' is not complete enough. The agent is left to infer when dialogs occur, what accepting versus dismissing means, and how promptText relates to prompt dialogs. The schema helps with parameter syntax but not operational context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so accept and promptText are already documented. The description adds no parameter-level detail, which is acceptable under the baseline for full schema coverage, but it also does not clarify operational nuances such as accept=false meaning dismiss.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Handle a dialog' simply restates the tool name and title, making it a tautology. It names the resource but uses the vague verb 'handle' without specifying whether the dialog is accepted, dismissed, or otherwise acted upon.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool, such as when a browser JavaScript dialog appears or that the dialog must be handled before continuing browser interaction. It also does not mention any alternatives or conditions for using accept versus promptText.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_hoverBDestructive
Hover over element on page
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and destructiveHint=true, so the safety profile is provided outside the description. The description adds no extra behavioral context such as the fact that hovering may trigger UI state changes without clicking, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with no filler or repetition. It is compact but not structured enough to convey usage context; still, for a simple action primitive, the brevity is appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-action tool with fully documented parameters and annotations, the description is minimally viable. However, with no output schema and no guidance on when hover is the right sibling tool, the description is slightly incomplete for an agent deciding among many browser interaction tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with target and element both already described in the schema. The tool description itself adds no parameter-level meaning, so it relies on the schema to convey semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('hover') and a resource ('element on page'), which distinguishes it from siblings like click, type, and drag. It does not explicitly contrast itself with related tools, but the action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use hover versus alternatives such as click, drop, or press_key. There is no mention of use cases like revealing tooltips or hover menus, nor any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_network_requestARead-only
Returns full details (headers and body) of a single network request, or a single part if part is set. Use the number from browser_network_requests.
| Name | Required | Description | Default |
|---|---|---|---|
| part | No | Return only this part of the request. Omit to return full details. | |
| index | Yes | 1-based index of the request, as printed by browser_network_requests. | |
| filename | No | Filename to save the result to. If not provided, output is returned as text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral detail by stating it returns headers and body, and that it can return a single part when `part` is set. However, it does not disclose behavior around invalid indices, file output, or other edge cases, which keeps this at a moderate score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two compact sentences with no filler. The core behavior is front-loaded, and the second sentence provides the essential contextual link to the sibling listing tool. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity retrieval tool, the description is complete: it states what is returned, how to select a specific request, and how to narrow to a single part. The rich parameter schema covers remaining invocation details, and the absence of an output schema is mitigated by the explicit description of the return content.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds a small amount of contextual meaning by linking `index` to browser_network_requests output, but this mostly repeats what the schema already says. A baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns full details of a single network request, and explicitly contrasts this with the list-oriented sibling browser_network_requests. The verb 'Returns' plus the resource ('single network request') and the optional 'part' selector make the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Use the number from browser_network_requests' gives clear workflow context: first list requests, then use this tool with the returned index. It does not explicitly state 'do not use this for listing all requests,' but the differentiation from the sibling is strongly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_network_requestsARead-only
Returns a numbered list of network requests since loading the page. Use browser_network_request with the number to get full details.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | Only return requests whose URL matches this regexp (e.g. "/api/.*user"). | |
| static | Yes | Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false. | |
| filename | No | Filename to save the network requests to. If not provided, requests are returned as text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds useful behavioral context by stating the list is 'since loading the page' and that it is a numbered summary, which helps the agent understand what it will receive before calling the sibling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. The primary action is front-loaded, and the second sentence provides a clear next-step pointer to the sibling tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool with full schema coverage and no output schema, the description is complete. It explains the return format (numbered list), the time scope (since loading the page), and how to obtain full details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters (filter, static, filename) are already fully documented. The description does not add parameter-specific meaning beyond the schema, which is acceptable given the complete schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Returns'), a clear resource ('network requests'), and a scope qualifier ('since loading the page'). It also distinguishes itself from the sibling browser_network_request by explaining that the sibling provides full details using the item number.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear contextual guidance: this tool returns a numbered list, and browser_network_request should be used next with the number for full details. It does not explicitly state when not to use this tool, but the workflow is obvious and complementary to the sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_press_keyBDestructive
Press a key on the keyboard
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Name of the key to press or a character to generate, such as `ArrowLeft` or `a` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag the operation as destructive (destructiveHint=true) and open-world (openWorldHint=true), and the description does not contradict those signals. However, the description adds no extra behavioral context, such as potential shortcuts, focus requirements, or navigation side effects, so it earns only a baseline score thanks to the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no unnecessary elaboration. It is slightly redundant with the tool title, but it is compact and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with complete schema coverage and annotations indicating destructive/open-world behavior, the description is mostly sufficient for correct invocation. The main missing piece is explicit guidance on when to prefer it over sibling input tools, which is already penalized under usage guidelines.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the single required parameter, key, is documented with examples like `ArrowLeft` and `a`. The tool description adds no additional parameter meaning, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('press') on a specific target ('a key'), so an agent can tell this is a keyboard-input tool. It does not explicitly distinguish pressing a key from typing with browser_type, but the key/character parameter and tool name make the core purpose reasonably clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus browser_type, browser_click, or browser_fill_form. No use cases, exclusions, or alternatives are mentioned, leaving the agent to infer the tool's role from its name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_resizeCDestructive
Resize the browser window
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | Width of the browser window | |
| height | Yes | Height of the browser window |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true and readOnlyHint=false. The description adds no behavioral context beyond that, such as whether the resize affects subsequent navigation, whether it changes the viewport or the browser chrome, or whether it is reversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short and front-loaded, with no obvious filler. However, it essentially restates the tool name and title, providing no additional structural benefit or useful elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter operation, the description plus schema is minimally adequate for invoking the tool. But it omits behavioral clarifications and usage context that would make it truly complete, especially given the destructive hint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with clear descriptions for width and height. The description itself adds no parameter-specific meaning, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Uses a specific verb ('resize') and a clear object ('browser window'), and the operation is distinct from the sibling browser_* tools. However, it does not explicitly differentiate itself or clarify whether it resizes the viewport or the entire OS window.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. The unique name implies a use case, but the description itself leaves usage decisions entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_run_code_unsafeADestructive
Run a Playwright code snippet. Unsafe: executes arbitrary JavaScript in the Playwright server process and is RCE-equivalent.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction. For example: `async (page) => { await page.getByRole('button', { name: 'Submit' }).click(); return await page.title(); }` | |
| filename | No | Load code from the specified file. If both code and filename are provided, code will be ignored. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive and read-write behavior, but the description adds the critical, non-obvious detail that execution happens in the Playwright server process and is RCE-equivalent. This is essential risk context beyond what the annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences with no filler. The safety warning is front-loaded immediately after the action, and every phrase adds meaningful signal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema plus the unsafe warning cover most invocation details: how code is called, how filename works, and what risk is involved. The main gaps are not explicitly stating that code or filename is practically required and not describing the return behavior, but the schema example makes the return pattern inferable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% parameter coverage, including the code invocation signature, the page argument, and filename precedence. The description itself adds no significant parameter-level meaning, so it stays at the schema-driven baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The lead sentence identifies a specific action and resource: 'Run a Playwright code snippet.' The unsafe clause further clarifies the execution context as arbitrary JavaScript in the Playwright server process, which is RCE-equivalent. It is clear, though it does not explicitly differentiate itself from the similarly code-oriented sibling browser_evaluate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies that this tool is for arbitrary Playwright code that specialized browser tools may not cover, especially with the strong 'Unsafe' and 'RCE-equivalent' warning. However, it never explicitly names a safer alternative or states when-not-to-use, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_select_optionCDestructive
Select an option in a dropdown
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| values | Yes | Array of values to select in the dropdown. This can be a single value or multiple values. | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the operation as non-read-only and destructive, and the description adds no extra behavioral context. It does not mention multi-select behavior, the permission flow behind the 'element' parameter, or any side effects on page state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler. It is efficient, though the brevity leaves no room for useful context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema covers the parameters, and annotations cover the destructive nature, so the essential calling contract is present. However, the description omits multi-select support and any guidance for choosing this tool over browser_fill_form, leaving the context minimally viable but incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already documented. The description adds little beyond the action itself, and it does not clarify the relationship between 'values' and multi-select, so it earns the baseline rather than more.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a clear verb ('select') and resource ('an option in a dropdown'), so an agent can tell it is about dropdown selection. It does not explicitly distinguish from sibling tools like browser_fill_form or browser_type, which could also affect form controls.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to reach for this tool instead of alternatives. The description only states the action, leaving the agent to infer conditions such as 'use when the target is a native <select> element'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_snapshotBRead-only
Capture accessibility snapshot of the current page, this is better than screenshot
| Name | Required | Description | Default |
|---|---|---|---|
| boxes | No | Include each element's bounding box as [box=x,y,width,height] in the snapshot. Coordinates are viewport-relative, in CSS pixels (Element.getBoundingClientRect) | |
| depth | No | Limit the depth of the snapshot tree | |
| target | No | Exact target element reference from the page snapshot, or a unique element selector | |
| filename | No | Save snapshot to markdown file instead of returning it in the response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds the behavioral framing of an 'accessibility snapshot' and a quality comparison to screenshots, but it does not disclose what the output actually contains, how large it can be, or that it returns element references (which is only revealed in the parameter schema).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler and the core action is front-loaded. The comparative phrase 'this is better than screenshot' is concise but slightly vague, preventing a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description is responsible for clarifying what the tool returns. It only says 'snapshot' without stating it is a textual or markdown accessibility tree; the schema hints at this via the filename and target parameters, but the description alone under-specifies the return format and practical scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, all four parameters are already well-documented in the schema. The description itself adds no additional parameter-level meaning, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('Capture') and the resource ('accessibility snapshot of the current page'), making the tool's basic function evident. It also gestures at differentiation by claiming it is 'better than screenshot', which separates it from browser_take_screenshot, though it does not define what an accessibility snapshot is.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage guidance is the implied preference for this tool over screenshots ('this is better than screenshot'), which hints at using it when accessibility/structure is needed. However, it does not explicitly state when to prefer this over other siblings like browser_evaluate, nor does it give any exclusions or conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_tabsBDestructive
List, create, close, or select a browser tab.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to navigate to in the new tab, used for new. | |
| index | No | Tab index, used for close/select. If omitted for close, current tab is closed. | |
| action | Yes | Operation to perform |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive and non-read-only behavior, but the description adds little beyond restating the action verbs. It does not explain side effects such as which tab is closed when index is omitted, whether select changes focus, or what happens when creating a tab without a URL. Those details live in the schema, not in the description, so the description itself does not enrich behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that lists the four supported operations concisely. It is front-loaded and contains no filler, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The combination of the description, action enum, and parameter descriptions is adequate for basic calls. However, with no output schema, the tool does not disclose what 'list' returns, and there is no guidance about behavior when required parameters are omitted. This leaves some gaps for an agent deciding how to interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter already has a clear explanation. The description does not add extra semantic detail beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource ('browser tab') and enumerates the exact operations ('List, create, close, or select'), which aligns with the action enum and distinguishes this tool from browser-level siblings like browser_navigate or browser_close. This leaves little ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given for when to use this tool rather than an alternative. For example, it does not mention browser_close as the sibling for closing the browser itself, or browser_navigate for navigation. The intended usage is only implied by the tool name and the action enum.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_take_screenshotARead-only
Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Image format for the screenshot. Default is png. | png |
| scale | Yes | Image resolution scale. "css" produces a screenshot sized in CSS pixels (smaller, consistent across devices). "device" produces a high-resolution screenshot using device pixels (larger, accounts for the device pixel ratio). Default is css. | css |
| target | No | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element | |
| filename | No | File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified. Prefer relative file names to stay within the output directory. | |
| fullPage | No | When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds a non-obvious behavioral constraint: the screenshot is observational only and cannot serve as a basis for interaction. It does not describe what the tool returns, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences: the first states the core purpose, and the second gives a critical usage caveat. There is no filler, and the most important distinction from browser_snapshot is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 100% schema coverage, annotations covering the read-only/non-destructive nature, and a clear sibling alternative, the description is largely complete for correct selection and invocation. The only minor gap is that, with no output schema, it does not state whether the result is image data, a saved file path, or something else.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and parameters such as type, scale, filename, and fullPage are already well documented in the input schema. The description itself adds no meaningful parameter-level detail, so it meets the baseline for fully covered schemas without adding extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Take a screenshot of the current page.' It also differentiates itself from the sibling browser_snapshot by noting that screenshots cannot be used to drive actions, so an agent can select the correct tool without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool (need a screenshot of the current page) and provides a clear exclusion: you cannot perform actions based on the screenshot. It names browser_snapshot as the alternative for action-oriented use, giving the agent direct routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_typeCDestructive
Type text into editable element
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to type into the element | |
| slowly | No | Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once. | |
| submit | No | Whether to submit entered text (press Enter after) | |
| target | Yes | Exact target element reference from the page snapshot, or a unique element selector | |
| element | No | Human-readable element description used to obtain permission to interact with the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate readOnlyHint=false, openWorldHint=true, and destructiveHint=true, so the risk profile is known. The description adds no behavioral context beyond what the annotations provide, such as effects on the page, timing, or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely brief and front-loaded, with no wasted words. It is efficient, though so minimal that it misses opportunities to convey usage or behavioral context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, open-world tool with five parameters and no output schema, the description is underspecified. It does not mention when to type vs fill a form, whether to use selectors or snapshot refs, or any cautions about side effects, leaving the agent under-informed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter already has a clear meaning in the schema. The description itself does not add any parameter-level semantics beyond what the schema provides, which meets the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Type') and resource ('editable element'), making the core action clear. However, it does not distinguish this from sibling tools like browser_fill_form or browser_press_key, so it does not fully disambiguate the tool's unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives such as browser_fill_form or browser_press_key. The description implies a general typing action but does not state when it should be preferred or when a sibling would be better.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_wait_forBRead-only
Wait for text to appear or disappear or a specified time to pass
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | The text to wait for | |
| time | No | The time to wait in seconds | |
| textGone | No | The text to wait for to disappear |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish that this is a safe, read-only, non-destructive operation, and the description adds the core condition semantics. However, it does not disclose what happens if the target text never appears, whether the wait can time out, or whether text, textGone, and time are mutually exclusive or combinable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler or repeated information. It communicates the essential behavior immediately and is easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the schema covers its parameters, but the description leaves important edge cases unaddressed: all parameters are optional, and the description does not clarify what happens when no arguments are provided or when multiple arguments are given. There is also no output schema, so the return behavior is unknown, though this is less critical for a wait operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters are already described in the input schema with 100% coverage, so the baseline is 3. The description loosely maps text to appearing, textGone to disappearing, and time to elapsed seconds, but it does not add details about parameter combinations, precedence, or valid ranges.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete action—waiting—and defines three target conditions: text appearing, text disappearing, or a specified time passing. This is enough to tell the tool apart from the sibling browser tools, none of which are wait operations, though it does not explicitly contrast with any sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives, nor any mention of typical scenarios such as waiting after navigation or before taking a snapshot. The intended usage is left entirely to inference from the name and description.
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. Dates show when Glama detected each change.
23 tool updates
v0.0.77- First observed
browser_click - First observed
browser_close - First observed
browser_console_messages - First observed
browser_drag - First observed
browser_drop - First observed
browser_evaluate - First observed
browser_file_upload - First observed
browser_fill_form - First observed
browser_handle_dialog - First observed
browser_hover - First observed
browser_navigate - First observed
browser_navigate_back - First observed
browser_network_request - First observed
browser_network_requests - First observed
browser_press_key - First observed
browser_resize - First observed
browser_run_code_unsafe - First observed
browser_select_option - First observed
browser_snapshot - First observed
browser_tabs - First observed
browser_take_screenshot - First observed
browser_type - First observed
browser_wait_for
TDQS
Each tool maps to a distinct browser action or state source, and the descriptions generally make boundaries clear. The only mild friction is between browser_type, browser_fill_form, and browser_evaluate, but their usage contexts differ enough to avoid serious misselection.
All tools share a consistent browser_ prefix and snake_case style, which gives the set a predictable feel. A few noun-style tools like browser_tabs, browser_console_messages, and browser_network_requests break the otherwise dominant action-focused pattern, but the deviation is minor.
At 23 tools, the surface feels heavy and sits in the 16-25 range that reads as over-scoped. The browser-automation domain is broad enough that most tools justify their existence, but some consolidation might improve the set's overall tightness.
The surface covers the major browser workflow: navigation, interaction, form filling, waiting, screenshots, snapshots, console/network inspection, dialogs, tabs, and file upload. Minor gaps like reload, forward navigation, and cookie/storage management remain, but agents can work around them with navigate or browser_evaluate.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.
Deploy AI-generated HTML/CSS/JS to instant public HTTPS URLs from any MCP-compatible agent.
Give any MCP-compatible AI assistant a builder for live, hosted web tools and workflows.
Hosted MCP for creating, checking, deploying, and hosting static sites for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA browser automation MCP server hosted on Vercel that enables AI agents to perform web interactions like clicking, typing, and capturing screenshots via Browserless.io. It supports persistent session management and Basic authentication for seamless navigation across protected sites.536Apache 2.0
- AlicenseNot gradedqualityCmaintenanceSecurity-hardened MCP server that gives AI assistants full control over your real browser session, supporting 36 tools for navigation, data extraction, monitoring, and more.MIT
- AlicenseAqualityDmaintenanceMCP server that lets AI assistants browse the web through your real Chrome with your cookies, sessions, and fingerprint, avoiding bot detection and CAPTCHAs. Enables web browsing, content extraction, and multi-step workflows via persistent tabs.1563MIT
- AlicenseAqualityBmaintenanceMCP server that gives AI coding assistants direct access to the browser — navigate, click, fill forms, run JavaScript, take screenshots, and read page content.11231MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kurtzi9/playwright-mcp-render-mto6ljjz'
If you have feedback or need assistance with the MCP directory API, please join our Discord server