Argus QA MCP
Payment safety guard that blocks requests to Adyen live payment APIs during QA sessions.
Can deliver QA reports by email through Amazon SES SMTP.
Payment safety guard that blocks requests to Braintree production payment APIs during QA sessions.
Sends assessment-finished notifications to a Discord incoming webhook.
Can deliver QA reports by email through Gmail SMTP using configured credentials.
Payment safety guard that blocks requests to PayPal live REST APIs during QA sessions.
Can deliver QA reports by email through SendGrid SMTP.
Sends assessment-finished notifications to a Slack incoming webhook.
Payment safety guard that detects Stripe live keys and blocks live payment API traffic during QA sessions, while allowing test and sandbox modes.
Sends assessment-finished notifications to a Zapier webhook or other JSON-accepting automation endpoint.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Argus QA MCPrecord a login test, assert the welcome message shows"
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.
Argus QA MCP
Let Claude (or any MCP-capable AI agent) QA-test your web app, and leave evidence behind.
Website: https://rileyhall99.github.io/argus-qa-mcp/
Argus is a Model Context Protocol server that gives an AI agent a real Chromium browser through Playwright, plus the things you need to trust its results:
Recordings for review: every session can produce a video, a Playwright trace (DOM snapshots, network and console for each step) and an HTML report of every action the agent took.
Real test verdicts:
assert_text/assert_visiblereturn PASS or FAIL, and the report tallies them.Network mocking: simulate API errors, payment declines, outages and slow responses without touching your backend.
Safety guards: refuses to enter card details on pages using a live payment environment, blocks live payment API traffic, optionally restricts which sites the agent may visit, and masks passwords and card numbers in recordings.

Quick start
Requires Node.js 22+.
1. Install the browser (once):
npx playwright install chromiumOr skip this and use your installed Google Chrome by setting ARGUS_BROWSER_CHANNEL=chrome (see Configuration).
2. Add Argus to your client.
Claude Code:
claude mcp add argus -- npx -y github:RileyHall99/argus-qa-mcpClaude Desktop: add this to claude_desktop_config.json (on Windows %APPDATA%\Claude\, on macOS ~/Library/Application Support/Claude/) and restart:
{
"mcpServers": {
"argus": {
"command": "npx",
"args": ["-y", "github:RileyHall99/argus-qa-mcp"]
}
}
}3. Ask for a test:
Start a recording called "login flow". Go to https://the-internet.herokuapp.com/login, log in as tomsmith / SuperSecretPassword!, assert that "You logged into a secure area!" is shown, report any console errors, then stop the recording and suggest a fix for anything that failed.
Argus writes the recording to ~/argus-qa/recordings/<date>_login-flow/. Open report.html to review it.
Related MCP server: AI Web Tester
Tools
Tool | What it does |
| Open a URL; returns status code, final URL and title. Resets the console and network logs. |
| Accessibility tree of the page (including iframes) with |
| Click an element; waits for any navigation it triggers. |
| Clear and fill a field. Password and card values are masked in recordings. |
| Choose option(s) in a |
| Press a key or chord ( |
| Hover an element (menus, tooltips). |
| Wait for an element or text to become visible, hidden, attached or detached. |
| Save a PNG (viewport or full page) and optionally return it. |
| PASS if text is visible on the page or in an element, otherwise FAIL with the actual text. Optional |
| PASS if an element is visible (or hidden), otherwise FAIL. Optional |
| Console errors, uncaught exceptions, failed requests, HTTP errors and guard blocks, deduplicated, optionally first-party only. |
| The page's HTTP requests with status, timing, failures and mock hits. |
| Answer matching requests with a canned response, a network error or a delay. |
| Remove one mock or all of them. |
| Start recording a trace, an optional video and the action log. |
| Save the recording and report; returns the verdict, failures (with screenshots and video times) and paths. |
| Add the agent's diagnosis and suggested fix for a failed step to the report, tagged as an app, test or environment fix. |
Element tools accept a frame parameter (an iframe selector, or a list for nested iframes), though aria-ref selectors reach into iframes without it.
When a step fails, Argus explains it in plain language instead of returning Playwright's raw output, e.g. "Element is covered: "#pay" was found, but another element is on top of it: <div class="cookie-banner">. Try: close the overlay first." It recognizes missing, hidden, disabled and covered elements, stale aria-refs, bad selectors, dropdown and field mismatches, wait and page-load timeouts, network errors (DNS, refused connections, certificates) and guard blocks.
Configuration
All settings are environment variables, set in your client's MCP config ("env": { ... }, or -e NAME=value with claude mcp add).
Variable | Default | Purpose |
|
|
|
| (bundled Chromium) |
|
| (any) | Comma-separated hosts the agent may open as pages, e.g. |
|
|
|
|
| Where recordings are written. |
|
| Where screenshots are written. |
Email and notifications (see Delivering reports):
Variable | Default | Purpose |
| (off) | Comma-separated recipients of every report, e.g. |
|
| Sender address. |
| — / | Your SMTP server (Gmail, Microsoft 365, SendGrid, Amazon SES, Postmark, ...). |
| — | SMTP login (for Gmail, an app password). |
|
| Implicit TLS. Otherwise STARTTLS is required, except to localhost. |
|
| How long to wait for the agent's suggested fixes before emailing anyway. |
|
| Attach the screen recording when it fits. |
|
| Size limit for the email; videos that don't fit are left out. |
| (off) | URL notified when an assessment finishes: a Slack or Discord incoming webhook, or any endpoint (Teams/Power Automate, Zapier, your own API) that accepts JSON. |
Safety model
Argus is meant for testing sites you own or are authorized to test, ideally staging environments with test payment credentials.
Guard | Behavior |
Payment guard (always on) | Blocks requests that use Stripe live keys ( |
Host allowlist (opt-in) | With |
Secret masking | Values typed into password and payment-card fields are replaced with |
Fixed recipients | Reports are emailed and notifications sent only to the addresses and webhook in the server's environment, never to anything an agent supplies. |
Limits you should know about:
The Playwright trace (
trace.zip) and the video still contain typed values (card numbers are visible on screen in the video). Treat recordings as sensitive. The video is emailed with the report unlessARGUS_EMAIL_ATTACH_VIDEO=false, so use test card numbers.The payment guard recognizes Stripe, Adyen, Braintree and PayPal only. It can't detect other providers, or a backend that charges cards server-side with its own secret key. It is a safety net, not proof that a site is in test mode.
firstPartyOnlycompares the last two labels of the host name, so it treats e.g.a.co.ukandb.co.ukas the same site.
Recordings
start_recording → (test steps) → stop_recording produces:
~/argus-qa/recordings/2026-10-24_22-43-42_login-flow/
├── report.html # verdict, test results, explained errors, website errors, video, screenshots, full log
├── trace.zip # open with: npx playwright show-trace trace.zip (or drag onto trace.playwright.dev)
├── video.webm
├── actions.json # machine-readable log of every tool call
├── failures/ # automatic screenshot of the page at each failed check or step
└── screenshots/ # screenshots taken with take_screenshotThe report is headed with the website tested: its name (the home page's title, or the brand part its page titles share, such as "Acme Shop" from "Log in | Acme Shop") and its address, followed by the test run's name and times. stop_recording returns the same as site.
It opens with a PASSED / FAILED verdict (failed if any check fails or any step errors), then:
Test results: every
assert_text/assert_visiblecheck with PASS or FAIL, the page it ran on, and for failures the expected-vs-actual detail.Errors during the run: each failed step with what went wrong, why, and what to try.
Errors from the website: console errors, uncaught exceptions and failed requests the site produced during the run, collected automatically and de-duplicated.
The report uses the Argus theme: a branded header bar with the verdict, light or dark to match the viewer's system setting, and always light when printed. It is a single self-contained file with no external fonts or scripts, so it works offline and sends nothing anywhere.
Every section can be hidden: click its heading, or use Show all / Hide all sections at the top. A hidden section's heading still shows a count (e.g. Errors from the website · 11 errors). Hidden sections are left out when the report is printed or saved as PDF, so you can share a trimmed version.
Every failure comes with evidence: a screenshot of the page at the moment it failed, shown beside the explanation (click it for full size), and an approximate video timestamp such as "▶ 0:12 in video". Clicking it jumps the embedded player to just before the failure. Password and card fields are blacked out in failure screenshots.
stop_recording returns the same verdict, failed checks and step errors, each with its screenshot path and video time, so the agent can summarize the outcome directly.
The agent's suggested fixes. When something failed, stop_recording asks the agent to call suggest_fix for each failed step. The agent's diagnosis and fix then appear in an AI agent's suggested fix column of the test results, and on each error card, tagged Fix in the app (a real bug), Fix in the test (wrong selector or expectation) or Fix the environment (e.g. server down). This is separate from Argus's built-in Try: hints. The report is rewritten after each suggestion, so this works after the recording has stopped, and each suggest_fix reply lists the failures still without one.
Delivering reports
When the agent runs on a server the client can't access, Argus can deliver each recording itself:
Notification when the assessment finishes. As soon as
stop_recordingruns, Argus posts toARGUS_NOTIFY_WEBHOOK. Slack gets the message astext, Discord ascontent, and any other URL gets JSON withevent: "assessment.finished", the verdict, site, counts and failed checks.The report by email. Argus emails
ARGUS_EMAIL_TOa branded summary of what failed, with each failure's explanation and the agent's suggested fix. It attachesreport.htmland the video. The attached report is a single file with screenshots built in, so it opens anywhere.A run where nothing failed is emailed right away.
A run with failures is emailed once the agent has called
suggest_fixfor every failure, so the client gets the fixes too. If that doesn't happen withinARGUS_EMAIL_WAIT_SECONDS, it is sent anyway. It is also sent when the next recording starts or the client disconnects.
stop_recording and suggest_fix report what was sent (or why not) under delivery.
Recipients and the webhook come only from the server's configuration. No tool takes an address, so a page under test can't trick the agent into sending the report elsewhere. The Playwright trace is never emailed, because it holds every typed value.
claude mcp add argus \
-e ARGUS_EMAIL_TO=client@acme.com \
-e ARGUS_SMTP_HOST=smtp.sendgrid.net -e ARGUS_SMTP_USER=apikey -e ARGUS_SMTP_PASS=SG.xxxx \
-e ARGUS_EMAIL_FROM=qa@yourco.com \
-e ARGUS_NOTIFY_WEBHOOK=https://hooks.slack.com/services/T000/B000/XXXX \
-- npx -y github:RileyHall99/argus-qa-mcpStarting a recording with video reloads the current page into a new browser context. Cookies, localStorage and the URL are kept; unsaved in-page state is not. Use video: false to record just the trace without a reload.
Development
npm install
npx playwright install chromium
npm run build # compile src/ to dist/
npm run typecheck # strict type-check without emitting
npm run dev # run the server from source with tsxTo try a local build in Claude Code: claude mcp add argus-dev -- node /path/to/argus-qa-mcp/dist/index.js.
License
Available Tools
18 toolsassert_textAssert textARead-only
Test assertion: PASS if the text is visible on the page (or inside the element matched by selector) within the timeout, otherwise FAIL (isError) with the text that was actually there.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Expected text | |
| exact | No | Require the whole text to match instead of a substring | |
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| label | No | Name for this check in the test report, e.g. "Login shows welcome message" | |
| timeout | No | Timeout in milliseconds | |
| selector | No | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real value beyond that: it defines the exact outcome (PASS vs FAIL/isError) and discloses that the error surfaces the text actually found, which is critical for an agent interpreting a failed assertion.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the PASS condition and immediately followed by the FAIL semantics. Zero filler.
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?
Six parameters with full schema descriptions and no output schema; the description covers the critical return semantics (isError plus actual text) so an agent can interpret results. Minor gaps remain around selector-scoped failure messaging and iframe interplay, but the schema covers those adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds semantics beyond the schema: it clarifies that the assertion can be scoped to an element matched by selector and that the timeout governs the wait. It leaves the exact/substring distinction and frame handling entirely to the schema, hence 4 rather than 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Test assertion' on text visibility) and states the full pass/fail semantic explicitly. It does not, however, differentiate itself from the sibling assert_visible or explain why one would assert text rather than element visibility, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It conveys implied usage (you're asserting expected text after some navigation/action) and the timeout/failure behavior, but gives no explicit when-to-use guidance versus assert_visible or wait_for, nor any exclusions. Context is inferable but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assert_visibleAssert visibleARead-only
Test assertion: PASS if the element is visible (or, with visible=false, hidden/absent) within the timeout, otherwise FAIL (isError).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| label | No | Name for this check in the test report, e.g. "Login shows welcome message" | |
| timeout | No | Timeout in milliseconds | |
| visible | No | false asserts the element is hidden or absent | |
| selector | Yes | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavioral context beyond the annotations: the PASS/FAIL outcome model, the timeout window, and critically that failure surfaces as isError. That failure-signaling detail is valuable and not in 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?
A single, front-loaded sentence that delivers the core semantics (pass condition, the visible=false inversion, timeout, fail signaling) with zero filler. The parenthetical is well-used to pack the edge case efficiently.
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 single-assertion tool with full annotations and a 100%-covered schema, the description conveys everything needed to invoke it correctly, including the failure mode. No output schema exists but the description states the return semantics (PASS / isError). Minor absence of explicit 'when to use vs wait_for' keeps it just under top marks.
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 parameters (frame, label, timeout, visible, selector) are already documented in the schema itself. The description restates the visible=false inversion behavior and timeout, which mirrors the schema rather than adding new syntax or edge-case meaning. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it asserts element visibility, with pass/fail outcomes spelled out. It's clearly distinguishable from the sibling assert_text (which checks text content) and wait_for (which just waits). An agent can tell exactly what this does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Test assertion' framing implies this belongs in a test/verification context, contrasted implicitly against the action tools (click, fill) in the sibling list. However, it never explicitly says when to prefer this over wait_for or assert_text, nor any exclusions. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_mocksClear mocksA
Remove one mock by id, or all mocks when no id is given. Returns the mocks still active and their hit counts.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Mock id returned by mock_route, e.g. "mock-1" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, and the description adds the critical behavioral detail that omitting the id removes ALL mocks, plus what the call returns. It stops short of warning that removal is irreversible or that active mocks will start hitting the real network again.
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 sentences, both load-bearing: the first covers operation and its branching behavior, the second covers the return value. Zero padding and the destructive default 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 no output schema, the description correctly compensates by naming the return value (remaining mocks and hit counts). For a one-parameter tool this is nearly complete; only irreversibility and post-clear effects are unaddressed.
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% and the sole parameter already documents the mock id format, so baseline is 3. The description still adds value by explaining the semantic of omitting the optional id entirely (clear all), which the schema does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (remove) and resource (mock), and precisely distinguishes the two modes: single mock by id vs. all mocks when no id is given. It does not explicitly name the sibling mock_route as its complement, but the operation itself 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 with-id vs. no-id conditional gives clear invocation semantics, and cleanup after mocking is implied. However, it never states when cleanup is warranted, that the no-id form is a broad wipe, or how it relates to mock_route beyond the schema's reference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
click_elementClick elementA
Click the first element matching a selector. Waits for any navigation the click triggers. Note "text=" is a case-insensitive substring match against any element (headings included); prefer aria-ref from get_page_snapshot or scoped selectors like button:has-text("Login").
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| timeout | No | Timeout in milliseconds | |
| selector | Yes | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint=false and openWorldHint=true, so the description only has to add context. It does so well by disclosing that the tool waits for navigation triggered by the click, and by warning that text= may match any element as a case-insensitive substring; still, it omits what happens on timeout or on no match.
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 sentences, with the action and its navigation-waiting side effect front-loaded, followed by a single caveat about selectors. Nothing is redundant.
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 3 parameters, 100% schema coverage, and no output schema, the description covers the main behavior an agent needs: matching semantics, navigation waiting, and selector preference. The only gaps are error behavior when no element matches and whether clicking scrolls the element into view.
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, and the description adds real meaning beyond the schema: it says aria-ref selectors also reach into iframes, so the frame parameter is often unnecessary, and it warns about substring matching. It does not describe how the frame list is ordered, or how timeout interacts with navigation waiting.
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?
It states a specific verb and resource — 'Click the first element matching a selector' — and the word 'first' usefully scopes the behavior when several elements match. It does not explicitly contrast itself with sibling action tools such as hover_element or fill_input, but the click semantics are 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?
It gives concrete selector guidance that changes how the tool should be called: prefer aria-ref from get_page_snapshot, and fall back to scoped selectors such as button:has-text("Login") rather than bare text=. It states no exclusion conditions (for example, when to use hover_element or press_key instead), so the guidance is contextual rather than complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_inputFill inputA
Clear an input, textarea or contenteditable element and fill it with text. Values typed into password and payment-card fields are masked in recordings. Card fields are refused if the page uses a LIVE payment environment; use the provider's test mode and test cards (e.g. Stripe 4242 4242 4242 4242).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to enter (an empty string just clears the field) | |
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| timeout | No | Timeout in milliseconds | |
| selector | Yes | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint=false and openWorldHint=true annotations by disclosing that existing content is destroyed first, that password and card values are masked in recordings, and that live payment environments cause an outright refusal with a suggested workaround. These are exactly the side-effect and failure-mode facts an agent cannot infer from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action, then the privacy/masking behavior, then the payment-environment restriction. No filler and no repetition of name or title.
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 mutating open-world tool with no output schema, the description covers destructive clearing, credential masking and a hard refusal case. The one meaningful omission is whether input/change/keyboard events are dispatched, which affects subsequent assertions and form submission in an automation 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%, with selector, text, frame and timeout all documented inline, including the note that an empty string clears the field. The description adds no further parameter-level meaning, which is acceptable given the schema already carries the load, hence the 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?
States a specific verb pair (clear + fill) and a precise resource set (input, textarea, contenteditable), which cleanly separates it from siblings like click_element, select_option and press_key. The clear-then-fill semantic is stated up front rather than implied.
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?
Provides concrete when-to-use guidance for a contested scenario: card fields are refused on LIVE payment pages, so use the provider's test mode with test cards. It stops short of naming when to prefer siblings (e.g. select_option for dropdowns, click_element for submission), so the element-selection guidance is inferred rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_console_errorsGet console errorsARead-only
Return JavaScript console errors, uncaught exceptions, failed network requests, HTTP >= 400 responses and guard blocks recorded since the last navigate_url. Chrome's duplicate "Failed to load resource" messages are merged into the matching network entry.
| Name | Required | Description | Default |
|---|---|---|---|
| firstPartyOnly | No | Hide entries whose URL belongs to another site (analytics, ads, CDNs) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered. The description adds non-obvious behavior: the accumulation window resets at each navigate_url, and Chrome's duplicate 'Failed to load resource' messages are merged into the matching network entry — a deduplication detail an agent could not predict and that affects how it interprets result counts.
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 sentences, both front-loaded with the return contents first and the dedup caveat second. Every clause carries information; no filler or restatement of the tool name.
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-required-param read tool with annotations and a fully documented schema, the description covers what is collected, the time window, and dedup semantics. It stops short of describing the per-entry result shape (no output schema exists), which would help an agent parse results, but the core calling information is present.
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 the single optional parameter firstPartyOnly is fully documented in the schema, so the baseline of 3 applies. The description adds nothing about the parameter, though nothing is missing that would cause misuse.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Return') and enumerates the exact resource contents: console errors, uncaught exceptions, failed network requests, HTTP >= 400 responses, and guard blocks. This clearly separates it from the sibling get_network_requests by scoping to errors only.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'recorded since the last navigate_url' implicitly tells the agent this must follow a navigation and resets per page load, which is useful usage context. However, it never explicitly says when to prefer this over get_network_requests or get_page_snapshot, leaving the agent to infer the boundary from the enumerated contents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_network_requestsGet network requestsARead-only
List HTTP requests made by the page since the last navigate_url: method, URL, resource type, status, duration, failure reason and whether a mock answered it. Static assets are hidden by default.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Return at most this many (most recent) | |
| failedOnly | No | Only failed requests and HTTP >= 400 | |
| urlContains | No | Only requests whose URL contains this text, e.g. "/api/" | |
| includeStatic | No | Include images, fonts, stylesheets and media | |
| resourceTypes | No | Only these resource types (overrides includeStatic) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint annotations already covering safety, the description adds useful behavioral context: the request window begins at the last navigate_url, returned fields include status/duration/failure reason/mock status, and static assets are excluded by default. It does not describe response ordering or pagination beyond what the schema covers, but it is more informative than a bare read operation.
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 definition is two tight sentences with no wasted wording. The main scope and returned fields are front-loaded, and the exception about static assets follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool with full schema coverage and no output schema, the description gives the essential scope, return fields, and default filtering behavior. It could go further by noting ordering or how results relate to get_console_errors, but it is complete enough to call correctly.
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 explains limit, failedOnly, urlContains, includeStatic, and resourceTypes. The description reinforces the static-asset default but adds no parameter syntax or semantics beyond the schema. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: "List HTTP requests made by the page since the last navigate_url." It also enumerates the returned fields, making the tool's scope clear. It does not explicitly differentiate itself from siblings such as get_console_errors, so it falls short of the top score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase "since the last navigate_url" implies this tool is used after navigation, and "Static assets are hidden by default" gives some filtering context. However, there is no explicit guidance on when to use this versus get_console_errors, mock_route, or other diagnostic siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_page_snapshotGet page snapshotARead-only
Return the page's accessibility tree as YAML: roles, accessible names, values and states, including iframe contents. Every element has a [ref=eN] handle; pass it to other tools as selector "aria-ref=eN". Use this before interacting with a page instead of guessing selectors. Refs from older snapshots may go stale.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Limit tree depth | |
| selector | No | Only snapshot this element's subtree | |
| maxLength | No | Truncate output beyond this many characters |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations: it discloses that iframe contents are included, defines the [ref=eN] handle contract, specifies the cross-tool selector syntax 'aria-ref=eN', and warns that refs from older snapshots may go stale. The staleness warning is a genuine behavioral hazard an agent must know before caching refs across calls.
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?
Four tight sentences, front-loaded with what is returned, then the handle contract, then the usage directive, then the failure mode. No filler and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the burden of describing the return value - and it does, naming the format (YAML), the content (roles/names/values/states/iframes) and the embedded ref handles. Combined with complete schema parameter docs and annotations covering the safety profile, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning by explaining that the selector parameter is fed the aria-ref values emitted by this same tool, linking the parameter to observable output. It says nothing about depth or maxLength truncation, leaving that entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb and resource ('Return the page's accessibility tree as YAML') plus the exact shape of what comes back: roles, accessible names, values, states, iframe contents. This clearly distinguishes it from observation siblings like take_screenshot or get_console_errors, which return entirely different artifacts.
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?
'Use this before interacting with a page instead of guessing selectors' states the triggering condition and names the anti-pattern it replaces, which is strong routing guidance. It does not explicitly say when not to use it or contrast it with take_screenshot, so it falls just short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hover_elementHover elementA
Move the mouse over an element, e.g. to open a dropdown menu or reveal a tooltip.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| timeout | No | Timeout in milliseconds | |
| selector | Yes | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=true, and the description is consistent with that by noting hover can reveal menus/tooltips (i.e., it changes page state). It adds no detail on auto-waiting, scroll-into-view, what happens on timeout, or whether the hover persists before the next action—useful gaps given a mouse-state tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with the action front-loaded and the use cases trailing as a short example clause. Nothing is extraneous or buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter, fully documented, non-mutating interaction tool with no output schema, the description is nearly sufficient—only sequencing/timing behavior after the hover is left unstated, which the agent must infer.
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 the selector description already documents aria-ref, CSS, text, role, and XPath formats plus the frame/timeout semantics. The description adds nothing beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Move the mouse over an element") that unambiguously identifies hover as distinct from click_element, fill_input, and select_option. It does not explicitly name a sibling or contrast itself, so it stops short of a 5.
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 parenthetical "e.g. to open a dropdown menu or reveal a tooltip" gives an implied when-to-use cue, but there is no guidance on when to prefer hover over click, whether to follow it with wait_for or get_page_snapshot, or any exclusions. Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mock_routeMock network routeA
Intercept browser requests matching a URL glob and answer them with a canned response, an error, or a delay, without contacting the real server. Tests UI behavior for API errors, payment declines, timeouts and outages. Only the browser sees the mock; no backend is contacted. Mocks persist until clear_mocks.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Raw body text (ignored when json is given) | |
| json | No | JSON body (sets content-type application/json) | |
| abort | No | Fail the request with this network error instead of responding | |
| times | No | Only mock the first N matching requests | |
| method | No | Only mock this HTTP method | |
| status | No | HTTP status to return | |
| delayMs | No | Delay before responding | |
| headers | No | Extra response headers | |
| urlPattern | Yes | Glob matched against the full URL, e.g. "**/api/checkout*" or "https://api.example.com/v1/**" | |
| contentType | No | Content-Type for a raw body (default text/plain) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the description carries most of the burden and does well: it explains the browser-only scoping, that no backend is contacted, and crucially that mocks persist until clear_mocks. It doesn't state what the tool returns (e.g., a handle/id) or precedence when multiple mocks match the same URL, which would complete the picture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and four tight sentences. Minor redundancy: 'without contacting the real server' and 'no backend is contacted' restate the same fact, so one of them could be cut.
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 10-parameter mutation-style tool with no output schema, the description covers the essential behavior: interception scope, persistence, and browser-only effect. It could say more about mock precedence and whether the call returns a reference, but an agent has enough to invoke it correctly.
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 reinforces the urlPattern glob semantics and maps loosely onto the status/body/abort/delayMs modes, but adds no syntax or format detail beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (intercept) and resource (browser requests matching a URL glob), plus the three response modes: canned response, error, or delay. It is clearly distinguishable from siblings like get_network_requests and clear_mocks, the latter named explicitly.
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?
Gives concrete usage scenarios (API errors, payment declines, timeouts, outages) and names clear_mocks as the cleanup path. It lacks an explicit 'when not to use this vs. get_network_requests' exclusion, but the context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
press_keyPress keyA
Press a key or chord, e.g. "Enter", "Tab", "Escape", "ArrowDown", "Control+A". Focuses the element first when a selector is given, otherwise sends it to whatever has focus. Waits for any navigation it triggers.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Key name as used by Playwright keyboard.press | |
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| timeout | No | Timeout in milliseconds | |
| selector | No | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only readOnlyHint=false and openWorldHint=true in annotations, the description adds useful behavioral detail: it focuses the target element when a selector is provided, otherwise sends the key to whatever has focus, and waits for any navigation triggered. It does not describe timeout/error behavior, but it meaningfully extends beyond 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 compact and front-loaded: the primary action and examples come first, followed by conditional focus behavior and navigation waiting. Every sentence contributes useful information with no repetition or filler.
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 four-parameter mutation tool with full schema coverage, no output schema, and annotations covering safety/open-world behavior, the description is nearly complete. It covers key/chord examples, focus semantics, and navigation waiting; minor gaps like timeout failure behavior are acceptable given the schema documents timeout.
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 already 100%, so the baseline is 3. The description earns extra credit by clarifying chord syntax via examples and by explaining the selector parameter's focus semantics, which are not fully captured in the schema text alone.
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?
Starts with a specific verb and resource ("Press a key or chord") and immediately supplies concrete examples, including modifier chords like "Control+A". This distinguishes it cleanly from sibling tools such as click_element and fill_input.
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 explains the selector/no-selector behavior, which implies when to use each mode, but it never explicitly contrasts this tool with alternatives like click_element, fill_input, or wait_for. Usage context exists but is not framed as when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
select_optionSelect optionB
Choose option(s) in a element, matching each by its value or its visible label.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| options | Yes | Option value/label, or several for a multi-select | |
| timeout | No | Timeout in milliseconds | |
| selector | Yes | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=true, so the mutation/open-world profile is known without the description. The description adds the useful matching rule (value vs visible label) but omits key behavior for a selection tool: whether multi-select calls replace or append to the current selection, whether it auto-waits for the option to appear, and what happens when an option is not found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler — the core action and matching rule come first. It is efficient but so terse that the structure leaves no room for the caveats an agent needs.
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 4-parameter mutating browser tool with no output schema, the schema covers inputs fully and annotations cover the safety profile, so the description need not explain return values. However, it says nothing about failure modes (option missing, element not select), selection replacement vs accumulation, or the aria-ref prerequisite implied by frame's description, leaving real 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 options/selector/frame/timeout are all documented in the schema itself, including the multi-select note. The description's 'matching each by its value or its visible label' largely restates the options parameter description rather than adding resolution rules or precedence (what happens if both a value and label match).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Choose') and a specific resource/context ('option(s) in a <select> element'), and explains the matching rule (value or visible label). It implicitly separates the tool from fill_input, but never names or contrasts any sibling explicitly.
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?
Usage is only implied by the phrase 'in a <select> element' — an agent can infer this is for dropdowns rather than free-text inputs. There is no explicit when-to-use/when-not, no mention of needing a prior get_page_snapshot for aria-refs, and no stated alternatives such as fill_input.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_recordingStart recordingA
Start recording the browser session for later review by a developer: a Playwright trace (DOM snapshots, network, console for every step), an optional video, and a log of every tool call. With video on, the page is reloaded into a fresh recording context (cookies and localStorage are kept). Call stop_recording when done to save everything.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Short label for the recording, e.g. "login flow" | session |
| video | No | Also capture a .webm screen recording |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint=false and openWorldHint=false, so the description carries the burden and does it well: it discloses the significant side effect that enabling video reloads the page into a fresh recording context while preserving cookies and localStorage. That reload/reset behavior is exactly the kind of non-obvious consequence an agent must know before calling.
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?
Three tight sentences: purpose and captured artifacts first, the side-effect caveat second, and the required follow-up action last. No filler, and the important behavioral warning is front-loaded rather than buried.
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 two optional params, no output schema, and light annotations, the description covers what is captured and the required stop_recording follow-up. It doesn't state where artifacts are persisted or what happens if recording is already active, which is a minor remaining gap for a stateful capture tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantic value by explaining the consequence of the video flag (page reload into a fresh context). The name parameter is left entirely to its schema description, which is acceptable given full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Start recording the browser session') and enumerates exactly what the recording contains: Playwright trace with DOM snapshots, network, console, optional video, and a tool-call log. It also names its paired sibling (stop_recording), so an agent can distinguish it from the other observation tools like take_screenshot or get_page_snapshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear lifecycle guidance — 'Call stop_recording when done to save everything' — which tells the agent the necessary follow-up. It lacks an explicit when-not or comparison to alternatives (e.g., use take_screenshot for a one-off capture), which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_recordingStop recordingA
Stop the active recording and save its trace.zip, video, screenshots, actions.json and an HTML report. Returns the overall verdict, the failed checks and errored steps with explanations, the number of website errors, the file paths and the command to open the trace viewer. If anything failed, follow up with suggest_fix for each failed step. When email delivery is configured, the report is emailed to the configured recipients once every failure has a suggested fix (see delivery in the result).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, and the description adds meaningful context beyond that: the exact artifacts written to disk, the returned verdict and error details, and the side effect of emailing the report to configured recipients. It omits edge cases such as behavior when no recording is active, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the action and outputs, then the follow-up guidance, then the conditional email delivery detail. Every sentence adds actionable information with no filler.
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 carries the burden of describing return values, which it does thoroughly: verdict, failed checks, errored steps, website error count, file paths, and the trace-viewer command. An agent has everything needed to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema has nothing to document and the description does not need to explain inputs. Baseline 4 applies for a no-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ("Stop the active recording") and immediately lists the artifacts saved (trace.zip, video, screenshots, actions.json, HTML report). This clearly distinguishes it from the sibling start_recording and other capture tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It establishes the trigger context (ending an active recording) and explicitly routes the agent to suggest_fix for each failed step after this call. It also explains the email-delivery precondition. There is no explicit statement of when not to call it, but the usage path is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_fixSuggest a fixA
Add your suggested fix for a failed step to the recording's report, shown in the "AI agent's suggested fix" column. Use the step numbers from stop_recording (failedChecks / toolErrors) or from failed tool calls during the recording. Diagnose the actual cause from the evidence (error explanation, actual page text, screenshot, console and network errors) and give a concrete fix: name the selector, file, endpoint or setting to change. Say whether the fix belongs in the app (a real bug), the test (wrong selector or expectation) or the environment (server down, missing data). Works during a recording or after stop_recording; calling it again for a step replaces the earlier suggestion.
| Name | Required | Description | Default |
|---|---|---|---|
| fix | Yes | The concrete fix to make | |
| step | Yes | Step number of the failed check or tool call | |
| cause | No | Your diagnosis of the root cause | |
| target | No | Where the fix belongs: app (bug in the site), test (the test is wrong) or environment |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false. The description adds real behavioral context beyond that: it is a mutating write that overwrites prior suggestions for the same step, works both during and after recording, and directs the agent to ground diagnoses in concrete evidence (error explanation, page text, screenshot, console/network errors).
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?
Front-loaded with the core action, followed by the step-number sourcing, evidence expectations, and replacement semantics. It is dense but every sentence carries distinct, actionable information with no filler.
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 4-parameter mutation tool with full schema coverage and no output schema, the description covers everything an agent needs: what to write, which step to reference, how to diagnose, how to categorize the target, and what happens on repeat calls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds genuine meaning: it explains where 'step' numbers originate and that 'cause'/'target' should reflect an app-vs-test-vs-environment diagnosis, giving the enum values practical intent beyond the schema's bare listing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (add) and resource (suggested fix for a failed step in the recording's report) and names exactly where the result surfaces ('AI agent's suggested fix' column). An agent can distinguish it from siblings like assert_text or stop_recording without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says which step numbers to use (from stop_recording's failedChecks / toolErrors, or failed tool calls during recording) and when the tool can be called (during a recording or after stop_recording). It also states the idempotent behavior — calling again for a step replaces the earlier suggestion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
take_screenshotTake screenshotA
Capture a PNG of the current page (full scrollable page or just the viewport) and save it to the screenshot directory. Returns the file path and, unless returnImage is false or the image is very large, the image itself.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | No | File name; saved inside the screenshot directory | screenshot.png |
| fullPage | No | Capture the full scrollable page instead of the viewport | |
| returnImage | No | Include the image in the response (false saves context) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint=false and openWorldHint=false; the description adds the real behavioral facts an agent needs: the file is written into the screenshot directory and the response includes the path. It also discloses the conditional image return ('unless returnImage is false or the image is very large'), which explains an otherwise surprising omission. Minor gap: silent about filename collisions/overwrite behavior, which matters for a write.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the action and artifact, then the return contract. Nothing redundant with the title or schema is repeated needlessly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description carries the return contract (file path plus conditionally the image). With only three fully documented optional params and explicit side-effect disclosure, nothing essential is missing for an agent to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and the schema already documents all three params. The description adds genuine nuance beyond the schema: returnImage's suppression is conditional not just on the flag but also on image size, and it explains the context-saving motive. That is value above the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Capture a PNG'), specific resource ('the current page'), and it names both capture modes (full scrollable page vs viewport) plus where the artifact lands. That is enough to separate it from get_page_snapshot, which by contrast implies text/DOM inspection rather than an image artifact.
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 visual evidence capture and mentions the context trade-off for returnImage, but it never states when to reach for this versus get_page_snapshot or start_recording, nor any prerequisites (page loaded, navigation settled). Usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_forWait forARead-only
Wait until an element (by selector) or a piece of visible text reaches a state: visible (default), hidden, attached or detached. Useful after actions that load content asynchronously.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text to wait for (substring match) | |
| frame | No | CSS selector of the iframe containing the element (e.g. "iframe[name^=__privateStripeFrame]"), or a list for nested iframes, outermost first. Not needed with aria-ref selectors. | |
| state | No | visible | |
| timeout | No | Timeout in milliseconds | |
| selector | No | Selector: "aria-ref=e5" from get_page_snapshot (preferred; also reaches into iframes), CSS ("#email", "button.submit"), text ("text=Sign in"), role ("role=button[name=/save/i]") or XPath ("xpath=//a") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so the safety profile is already covered. The description adds the default state ('visible') and the fact that it blocks on a target state, which is meaningful beyond the annotations. It omits the polling/blocking nature of the call beyond timeout, and does not say what happens when the timeout expires (error vs. silent return), which is the primary behavioral risk of a wait tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The target states and the default are front-loaded before the usage hint, so an agent can act on the first sentence alone.
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 5 optional parameters, no required params and no output schema, the description should disclose return behavior and timeout-failure semantics. It covers the states and the async rationale but leaves the return value and timeout outcome unstated, which matters for an agent composing subsequent steps.
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 80%, so the schema already documents selector syntax, iframe handling, state enum and timeout. The description restates selector/text/states without adding format or edge-case detail (e.g. interplay of text vs selector, behavior when both are supplied). 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?
States a specific verb ('Wait until') plus the two targeting modes (selector, visible text) and enumerates the four target states. An agent can distinguish it from click_element or navigate_url immediately. It does not, however, distinguish itself from the sibling assert_text/assert_visible, which is the closest conceptual neighbor.
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?
'Useful after actions that load content asynchronously' gives a clear positive usage context. There is no guidance on when NOT to use it, nor any pointer to the alternatives (assert_visible, assert_text, get_page_snapshot polling), so the when-to-use-vs-alternative decision is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
18 tool updates
v0.1.0- First observed
assert_text - First observed
assert_visible - First observed
clear_mocks - First observed
click_element - First observed
fill_input - First observed
get_console_errors - First observed
get_network_requests - First observed
get_page_snapshot - First observed
hover_element - First observed
mock_route - First observed
navigate_url - First observed
press_key - First observed
select_option - First observed
start_recording - First observed
stop_recording - First observed
suggest_fix - First observed
take_screenshot - First observed
wait_for
TDQS
Scored across 18 tools
Most tools have clearly distinct purposes across navigation, interaction, assertions, diagnostics, mocking, and recording. Minor overlap exists between wait_for and the assert_* tools, and between get_console_errors and get_network_requests since both surface failed network activity, but descriptions clarify the intended use.
All tool names consistently use snake_case with a verb-led pattern such as navigate_url, click_element, assert_visible, mock_route, and start_recording. There are no mixed naming conventions or confusing style deviations.
The 18 tools cover a broad browser-automation and QA workflow, and each has a distinct role. The count is slightly above the typical 3-15 range but remains reasonable for a server combining page interaction, assertions, diagnostics, mocking, and recording.
The surface covers essential browser automation and QA lifecycle operations: navigation, snapshots, interactions, assertions, console/network diagnostics, mocking, and recording with suggested fixes. Some gaps remain, such as file upload, drag-and-drop, and explicit tab/window or storage management, but agents can work around most of these.
Maintenance
Related MCP Connectors
Browser-based QA for AI-built software. Test pages with real browsers via agents.
Test a web app in a real browser from plain English. Passed, failed or cannot verify, with evidence.
Hosted browser for AI agents: screenshots, post-JS DOM, console, WCAG. No install, no API key.
Website checker for AI coding agents. Measures your site in a real browser, with evidence.
Related MCP Servers
AlicenseNot gradedqualityDmaintenanceEnables AI to perform real-browser QA testing on websites via Playwright, finding bugs, accessibility, SEO, and performance issues through natural language conversations.1MIT- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to autonomously interact with and test web applications in a real browser, providing DOM/Accessibility tree extraction, runtime telemetry, screenshot capture, and Markdown test reports.12 npm1MIT

QualityMax QA MCPofficial
AlicenseAqualityAmaintenanceEnables coding agents to independently verify web changes by scanning pages, inspecting UI structure, generating Playwright reproductions, and executing tests with structured QA evidence.4222 npm4MIT- AlicenseAqualityBmaintenanceEnables AI agents to automate browsers through Playwright behind multi-layer safety guards, restricting navigation to allowed domains, defaulting to read-only actions, and recording all behavior in audit logs.7MIT