zenrows-mcp
OfficialZenRows MCP 서버
ZenRows MCP(Model Context Protocol) 서버는 AI 시스템이 ZenRows를 사용하는 표준 방식입니다. 단일 연결로 AI 어시스턴트, 에이전트 또는 애플리케이션이 모든 웹사이트에 실시간으로 액세스할 수 있습니다.
📚 전체 문서: docs.zenrows.com/integrations/mcp/mcp-overview
ZenRows MCP를 사용하는 이유
봇을 차단하는 사이트 접근. 안티봇 시스템에 차단되지 않고 모든 웹사이트에 대규모로 액세스하세요.
관리형 스크래핑 인프라. 프록시 로테이션, 헤드리스 브라우저 오케스트레이션, 안티봇 회피 및 세션 관리가 ZenRows 인프라에서 실행됩니다.
기존 AI와 연동. AI 어시스턴트, 에이전트 프레임워크, AI SDK, IDE 플러그인 및 맞춤형 애플리케이션을 포함한 모든 MCP 클라이언트와 작동합니다.
쉬운 영어, 스크래핑 코드 불필요. 작업을 자연어로 설명하면 AI가 적절한 도구를 선택합니다. 선택자(selector), 프록시 관리, 안티봇 튜닝이 필요 없습니다.
Related MCP server: @hauntapi/mcp-server
빠른 시작
ZenRows MCP는 두 가지 전송 옵션을 지원합니다. 둘 다 동일한 도구와 기능을 제공하므로 클라이언트에 맞는 것을 선택하세요.
원격 MCP 서버
AI 애플리케이션이 LLM API를 직접 호출할 때 호스팅된 ZenRows MCP 서버를 사용하세요. 서버가 ZenRows 인프라에서 실행되므로 설치, 구성 또는 업데이트할 필요가 없습니다.
서버 URL:
https://mcp.zenrows.com/mcp전송: Streamable HTTP
인증: OAuth 기반. 모든 요청의 Authorization 헤더에 ZenRows API 키를 Bearer 토큰으로 전달하세요.
Authorization: Bearer YOUR_ZENROWS_API_KEY대부분의 MCP 클라이언트는 도구 구성의 authorization 약식 필드를 통해 이를 허용하며 자동으로 Bearer 토큰으로 전달합니다. 일부 클라이언트는 대신 자유 형식의 headers 필드를 사용합니다. 두 방식 모두 작동합니다.
예시: OpenAI Responses API
import os
from openai import OpenAI
ZENROWS_API_KEY = os.environ["ZENROWS_API_KEY"]
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.responses.create(
model="gpt-5",
tools=[
{
"type": "mcp",
"server_label": "zenrows",
"server_description": "Web scraping MCP server for accessing live web content.",
"server_url": "https://mcp.zenrows.com/mcp",
"authorization": ZENROWS_API_KEY,
"require_approval": "never",
}
],
input="Visit https://news.ycombinator.com/ and summarize the three most recent posts.",
)
print(response.output_text)프레임워크별 예시가 포함된 전체 가이드는 원격 MCP 서버 문서를 참조하세요.
로컬 MCP 서버
MCP 클라이언트가 원격 URL을 호출하는 대신 로컬 하위 프로세스로 서버를 실행할 때 로컬 stdio 구성을 사용하세요. 이는 Claude Desktop, Claude Code, Cursor, Windsurf, VS Code, Zed 및 JetBrains IDE를 포함한 데스크톱 AI 도구 및 IDE 플러그인의 표준 설정입니다.
패키지: npm의 @zenrows/mcp
인증: ZENROWS_API_KEY 환경 변수를 통한 API 키.
요구 사항: Node.js 설치됨 (npx가 작동해야 함).
구성:
{
"mcpServers": {
"zenrows": {
"command": "npx",
"args": ["-y", "@zenrows/mcp"],
"env": {
"ZENROWS_API_KEY": "YOUR_ZENROWS_API_KEY"
}
}
}
}이 구성의 정확한 위치는 클라이언트마다 다릅니다. 클라이언트의 파일 경로는 클라이언트별 설정 가이드를 참조하세요.
도구
ZenRows MCP는 두 가지 도구 제품군을 제공합니다:
scrape: 마크다운, 일반 텍스트, HTML, JSON, PDF 또는 스크린샷을 반환하는 단일 요청 가져오기. Universal Scraper API 기반.browser_*: 탐색, 클릭, 양식 채우기, JavaScript 실행, 쿠키, 탭 및 지속적 세션을 포함한 전체 브라우저 자동화를 위한 30개 이상의 도구. Scraping Browser 기반.
AI가 프롬프트에서 적절한 도구를 선택합니다. 코드에서 도구를 직접 호출할 필요가 없습니다.
모든 도구, 매개변수 및 반환 값에 대한 전체 도구 참조를 확인하세요.
개발
git clone https://github.com/ZenRows/zenrows-mcp
cd zenrows-mcp
npm install
cp .env.example .env # Add your API key
npm run dev # Run with .env loaded (requires Node.js 20.6+)
npm run build # Compile to dist/
npm run inspect # Open the MCP inspector UI풀 리퀘스트와 이슈는 언제나 환영합니다.
리소스
라이선스
Available Tools
63 toolsaccount_signup_answerAInspect
Answer the question Zenrows asks before it creates a free account. Use it only when another Zenrows tool reports a signup question: answer that question yourself and pass the answer here. On success the API key is stored and you can retry the original tool call.
| Name | Required | Description | Default |
|---|---|---|---|
| answer | Yes | Your answer to the signup question, as plain text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is not read-only and is open-world. The description adds important context beyond them: the tool creates a free account, stores the API key on success, and enables retrying the original call. It does not describe failure behavior if the answer is rejected, so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three front-loaded sentences with no waste: purpose, usage condition, and success outcome. Every sentence contributes needed information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single-parameter schema, rich annotations, and absence of an output schema, the description is complete enough. It covers when to call the tool, what to pass, and what happens on success.
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 answer parameter is already documented as plain text with a maxLength. The description reinforces that the agent must provide the answer but adds no format, validation, or examples beyond the schema, so 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 action and resource: answer the signup question Zenrows asks before creating a free account. It also distinguishes this tool from siblings by limiting its use to cases where another Zenrows tool reports a signup question.
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 an explicit trigger: use only when another Zenrows tool reports a signup question. It also explains the full workflow: answer the question yourself, pass the answer here, then retry the original tool call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
account_usageARead-onlyInspect
Read the current plan's credit allowance and how much of it is spent.
Useful before a large batch, or after a 402 / AUTH004, to see whether the account has credits left and when the allowance renews. The call is free and does not use a concurrency slot.
Credit costs per request: 1 basic, 5 js_render, 10 premium_proxy, 25 both.
AUTH004 ("usage exceeded") means this allowance is spent until it renews at the end of the billing period (period_ends_at in this tool's response). Plans and credit options are described at https://www.zenrows.com/pricing. AUTH006 is the concurrency limit, not a credit limit.
AUTH014 (Batch: api_key_cap_reached) means this API key hit one of its own credit caps while the account still has credits; other keys keep working. The response's api_key.caps lists the calling key's caps: window, credits, used_credits, remaining_credits, resets_at, and unavailable (usage could not be read). Caps are managed at https://app.zenrows.com/settings/api-keys.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish a safe read (readOnlyHint=true, destructiveHint=false), and the description adds substantially beyond them: the call is free, consumes no concurrency slot, per-request credit costs, renewal timing, and the meaning of specific error codes with pointers to the response fields they map to.
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?
Purpose is front-loaded in the first sentence, followed by usage triggers then error-code details. It is information-dense and slightly long, but nearly every clause (costs, slot behavior, error meanings) is callable, non-redundant 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?
With no output schema, the description carries the return-value burden and does name key fields (period_ends_at, api_key.caps). Given a zero-parameter, annotation-covered read tool, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline is 4. It adds no param-level detail, which is appropriate here.
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: 'Read the current plan's credit allowance and how much of it is spent.' No sibling tool covers account billing/credit state, so the agent can identify this unambiguously.
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 names the trigger conditions ('before a large batch, or after a 402 / AUTH004') and disambiguates error semantics across AUTH004, AUTH006 and AUTH014, telling the agent when this tool applies versus when the error means something else.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_cancelADestructiveIdempotentInspect
Stop a Batch job's current run for good. No task still waiting is started or billed; tasks already in flight finish (and bill). Results so far stay readable with batch_results. Tasks that never started stay pending: batch_rerun (default failed and pending) runs them later. Idempotent: a run that already ended answers with its final status and already_ended:true. To halt without ending the run, use batch_pause.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the 'destructiveHint' annotation, the description adds crucial behavioral details regarding resource consequences. It specifies that tasks in flight 'finish (and bill)' while waiting tasks are stopped and unbilled, which is essential operational context.
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 dense and long, but every sentence serves a critical purpose, detailing state transition, billing consequences, and sibling comparisons. It is highly informative without being unnecessarily rambling.
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 complexity of job state management, the description is exceptionally complete. It clarifies not only what cancellation does but also the resulting state (results stay readable, pending tasks remain, idempotency details) for an AI agent to execute 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?
Since the schema coverage is 100%, the schema already provides full semantics for the required 'job_id' parameter. The description does not add unique semantic value beyond confirming its necessity.
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 ('Stop') and resource ('Batch job'), clearly defining the action. It distinguishes itself by stating the action is 'for good,' setting it apart from alternative state management actions like pausing or rerunning.
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 provides explicit guidance on when to use this tool versus its close sibling, stating: 'To halt without ending the run, use batch_pause.' It also details the differential effect on waiting vs. in-flight tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_contentARead-onlyInspect
Read one Batch task's stored result, by job_id and task_id (from batch_results). A text result (HTML, Markdown, plain text, JSON) comes back inline, cut to max_chars (default 20000); a final note says when it was cut. A binary result (a PDF) is not inlined: the reply gives its result_url, presigned for 2 hours. Finding that URL reads the run's results; on a large run one call may run out of time first and answer with lookup_cursor: call batch_content again with it to go on.
BATCH_TASK_NOT_READY: the task has not finished; BATCH_TASK_FAILED: it failed (task_error holds its error); BATCH_RESULT_EXPIRED: past the job's retention (14 days by default); rerun to scrape it again.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list | |
| run_id | No | An earlier run's id (from batch_status or batch_rerun). Default: the job's latest run. | |
| task_id | Yes | task_id from a batch_results row | |
| max_chars | No | Max characters of a text result to return (default 20000) | |
| lookup_cursor | No | lookup_cursor from a previous batch_content reply on a binary result, to go on looking for its result_url |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond annotations: text results are inlined and truncated at max_chars with an explicit cut note, binary PDFs are never inlined and instead yield a 2-hour presigned result_url, large-run lookups can exhaust time and return a cursor, and the three named error codes plus the 14-day retention default are documented.
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-loads what the tool does, then failures, in two tight paragraphs with no filler, and every clause carries operational information. The prose is dense and occasionally awkwardly phrased ('Finding that URL reads the run's results'), which slightly taxes readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full return-value burden and does: inline text vs. result_url, truncation signaling, cursor continuation, and named error codes with their meanings. Nothing an agent needs to call or interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description earns more: it explains max_chars' default and truncation note, the purpose of lookup_cursor as a continuation token, and that run_id defaults to the job's latest run. It contextualizes parameters rather than merely restating them.
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 ('Read') and resource ('one Batch task's stored result'), plus the exact keys (job_id, task_id) and their provenance ('from batch_results'). This cleanly separates it from batch_results, which lists rows rather than returning content.
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?
Explains the operating conditions thoroughly: when lookup_cursor appears and how to continue, and when to rerun after BATCH_RESULT_EXPIRED. It stops short of an explicit 'use this instead of batch_results when...' statement, leaving a small inference gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_createAInspect
Submit a Batch job: many URLs scraped asynchronously in the cloud (Zenrows Batch API). Suited to large URL lists; scrape and extract handle single pages. Not the same as browser_batch.
Tasks use automatic mode (mode=auto) by default: Zenrows enables JS rendering and premium proxies only on the pages that need them. Pass just the URLs. Set js_render or premium_proxy (job-level, or per task) only to force a fixed configuration; that turns automatic mode off for those tasks.
Cost: the same credits as the regular API, per successful task: 1 for a basic request, 5 with js_render, 10 with premium_proxy, 25 with both; mode=auto bills each task at the configuration that worked. Failed tasks are not billed, except target 404 and 410 answers, billed as on the regular API. Limits: up to 100,000 tasks per call; 3 active jobs per account by default, shared with Crawl (BATCH_QUOTA_EXCEEDED past that); a job frees its slot when its run ends.
Creates a closed job with every task in this one call. Each task takes a url plus optional external_id, metadata, method/body (POST tasks) and scrape params. Every call sends an Idempotency-Key, so the bounded retries on network errors and 5xx never create a second job; an error reply carries the key to retry with.
Returns job_id, status and stats at once; the job runs asynchronously. Then: batch_wait until it ends, batch_results to list rows (paged), batch_content to read one task's page. A run that ends failed (out of credits, inactive subscription, key cap) answers ok:false with error.code and server_code; batch_rerun recovers it. Submits of 10,000+ tasks keep writing tasks for a while (ingesting:true). Errors: BATCH_INVALID_REQUEST (400, server_code and invalid_tasks say what), BATCH_INSUFFICIENT_CREDITS (402), BATCH_KEY_CAP_REACHED (402, this key's cap), BATCH_QUOTA_EXCEEDED (429, job limit), AUTH_INVALID (401; server_code subscription_inactive means fix Billing), BATCH_ACCESS_DENIED (403, do not retry), BACKEND_UNAVAILABLE. Schedules, webhooks, exports, CSV inputs and open jobs are available through the Batch API and SDKs only.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | No | Shorthand: list of URLs (converted to tasks), up to 100,000. Ignored when tasks is provided. | |
| wait | No | If true, poll before returning until the run ends or pauses, or wait_timeout passes; a timeout returns the current state with ok:true | |
| tasks | No | Tasks (each needs a url), up to 100,000. Prefer this over urls when you need per-task params. | |
| js_render | No | Force js_render on all tasks (5 credits each). Overrides automatic mode (mode=auto), which already renders when needed. | |
| mode_auto | No | Automatic mode (mode=auto) is on by default; leave unset. False sends plain requests without it. | |
| wait_timeout | No | Max wait in seconds when wait=true (default 50). Many MCP clients cancel a call after 60 s. | |
| premium_proxy | No | Force premium_proxy on all tasks (10 credits each, 25 with js_render). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them. | |
| proxy_country | No | Job-level ISO country code. Works in automatic mode (mode=auto); with js_render alone it requires premium_proxy. | |
| response_type | No | Job-level output format. Leave unset for the raw HTML, the default. | |
| zenrows_params | No | Additional job-level scrape params merged with the flags above. Accepted: allowed_status_codes, autoparse, block_resources, css_extractor, custom_headers, extract, extract_fields, js_instructions, js_render, json_response, mode, original_status, outputs, premium_proxy, proxy_country, response_type, session_id, wait, wait_for. | |
| idempotency_key | No | Sent as the Idempotency-Key header, up to 128 characters; generated per call when unset. Reusing a key with the identical request within 24 hours returns the original response instead of doing it again; with a different request it is BATCH_IDEMPOTENCY_CONFLICT. | |
| wait_timeout_ms | No | Deprecated: the same wait in milliseconds. Use the seconds parameter instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations only covering write/open-world/safe profile, the description carries real behavioral weight: credit costs per configuration (1/5/10/25), billing rules for failed and 404/410 tasks, hard limits (100,000 tasks, 3 active jobs, BATCH_QUOTA_EXCEEDED), idempotency guarantees across retries, and the full error taxonomy with actionable codes. This is substantially beyond what readOnlyHint/destructiveHint/openWorldHint 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?
Front-loaded and organized into labeled paragraphs (purpose, mode, cost, limits, returns/workflow, errors), so a reader can stop after the first two sentences. It is long, and the exhaustive error-code enumeration plus the cost paragraph border on verbosity for a tool-selection read, but each block is distinct and non-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?
There is no output schema, and the description compensates fully: it states what is returned (job_id, status, stats), that the job runs asynchronously, the ok:false/error.code/server_code failure shape, the ingesting:true behavior for 10,000+ task submits, and the exact follow-up toolchain. For a 12-parameter, 0-required async job creator, nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema itself already documents credits per flag, mode=auto default, idempotency-key reuse semantics, and the urls-vs-tasks precedence. The description's prose on 'Pass just the URLs' and 'Set js_render ... only to force a fixed configuration' largely restates that, so the baseline of 3 for a fully-covered schema is the correct ceiling.
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 opening sentence names the verb and resource precisely ('Submit a Batch job: many URLs scraped asynchronously in the cloud') and immediately positions it against siblings, stating that 'scrape and extract handle single pages' and 'Not the same as browser_batch.' An agent can tell exactly what this does and what it does not, without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit selection rule ('Suited to large URL lists; scrape and extract handle single pages'), rules out a lookalike sibling ('Not the same as browser_batch'), and names the follow-up tools in sequence (batch_wait, batch_results, batch_content, batch_rerun). It even states what is out of scope (schedules, webhooks, exports, CSV inputs, open jobs are API/SDK-only).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_deleteADestructiveIdempotentInspect
Delete a Batch job with all its runs and results, for good. A run in flight stops picking up tasks at once, and the job frees its active-job slot. The job reads as not found right away; storage is cleaned up in the background. Idempotent. To keep the results, use batch_cancel instead.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint and idempotentHint, but the description adds substantial context beyond them: what is destroyed (all runs and results), that in-flight runs stop picking up tasks at once, that the active-job slot is freed, that the job reads as not found immediately, and that storage cleanup happens in the background.
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-loads the core action and outcome, then layers timing, slot behavior, idempotency, and the alternative in short declarative clauses. Every sentence carries distinct 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?
As a destructive mutation with no output schema, the definition still covers destruction scope, immediate vs background effects, idempotency, and the safer alternative. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (job_id) with 100% schema description coverage, so the schema already carries the semantics ('Batch job id returned by batch_create or batch_list'). The description adds nothing about the argument, so the baseline 3 for high coverage 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 ('Delete a Batch job with all its runs and results') and immediately distinguishes itself from batch_cancel by scope. An agent can tell it apart from siblings 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 routes the agent to the alternative: 'To keep the results, use batch_cancel instead.' The when-to-use condition for the destructive path versus the cancel path is stated outright, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_listARead-onlyInspect
List this account's Batch jobs, newest first, each with its latest run's status and stats. Filter by status (open or closed) and type (regular or scheduled). Pass next_cursor as cursor for the next page; a page can hold fewer than limit jobs while next_cursor is still set, so keep paging until it is null. Deleted jobs are not listed.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only jobs of this type | |
| limit | No | Jobs per page (default 20, max 100) | |
| cursor | No | next_cursor from a previous batch_list call | |
| status | No | Only jobs with this job status |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral traits beyond the read-only annotation. It specifies the sorting order ('newest first'), the data provided ('latest run's status and stats'), and crucial negative constraints ('Deleted jobs are not listed').
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 highly dense and efficient. It front-loads the core function and uses every clause to communicate a critical operational or structural requirement (sorting, filtering, paging).
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 definition is comprehensive. It covers the scope (this account), the required output details (stats/status), the filtering mechanism, and the full pagination lifecycle, leaving no operational requirements ambiguous.
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?
While schema coverage is 100%, the description provides deep functional semantics for the parameters. Specifically, it details that `next_cursor` facilitates pagination and explains the practical constraint of when to stop iterating, adding context beyond the schema definition.
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 purpose is stated clearly and specifically: 'List this account's Batch jobs.' It effectively distinguishes itself from sibling tools like `batch_create` or `batch_cancel` by focusing exclusively on retrieval.
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 guidelines are exceptional. The description details the specific filtering capabilities (status/type) and, crucially, outlines the precise pagination logic, advising the agent to 'keep paging until it is null.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_pauseAIdempotentInspect
Pause a Batch job's current run: it picks up no new tasks until batch_resume. Tasks already in flight still finish and bill; for a hard cost stop use batch_cancel. A paused run still counts as an active job. Idempotent; a run that already ended answers with its final status and already_ended:true.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses that in-flight tasks still finish and bill, that a paused run still counts as an active job, that the operation is idempotent, and that an already-ended run returns its final status with already_ended:true. These are non-obvious behavioral traits the structured fields do not 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 action and its scope constraint are front-loaded in the first clause, followed by cost guidance, state semantics, and idempotency. Every sentence earns its place 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 single-parameter mutation with no output schema, the description covers effect, billing implication, job-state implication, idempotency, and the already-ended return case. Nothing needed to invoke or interpret it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single job_id parameter is already documented as coming from batch_create or batch_list, so the schema does the heavy lifting. The description adds no extra parameter syntax or format detail; 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 (pause) and resource (a Batch job's current run), and immediately scopes the effect: no new tasks picked up. It distinguishes itself from batch_resume (the inverse) and batch_cancel (hard stop) without either schema being opened.
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 names when to use alternatives: batch_resume to restart, batch_cancel 'for a hard cost stop.' It also clarifies the soft-stop semantics (in-flight tasks still finish and bill), so an agent can choose between pause and cancel on cost grounds.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_rerunAInspect
Start a new run of a Batch job whose latest run ended (completed, stopped or failed). By default it reruns only the tasks that failed or never started (status ["failed", "pending"]), and carries the others' results over: the recovery after a run that failed on credits or was cancelled. Pass status to pick other task statuses, or full:true to scrape every task again. Rerun tasks are billed like new ones.
A rerun of only some tasks works up to 10 days after the run started (BATCH_RERUN_WINDOW_EXPIRED after that; full:true still works). BATCH_NO_MATCHING_TASKS: no task has those statuses. BATCH_RUN_NOT_FINISHED: the latest run is still in flight. Sends an Idempotency-Key, so a retry never starts two runs. Returns the new run at once (it writes its tasks first, ingesting:true); call batch_wait.
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | Rerun every task, not only some (default false) | |
| job_id | Yes | Batch job id returned by batch_create or batch_list | |
| status | No | Task statuses to rerun (default ["failed", "pending"]). Ignored with full:true. | |
| idempotency_key | No | Sent as the Idempotency-Key header, up to 128 characters; generated per call when unset. Reusing a key with the identical request within 24 hours returns the original response instead of doing it again; with a different request it is BATCH_IDEMPOTENCY_CONFLICT. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark this as a non-read-only, non-destructive, open-world write. The description goes well beyond that: billing ('Rerun tasks are billed like new ones'), the 10-day partial-rerun window, specific error codes, automatic Idempotency-Key handling, and the fact that it returns immediately while tasks ingest. This is unusually rich behavioral disclosure.
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, then defaults, alternatives, constraints and errors in a logical order; nearly every sentence earns its place. It is dense and long, but the density is information rather than padding.
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 a mutation tool with no output schema and four parameters, the description supplies the missing pieces: failure modes, time window, idempotency guarantee, billing implication, immediate-return semantics, and the next call to make. Nothing an agent needs to invoke it correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: what the default status set is and why, that status is ignored under full:true, and that full:true 'scrapes every task again.' The idempotency_key semantics largely restate the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb+resource with a precondition: 'Start a new run of a Batch job whose latest run ended (completed, stopped or failed).' This distinguishes it cleanly from sibling tools like batch_create (new job) and batch_resume (in-flight run), so an agent can route 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?
It names the default behavior (rerun failed/pending), the recovery scenario ('after a run that failed on credits or was cancelled'), and the alternative modes (status, full:true), plus the follow-up call to batch_wait. It stops short of explicitly contrasting with sibling tools such as batch_resume, so it is clear context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_resultsARead-onlyInspect
List a Batch run's result rows, a page at a time: up to limit rows (default 100, max 1000) and next_cursor. Pass next_cursor back as cursor to continue; it is null once every row was read.
Each row has task_id, external_id, url, metadata, status (successful, failed, pending, processing, expired), type, result_url when successful, and error when failed. A result_url is presigned and expires after 2 hours: call batch_results again for a fresh one, or read the body with batch_content. Results are kept 14 days by default; after that a successful row reads as status "expired", with no result_url, and batch_content answers BATCH_RESULT_EXPIRED.
Filter with status: all (default), successful, failed, or processing (not finished yet). A sparse filter can return fewer rows than limit with next_cursor still set: keep paging. While the run is still running or writing its tasks, the list is partial.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows to return (default 100, max 1000) | |
| cursor | No | next_cursor from a previous batch_results call | |
| job_id | Yes | Batch job id returned by batch_create or batch_list | |
| run_id | No | An earlier run's id (from batch_status or batch_rerun). Default: the job's latest run. | |
| status | No | Filter rows by status (default all). processing = tasks not finished yet. successful also returns expired rows. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld/destructive annotations: presigned result_url expiry (2 hours), 14-day retention, expired-row behavior, the BATCH_RESULT_EXPIRED error from batch_content, and partial lists while the run is still writing. This is exactly the operational context an agent needs.
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?
Dense and front-loaded, with the paging mechanics first and return-shape second. Minor redundancy with the schema on limit defaults and the status enum, but every sentence is otherwise load-bearing.
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 carries the full burden of describing return values and does so thoroughly (task_id, external_id, url, metadata, status, type, result_url, error). Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter behavior beyond the schema: status filter semantics (processing = not finished, successful includes expired) and the warning that a sparse filter can return fewer rows than limit with next_cursor still set.
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 ('List a Batch run's result rows, a page at a time') and scopes it clearly. An agent can immediately distinguish it from batch_content (reads a body) and batch_status (run state) without opening 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?
Explicitly routes to alternatives with conditions: 'call batch_results again for a fresh one, or read the body with batch_content,' and explains the cursor continuation loop and the status filter options. The paging guidance ('keep paging' on sparse filters) removes inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_resumeAIdempotentInspect
Resume a paused Batch run: it picks up its remaining tasks again, billed as they finish. Idempotent on a run that is not paused; a run that already ended answers with its final status and already_ended:true. Needs credits: BATCH_INSUFFICIENT_CREDITS or BATCH_KEY_CAP_REACHED otherwise.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: billing semantics ('billed as they finish'), concrete return behavior on an ended run ('final status and already_ended:true'), and the exact credit failure codes (BATCH_INSUFFICIENT_CREDITS, BATCH_KEY_CAP_REACHED). This is the kind of operational detail the idempotentHint/destructiveHint flags cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences plus a short credit footnote; every clause carries distinct information (action, billing, idempotency, ended-run return, error codes) and the primary purpose 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 compensates by describing the important return signal (already_ended:true) and the failure modes, plus cost behavior. Nothing an agent needs to invoke this correctly against its siblings is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single job_id is fully documented as 'Batch job id returned by batch_create or batch_list'. The description adds no further parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Resume) and a precisely scoped resource (a paused Batch run), which an agent can distinguish from the counterpart sibling batch_pause. It does not explicitly differentiate from batch_rerun or batch_cancel, so sibling separation relies on inference rather than the text.
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 precondition (only meaningful on a paused run) and describes behavior for the not-paused and already-ended cases, which functionally covers when the call is a no-op. It never names an alternative tool for those cases, so the routing guidance is implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_statusARead-onlyInspect
Get a Batch job's latest run: job_id, run_id, status (pending, running, completed, stopped, failed), stats (total, completed, successful, failed) and the job.
A failed run answers ok:false with error.code BATCH_INSUFFICIENT_CREDITS, BATCH_KEY_CAP_REACHED, AUTH_INVALID (subscription_inactive) or BATCH_RUN_FAILED, error.server_code (the failure_reason) and failure_detail; batch_rerun recovers it once fixed. A paused run has paused:true; one still writing its tasks has ingesting:true.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description goes further by disclosing error semantics (ok:false with BATCH_INSUFFICIENT_CREDITS, BATCH_KEY_CAP_REACHED, AUTH_INVALID, BATCH_RUN_FAILED), server_code/failure_detail fields, and the paused:true / ingesting:true state flags. That is meaningful behavior beyond the structured fields, though it omits things like polling/rate expectations.
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 purpose and return shape, then a compact paragraph covering failure, pause, and ingestion states. Dense but every sentence carries operational information; only the error-code enumeration feels list-heavy.
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 usefully compensates by naming the returned fields, the failure codes, and the paused/ingesting flags, so an agent can interpret a response. It stops short of describing polling behavior or how a non-terminal run should be followed up beyond the rerun 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% and the single job_id parameter is already documented as coming from batch_create or batch_list, so the schema carries the load. The description restates job_id as a returned field but adds no new constraint, format, or lookup semantics for the input.
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 ('Get a Batch job's latest run') and enumerates the returned fields (job_id, run_id, status, stats, job), which separates it from sibling tools like batch_results or batch_list that surface different payloads. The status enum values are spelled out, so an agent knows exactly what this tool reports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for interpreting results and routes a failed run to batch_rerun as the recovery path. However, it never explicitly contrasts itself with batch_wait, batch_list or batch_results (e.g. 'use batch_wait to block until completion'), so the when-to-use boundary is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_waitARead-onlyInspect
Poll a Batch job until its run ends (completed, stopped or failed) or pauses, and return its status and stats like batch_status. If the wait runs out first, it returns the current state with ok:true, timed_out:true and a note: call batch_wait again. A paused run returns at once with paused:true (it does not move until batch_resume). A failed run answers ok:false with error.code and server_code (insufficient_credits, subscription_inactive or api_key_cap_reached). Transient poll errors are retried. A call that carries a progressToken gets a progress notification after each poll.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Batch job id returned by batch_create or batch_list | |
| timeout | No | Max wait in seconds (default 50). Many MCP clients cancel a call after 60 s. | |
| timeout_ms | No | Deprecated: the same wait in milliseconds. Use the seconds parameter instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint/openWorldHint/destructiveHint; the description goes well beyond by disclosing the timeout contract (ok:true, timed_out:true, retry note), the paused-run short circuit, the failed-run error envelope with enumerated error.code/server_code values, automatic retry of transient poll errors, and progress notifications when a progressToken is supplied.
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 purpose, then each subsequent sentence covers a distinct outcome (timeout, pause, failure, retries, progress) with no filler. It is a dense single paragraph rather than a scannable structure, which costs it the top mark.
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 available, the description compensates by spelling out the return shape in each branch (ok/timed_out/paused/error.code) and the side-effect behavior around pause and resume. An agent has everything needed to call it and interpret the response.
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 job_id, timeout (default 50, 60s client cancel note) and the deprecated timeout_ms all documented in the schema itself. The description only alludes to the timeout indirectly ('If the wait runs out first') and adds no syntax or unit detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Poll a Batch job until its run ends') and names the exact terminal states (completed, stopped, failed) plus the pause case. It also anchors itself against a sibling by saying it returns status and stats 'like batch_status', letting an agent distinguish the blocking variant from the immediate one.
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 clear operating context: call it when you want to block until the run ends, re-call batch_wait if it times out, and note that a paused run will not advance until batch_resume. It stops short of explicitly saying when NOT to use it (e.g. prefer batch_status for non-blocking polling), so it is strong but not fully routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_batchADestructiveInspect
Execute a sequence of browser actions in a single call against an existing session.
Use this when you already know the full sequence of steps — it reduces round trips and is faster than calling each tool individually.
Actions run sequentially and stop at the first failure unless stop_on_error is false. Each step result is returned in the results array at the same index.
Note: screenshots in batch results are returned as base64 strings inside the JSON; browser_screenshot returns them as images.
A batch can include evaluate, so it can change or delete page state the same way browser_evaluate can.
| Name | Required | Description | Default |
|---|---|---|---|
| actions | Yes | Ordered list of actions to perform. Each action has a 'type' field plus type-specific parameters. | |
| session_id | Yes | Session ID returned by browser_navigate | |
| stop_on_error | No | Stop executing on the first failed action (default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations that mark it destructive/open-world, the description discloses sequential execution, stop-on-first-failure behavior controlled by stop_on_error, results indexed by step, screenshot return format differences from browser_screenshot, and the fact that evaluate steps can mutate or delete 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 front-loaded with the core purpose, then gives usage guidance, execution behavior, result behavior, and one important caveat. Every sentence carries useful information for selection or invocation.
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 complex batch tool with no output schema, the description covers the critical return behavior: per-step results are in an indexed results array, failures stop execution unless configured otherwise, and screenshots are base64 strings. Combined with the rich action schema and annotations, this is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents session_id, actions, and stop_on_error. The description still adds useful semantics about stop_on_error behavior and result indexing, though it does not need to re-document the fully enumerated action schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: execute a sequence of browser actions in a single call against an existing session. It distinguishes itself from the individual browser_* tools by explaining that it reduces round trips and is faster than calling each tool separately.
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 an explicit usage condition: use this when you already know the full sequence of steps. It also names the alternative strategy, calling each tool individually, and explains why batch is preferable in that situation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_checkCInspect
Check a checkbox or radio button.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector of the checkbox or radio element | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the safety profile is covered structurally. The description adds nothing beyond that: no idempotency semantics (what happens if already checked), no failure mode for a bad selector, and no waiting behavior, which matters for a state-mutating browser 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 short sentence with no filler, and the action is front-loaded. Its brevity is under-specification rather than excess, so it is efficient but earns no extra credit.
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 two-parameter tool with full schema coverage, annotations covering the safety profile, and no output schema, this is minimally adequate. An agent can call it correctly, but the relationship to browser_uncheck and error/retry behavior remain undocumented.
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%: both session_id ('Session ID returned by browser_navigate') and selector ('CSS selector of the checkbox or radio element') are fully documented in the schema. The description adds no formatting or resolution detail, 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 ('Check a checkbox or radio button'), which is clearly distinct from siblings like browser_click and browser_fill. It does not, however, name its inverse browser_uncheck, so an agent must infer the boundary itself.
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 when-to-use guidance, no prerequisites, and no mention of the direct alternative browser_uncheck or of browser_click for non-checkbox elements. The purpose sentence implies the use case but the description provides no routing help.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_clear_cookiesBDestructiveInspect
Clear all cookies for the current browser session.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true and readOnlyHint=false, so safety is covered externally. The description adds useful scope by saying it clears all cookies for the current browser session, but it does not mention reversibility, auth requirements, or effects on active pages.
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 that states the action and its scope with no wasted words. It is appropriately sized for a simple browser operation.
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 low complexity, full schema coverage, and annotations that carry the destructive/open-world profile, the description is nearly sufficient for correct invocation. It could be strengthened by naming sibling alternatives, but nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single session_id parameter is fully documented in the schema. The description adds no parameter detail beyond what the schema already provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Clear all cookies for the current browser session.' It clearly differs from browser_get_cookies and browser_set_cookies, though it does not explicitly distinguish itself from the similarly named browser_clear_local_storage 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?
It gives no guidance about when to use this tool versus alternatives such as browser_get_cookies, browser_set_cookies, or browser_clear_local_storage. The intended use is implied only by the tool name and description text.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_clear_local_storageADestructiveInspect
Delete every localStorage entry in the current page context.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=true, so the safety profile is covered. The description usefully confirms the operation is a total wipe ('every entry') limited to the current page context rather than all tabs, but adds nothing about reversibility, permissions, or whether other origin storage is affected.
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 zero redundancy, sized correctly for a one-parameter destructive utility.
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 destructive utility with complete schema coverage, no output schema, and annotations carrying the safety burden, the definition is essentially sufficient. Only the absence of any usage context keeps it short of full 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% for the single session_id parameter, and the schema already documents it as the ID returned by browser_navigate. The description adds no additional parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Delete) and resource (every localStorage entry) scoped to the current page context. An agent can immediately distinguish it from siblings like browser_clear_cookies, browser_set_local_storage, and browser_get_local_storage without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance, no alternatives, and no conditions under which the destructive wipe should be preferred over targeted removal via browser_set_local_storage. Usage is only inferable from the tool name, which is weaker than explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_clickBInspect
Click an element on the page using a CSS selector.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector of the element to click | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds nothing beyond restating the action and selector mechanism; it does not mention potential side effects like navigation or form submission, nor what happens when the element is missing.
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 zero waste. It states the action and method 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 simple click tool with full schema coverage and annotations covering safety and open-world behavior, the description is minimally adequate. It omits prerequisites like needing an active session from browser_navigate and what happens when a selector does not match, though session_id origin is covered by 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 both parameters are fully documented by the schema. The phrase 'using a CSS selector' merely echoes the selector parameter and adds no additional syntax or constraint.
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 (Click), resource (element on the page), and mechanism (CSS selector). It does not explicitly distinguish itself from siblings like browser_type or browser_fill, 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?
No when-to-use or when-not-to-use guidance is provided. It does not mention alternatives such as browser_fill for input or browser_hover for mouseover, leaving the agent to infer from tool names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_closeAInspect
Close a browser session and free all associated resources, including the concurrency slot it holds.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the write/non-destructive profile is covered. The description adds genuinely new context — that closing releases 'all associated resources, including the concurrency slot' — which tells the agent about a quota/rate-limit effect not visible in the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the most important fact (closing frees resources and the concurrency slot) is stated 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 simple one-parameter teardown tool with a rich schema and clear safety annotations, the description is nearly complete. Minor gaps remain — no error/idempotency behavior if the session is unknown or already closed — but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; the single session_id parameter is already documented as 'Session ID returned by browser_navigate'. The description adds nothing beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Close) and resource (a browser session), plus the side effect of freeing resources. It is unmistakable against siblings, though it does not explicitly name a counterpart tool the way the highest-scoring examples do.
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 — the mention of freeing 'the concurrency slot' hints at when to call it (when you are done and need to release capacity), but there is no explicit when/when-not guidance or named alternative. Neither does it say whether it is safe to call on an already-closed session.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_dragCInspect
Drag an element from its current position to a target element.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate | |
| source_selector | Yes | CSS selector of the element to drag | |
| target_selector | Yes | CSS selector of the drop target |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond them: no mention of whether HTML5 drag events fire, whether intermediate mouse moves occur, or what happens when the source or target selector 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 zero padding that states the action and its two endpoints. It is appropriately short, though it is arguably too thin to be maximally useful rather than 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 three-parameter interaction tool with full schema coverage and annotations covering safety, the description is minimally viable. It omits failure behavior, visibility/viewport requirements, and drag-event semantics, which an agent would want before invoking it in a browser session.
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 each of the three parameters is documented in the schema (session_id, source CSS selector, target CSS selector). The description merely restates the source/target relationship without adding format or syntax detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Drag') and resource ('an element') with source and target positions, which clearly separates it from siblings like browser_click and browser_hover. It does not explicitly name those alternatives, but the action 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?
No guidance on when to use this versus browser_click, browser_hover, or browser_evaluate-driven drag scripts, and no prerequisites such as elements needing to be visible or in the viewport. The agent must infer the use case entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_evaluateADestructiveInspect
Execute JavaScript in the browser context and return the result. The script can change or delete the session's page state, such as cookies, storage and form data.
| Name | Required | Description | Default |
|---|---|---|---|
| script | Yes | JavaScript expression or function body to evaluate in the page context | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true and openWorldHint=true, so the bar is lower. The description still earns credit by concretizing the blast radius: cookies, storage and form data can be changed or deleted, which is more actionable than a bare 'destructive' flag. It does not discuss sandboxing, timeouts, or what the return value looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the capability first, the risk second. No filler, no restating the tool name, and the most important caveat is not 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?
No output schema, and the description does say a result is returned, but not in what form (serialized? JSON-safe? errors thrown?). Annotations plus the destructive-state warning cover the safety picture well, so the remaining gap is small.
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 only two parameters, both documented in the schema (script semantics and session_id provenance). The description adds nothing about script syntax, serialization of results, or how errors surface, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Execute JavaScript in the browser context and return the result.' An agent can immediately tell this is the arbitrary-script escape hatch versus the many narrow siblings (browser_click, browser_get_text, etc.). It stops short of naming any sibling it supersedes, so 4 rather than 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?
No when-to-use guidance at all. Given the large set of purpose-built siblings, the description never says to prefer browser_get_text/browser_click and only fall back to browser_evaluate for cases they don't cover. The side-effect warning hints at caution but does not route the agent to an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_fillAInspect
Clear an input field and set its value, replacing what was there (browser_type appends instead).
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | Value to fill in | |
| selector | Yes | CSS selector of the input element | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the write/exploration profile is covered. The description's useful addition is that it clears existing content before setting the value — a nuance not conveyed by destructiveHint=false — but it says nothing about required page state, element type constraints, or what happens on a non-input selector.
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, front-loaded with the operation and immediately followed by the sibling disambiguation. Nothing is redundant and every clause 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 three-parameter, fully schema-documented write tool with annotations covering safety and open-world behavior, the essential routing and semantics are present. Minor gaps remain around error/edge-case behavior (e.g. what happens if the selector matches a non-input element), which keeps it short of a 5.
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 all three parameters are documented in the schema, so the schema carries the burden. The description adds no syntax, format, or selector-interpretation detail beyond what the schema provides — the baseline 3 for full-coverage schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description pairs a specific verb ('Clear ... and set its value') with the resource (an input field) and explicitly contrasts it with the sibling browser_type ('appends instead'). An agent can distinguish this from browser_type without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the alternative tool by name and states the selecting condition: use browser_fill when you want to replace existing content, browser_type when you want to append. This is exactly the when/when-not/alternative guidance the tool needs given the near-identical sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_focusBInspect
Move focus to an element, triggering focus-dependent UI changes.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector of the element to focus | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the agent knows this mutates page state without being 'destructive'. The description adds one genuine behavioral detail — that focus may trigger focus-dependent UI changes (menus, validation, scroll) — but says nothing about what happens with non-focusable elements or timing.
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 compact sentence with the action front-loaded and no wasted words. Nothing could be trimmed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and both required parameters well documented, the description is minimally sufficient. It could go further by stating what occurs on failure or whether the tool waits for the element, but it covers enough for a simple two-param browser action.
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%: both selector and session_id are documented in the schema itself, including that session_id comes from browser_navigate. The description adds no further parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Move focus to an element') and adds a consequence ('triggering focus-dependent UI changes'), so the action is unambiguous. It does not, however, distinguish itself from the many adjacent interaction siblings such as browser_click, browser_hover, or browser_press_key, which an agent may confuse with focusing.
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 focus versus clicking, hovering, or typing into an element. The description implies the purpose but offers no conditions, prerequisites, or exclusions relative to the sibling interaction tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_generate_pdfCRead-onlyInspect
Render the current page as a PDF document.
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Page scale factor (default 1) | |
| landscape | No | Landscape orientation (default false) | |
| session_id | Yes | Session ID returned by browser_navigate | |
| print_background | No | Print background graphics (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered. The description adds nothing beyond that: it doesn't say whether the PDF is returned inline, saved to a path, or downloaded, which is the key behavioral question for a generation 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, front-loaded sentence with no filler. It is efficient, though the brevity contributes to the missing usage and output information rather than being purely a virtue.
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 should explain how the generated PDF is delivered (bytes, URL, file path, download). It omits this entirely, leaving a real gap for an agent that must consume 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 scale, landscape, print_background, and session_id are fully documented in the schema with defaults. The description adds no parameter meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Render) and resource (current page as a PDF document), which is unambiguous. It does not differentiate from the closest sibling, browser_screenshot, which also captures the current page but to an image.
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 choose PDF rendering over browser_screenshot, scrape, or extract, nor any noted prerequisites. The agent must infer the use case entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_accessibility_treeARead-onlyInspect
Get the ARIA accessibility tree of the current page as readable text.
Shows the page structure and the selectors needed to interact with elements, in fewer tokens than a screenshot.
The tree shows all interactive elements (buttons, inputs, links) with their roles, labels, and states — everything needed to drive browser interactions.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, covering the safety profile. The description usefully adds that the output is text enumerating roles, labels and states, but says nothing about behavior on large pages, truncation, or whether it requires the page to be fully loaded.
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 short paragraphs, front-loaded with the core action. There is mild redundancy between the second and third paragraphs, which both describe what the tree contains, but no wasted 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?
With no output schema, the description correctly shoulders the job of describing return contents (roles, labels, states, selectors). It is nearly complete for a read-only single-param tool, missing only edge-case behavior like tree size limits or loading prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single required parameter (session_id) whose schema description is 100% covered ('Session ID returned by browser_navigate'). The description adds no further parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the ARIA accessibility tree of the current page') and characterizes the output as readable text. It implicitly differentiates from the screenshot sibling by noting the token advantage, but it never names an alternative tool 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?
Provides usable context: use it to see page structure and the selectors needed to drive interactions, and it is cheaper in tokens than a screenshot. It stops short of explicit when-not conditions or naming competing siblings like browser_get_html or browser_get_text.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_attributeBRead-onlyInspect
Get the value of a specific attribute on an element.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector of the element | |
| attribute | Yes | Attribute name to retrieve (e.g. 'href', 'src', 'data-id') | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered by structured data. The description adds no behavioral context at all: nothing about behavior when the selector matches multiple elements, when the attribute is absent (null? empty string?), or whether the page must already be loaded.
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 short sentence, front-loaded with the verb and the scope, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description should ideally state the return shape (string value, null/error when missing) and whether the element must exist. For a minimal getter with fully documented parameters and read-only annotations this is adequate but leaves 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 selector, attribute, and session_id are each documented in the schema, including attribute examples ('href', 'src', 'data-id'). The description adds no meaning beyond that, 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?
States a specific verb+resource: retrieving the value of one named attribute on one element. This is distinguishable in principle from browser_get_text and browser_get_html, though the description never names those siblings or contrasts the scope. Clear but not sibling-differentiating.
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 statement of when to use this versus browser_get_html, browser_get_text, browser_evaluate, or browser_query_selector_all. The agent must infer that this is the single-attribute read path from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_cookiesBRead-onlyInspect
Get all cookies for the current page.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the scope of the read ('all cookies, current page') but says nothing about cookie scope semantics (domain vs page), httpOnly inclusion, or output format.
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 short sentence with the verb and scope front-loaded and no filler. Nothing could be removed without losing meaning.
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 tool with full parameter coverage and complete safety annotations, this is close to adequate, but the absence of an output schema means the description should say what is returned (name/value pairs, count, format) and whether the scope is page or domain. The 'current page' framing may mislead on cookie 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?
The sole parameter session_id is fully documented in the schema (100% coverage) as coming from browser_navigate, so the schema already carries the semantics. The description adds no parameter-level detail, which is the expected baseline when schema coverage is complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (cookies) with a scope qualifier (current page), so it is clearly separable from browser_set_cookies and browser_clear_cookies by verb. The phrase 'current page' is slightly imprecise since cookies are domain-scoped, but the intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus alternatives such as browser_local_storage, browser_set_cookies, or reading cookies inside browser_evaluate. No prerequisites or context selection criteria are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_htmlCRead-onlyInspect
Get the HTML source of an element or the full page.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | No | CSS selector of the element (omit for full page HTML) | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond the factual operation: no note on invalid-selector errors, on result size for full-page HTML, or on what happens if the element isn't present.
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 scope contrast (element vs full page) is stated immediately. It is slightly redundant with the schema's selector description but wastes no space.
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 two-parameter read-only tool with a fully described schema, the description is minimally sufficient, and no output schema exists so return values need not be explained. It nonetheless omits practical caveats (large payloads, invalid selectors) that an agent would benefit from.
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 the selector description already stating 'omit for full page HTML'. The description's 'element or the full page' phrasing mirrors the schema without adding format or syntax detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and resource ('HTML source'), and clarifies the two scopes (element vs full page). It distinguishes itself from browser_get_text and browser_get_attribute implicitly, though it never names those siblings 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?
No when-to-use or when-not-to-use guidance, and no routing to alternatives such as browser_get_text for visible text or browser_get_attribute for a single attribute. The agent gets no help choosing among the many sibling getters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_local_storageARead-onlyInspect
Read one localStorage value in the current page context.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Storage key to read | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so safety is covered. The description adds the 'current page context' scoping detail, but does not say what happens if the key is missing or the page isn't loaded. With annotations doing the heavy lifting, a 3 fits.
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 no waste, front-loaded with verb and resource. The 'current page context' qualifier earns its place by scoping behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read tool with full schema coverage and annotations declaring safety, the description is nearly complete. The only minor gap is not stating the result when a key is absent (null/error), which would help an agent interpret the call.
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 both session_id and key are fully documented in the schema, and the description adds no format or syntax detail beyond it. The phrase 'one localStorage value' subtly confirms single-key semantics, matching the 'key' parameter, but this is baseline-level added 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?
States a specific verb (Read) and resource (localStorage value) with scope qualifier 'one' and 'current page context'. This distinguishes it from browser_set_local_storage and browser_clear_local_storage, which mutate rather than read, though neither sibling is 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?
Usage is implied by the read-vs-write/clear split among the localStorage siblings, but the description never states when to prefer this tool or what conditions apply (e.g., must be on a page, key must exist). No explicit alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_textBRead-onlyInspect
Get the visible text content of an element or the entire page body.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | No | CSS selector of the element (omit for full page body text) | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description does add one genuine behavioral detail — only *visible* text is returned — but says nothing about hidden elements, whitespace normalization, or whether a missing selector/text yields an error or empty string.
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 14-word sentence with zero filler, and the primary scope (element vs. whole page) is front-loaded. Nothing needs trimming and nothing is 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 two-parameter, read-only tool the definition is minimally sufficient, but with no output schema it never says what comes back (a plain string? concatenated visible text? empty on no match), and it omits the sibling routing that a crowded namespace like this one clearly needs.
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 selector parameter already documents 'CSS selector of the element (omit for full page body text)' and session_id points back to browser_navigate. The description's 'entire page body' clause merely restates the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the visible text content') plus the two scopes (a single element or the entire page body). It implicitly distinguishes itself from browser_get_html by specifying 'text content', but it never names browser_get_html, browser_get_attribute, or extract as the alternatives an agent must choose between.
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 when-to-use or when-not-to-use guidance. Nothing tells the agent to prefer this over browser_get_html when only readable text matters, or over browser_get_attribute for a single attribute, and no prerequisites (e.g. an active session from browser_navigate) are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_titleARead-onlyInspect
Get the title of the current page.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds nothing beyond them (no note about empty titles, iframes, or timing after navigation), but nothing is contradicted for a simple read.
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 zero filler. It is as short as it can be while still naming verb and resource, though it offers no structural cues for the workflow.
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-parameter, read-only accessor with full schema coverage and no output schema, naming the returned value (the page title) is sufficient for correct invocation. Only workflow hints 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% and the lone session_id parameter is documented in the schema as originating from browser_navigate, so the description carries no additional parameter burden. 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?
Specific verb ('Get') plus resource ('the title of the current page'), which cleanly separates it from siblings such as browser_get_url, browser_get_html, or browser_get_text. It does not explicitly name those siblings, so full differentiation is left to the agent.
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: the schema note that session_id comes from browser_navigate hints at the workflow, but the description states no when-to-use, prerequisites, or alternatives. For a trivially scoped tool this is adequate but thin.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_get_urlBRead-onlyInspect
Get the current URL of the browser session.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is fully covered. The description adds only the 'current' qualifier (live session state) and nothing about return format or failure modes, so it neither contradicts nor substantially enriches 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 with zero filler. Nothing redundant or padded.
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 getter with a fully documented single parameter, the definition is nearly complete; the implied return value (the URL string) is obvious from the name and no output schema is needed. It could be marginally stronger by noting it reflects the live page state.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter and schema description coverage is 100% — the schema itself explains that session_id comes from browser_navigate. The description adds no parameter detail, which is the expected baseline when the schema does the work.
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 ('Get') and resource ('current URL of the browser session') make the tool's function unambiguous. It implicitly distinguishes itself from siblings like browser_get_title or browser_get_html, though it never names an alternative 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?
No when-to-use guidance, no prerequisites, and no mention of alternatives such as browser_get_title or browser_navigate. The agent must infer that this is called to read the current page location, likely after a navigation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_go_backBInspect
Navigate back to the previous page in the browser history.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare openWorldHint=true, readOnlyHint=false, and destructiveHint=false, so the safety profile is covered elsewhere. The description adds no behavioral context of its own: nothing about what happens when there is no prior history, whether it errors, or whether it waits for the page to load. It does not contradict the annotations, but it contributes nothing beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single nine-word sentence with the action front-loaded and zero filler. Nothing needs trimming.
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-parameter, output-schema-less navigation tool the description is mostly sufficient, but it omits edge-case behavior (no back entry available, failure signalling) that an agent would need before calling it in a history-dependent flow.
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 parameter session_id is already documented in the schema as 'Session ID returned by browser_navigate'. The description adds no meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Navigate back to the previous page in the browser history.' This distinguishes it implicitly from browser_go_forward and browser_navigate. However, it never names those siblings, so it falls 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?
Usage is only implied by the purpose statement – an agent can infer it is used when it wants to return to a prior page. It gives no explicit when-to-use, when-not-to-use, or alternative routing (e.g., use browser_navigate or browser_go_forward instead).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_go_forwardBInspect
Navigate forward to the next page in the browser history.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, so the safety profile is covered externally. The description adds nothing beyond them: it does not say what happens if there is no forward history, whether the page reloads or triggers loads, or that session_id must reference an active session.
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 short sentence with zero filler, front-loading the action. Nothing is padded or 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?
For a one-parameter navigation tool with annotations covering the safety profile, the description is minimally sufficient. It omits the no-forward-history case and any indication of the resulting page state, but no output schema exists and the schema documents the param, so the gap is small rather than critical.
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 single session_id parameter is documented in the schema as 'Session ID returned by browser_navigate'. The description adds no additional meaning about the parameter, 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?
States a specific verb+resource ('Navigate forward ... in the browser history'), so the action is unambiguous. It does not explicitly name or contrast with siblings like browser_go_back or browser_navigate, but the direction word 'forward' implicitly separates it from the back-facing tool.
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 implied by 'forward in the browser history' — an agent can infer this only applies when prior navigation has created forward history. There is no explicit statement of prerequisites (e.g., a prior browser_go_back or navigation), no failure-mode guidance, and no routing to alternatives such as browser_navigate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_hoverBInspect
Move the mouse cursor over an element to trigger hover effects.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector of the element to hover over | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, covering the safety profile. The description adds only the mechanical action and does not explain side effects (DOM/CSS state changes, whether a subsequent click is needed), timing/wait requirements, or that it returns nothing useful.
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 tight sentence with the action front-loaded and no redundant or filler text. Nothing is padded.
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, non-destructive action with full schema coverage and no output schema, the description is sufficient to call the tool correctly. It could note that hover effects are transient and typically require a follow-up action, but the gap is minor.
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%: both selector and session_id are fully documented in the schema, including that session_id comes from browser_navigate. The description adds no syntax or format detail beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('move the mouse cursor over an element') plus the intended effect ('trigger hover effects'), which distinguishes it in practice from browser_click, browser_focus, and browser_drag. It does not explicitly name or contrast with those siblings, so it falls 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 phrase 'to trigger hover effects' hints at intent, but there is no guidance on when to prefer hover over siblings like browser_click or browser_focus, no prerequisites, and no exclusions. An agent must infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_new_tabAInspect
Open a new browser tab. Returns a tab_id to use with browser_switch_tab.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to open in the new tab (opens blank tab if omitted) | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, which cover the mutation and safety profile. The description adds that a tab_id is returned for use with browser_switch_tab, useful context but limited. No additional behavioral traits like permissions or persistence are disclosed.
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 with zero waste. The core action and return value are front-loaded, making it 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?
Given the tool's simplicity, full schema coverage, and presence of annotations, the description is complete. It covers purpose and return value (compensating for the missing output schema) and links to the follow-up 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 description coverage is 100%, so parameters are fully documented in the schema. The description adds no further meaning about url or session_id. 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: 'Open a new browser tab.' Clear and distinct from most siblings. However, it doesn't explicitly contrast with browser_navigate, which also involves opening a URL, so the differentiation is only partial.
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?
Mentions that the returned tab_id should be used with browser_switch_tab, implying a workflow. But it offers no explicit when-to-use versus alternatives like browser_navigate, nor any exclusions or prerequisites beyond what the schema shows.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_press_keyCInspect
Press a keyboard key. Examples: "Enter", "Tab", "Escape", "ArrowDown", "Control+a".
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Key to press (e.g. "Enter", "Tab", "Escape", "ArrowDown", "Control+a") | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. Beyond that the description adds no behavioral context: no mention of focus requirements, whether the key is dispatched to the page or the browser chrome, or any side effects such as form submission on Enter.
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, front-loaded with the action. It is efficiently sized, though the example enumeration is verbatim duplication of the schema and earns little of its space.
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 two-parameter tool with full schema coverage and safety annotations, the definition is minimally adequate. It leaves a real gap by not stating that the key is delivered to the focused element or noting modifier-combo syntax beyond the schema examples.
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 both session_id and key documented inline, so the baseline is 3. The description's example list merely repeats the identical examples already present in the key property description, adding no new meaning.
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 ('Press a keyboard key'), which is unambiguous and distinct from the click/type/fill siblings. However, it does not draw the boundary against browser_type or browser_fill, so the agent must infer the difference itself.
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 only supplies example key strings; it never says when to use this tool rather than browser_type, browser_fill, or browser_click, nor does it mention that a key event is sent to the currently focused element. Usage must be inferred entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_query_selector_allBRead-onlyInspect
Find all elements matching a CSS selector and return their text, HTML, and attributes.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector to query | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the useful fact that it returns text, HTML, and attributes, but says nothing about behavior on zero matches, whether it waits for elements, result caps, or pagination.
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 well-formed sentence with no filler, and the operation ('find all matching elements') is front-loaded ahead of the return payload. It is efficient, though it could spend one more clause on disambiguation rather than staying this terse.
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 sensibly enumerates the returned fields (text, HTML, attributes), which is genuinely needed. However, for a browser-query tool in a large sibling set, it omits key context such as empty-result behavior and whether it requires the page to be already loaded.
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 both session_id and selector are already documented at the schema level. The description adds no syntax, format, or defaulting detail beyond what the schema provides, making 3 the correct 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 description gives a specific verb ('find all elements matching a CSS selector') plus the resource and the payload returned ('text, HTML, and attributes'), so an agent knows exactly what it does. It does not, however, distinguish itself from near-neighbours like browser_get_text or browser_get_html, which also retrieve element content.
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 statement of when to prefer this over browser_get_html, browser_get_text, browser_get_attribute, or browser_wait_for_selector. The intended use (bulk multi-element retrieval by selector) must be inferred from the name and the word 'all'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_reloadBInspect
Reload the current page of a browser session.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, so safety basics are covered. However, the description adds no behavioral context such as whether it waits for load, resubmits form data, or requires an active session beyond the parameter name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence with no wasted words and is front-loaded with the core action. It is appropriately sized for a simple 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 low-complexity, single-parameter tool with annotations and no output schema, the description is largely sufficient. It could mention the need for an existing session or post-reload behavior, but the schema and annotations cover the essentials.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter, and the schema provides 100% description coverage with 'Session ID returned by browser_navigate'. The description does not mention the parameter, so 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 (Reload) and resource (current page of a browser session), making the operation clear. It does not explicitly distinguish itself from sibling tools like browser_navigate or browser_go_back, so it falls 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?
No guidance is provided on when to use this tool versus alternatives such as browser_navigate, browser_go_back, or browser_wait. The description only states what it does, leaving usage context 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_screenshotARead-onlyInspect
Take a screenshot of the current page or a specific element. Use for visual verification or when the accessibility tree is not sufficient.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | No | CSS selector to capture only a specific element (overrides full_page) | |
| full_page | No | Capture full page including content below the fold (default false) | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds use-case context but does not disclose the return format (image bytes vs. URL) or any capture limits, which is a meaningful omission for a screenshot 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 tight sentences with no filler; the action is front-loaded and the routing condition follows immediately. Every clause 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 3-parameter read-only tool with full schema coverage and annotations, the description covers purpose and usage adequately. The main remaining gap is the absence of any note on what the tool returns, which matters more here because there is no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so selector, full_page, and session_id are fully documented in the schema. The description's phrase 'current page or a specific element' only loosely maps to those parameters and adds no syntax or default details, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Take a screenshot') with explicit scope ('current page or a specific element'). It also names the sibling alternative (accessibility tree), so an agent can distinguish it from browser_get_accessibility_tree and browser_get_html without opening 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?
Gives a clear condition for use ('visual verification') and an explicit alternative trigger ('when the accessibility tree is not sufficient'). It stops short of stating when not to use it (e.g., prefer text extraction for simple content), but the routing guidance is solid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_scrollCInspect
Scroll the page in a given direction.
| Name | Required | Description | Default |
|---|---|---|---|
| distance | No | Pixels to scroll (default 500) | |
| direction | Yes | Scroll direction | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare openWorldHint=true and destructiveHint=false, but the description adds no additional context such as whether the scroll completes synchronously, whether it triggers lazy loading, or how it interacts with the viewport state. The one sentence merely restates the 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?
A single front-loaded sentence with no wasted words, though the phrase 'in a given direction' is mildly redundant with the direction parameter already in 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?
For a simple scroll action with full schema coverage, the definition is minimally viable, but it omits any note about whether scrolling is instant or animated, whether lazy content is triggered, or what the call returns (no output schema exists). An agent can call it, but not fully predict the effect.
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% – direction's enum, the distance default of 500 pixels, and session_id's provenance are all documented in the schema. The description adds nothing beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (scroll) and resource (the page) and the direction parameter, so an agent knows exactly what the tool does. It does not, however, distinguish itself from adjacent viewport tools such as browser_press_key or browser_evaluate, which can also move the page.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance: nothing says to call this before a screenshot, when content is below the fold, or that browser_wait may be needed for lazy-loaded content. No alternatives or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_select_optionCInspect
Select an option from a dropdown element.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | Value of the option to select | |
| selector | Yes | CSS selector of the <select> element | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnlyHint=false, destructiveHint=false, and openWorldHint=true, so the safety profile is covered structurally. The description adds nothing beyond that: it does not say whether change events fire, how an invalid value or missing option is handled, or whether the selection is verified. For a mutation tool this is a notable gap.
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 no filler and the key information (select, option, <select> dropdown) front-loaded. It is efficient, though its brevity edges toward under-specification rather than pure 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 simple three-parameter tool with full schema coverage, annotations, and no output schema, the description covers the core action adequately. It omits failure behavior (option not found, hidden/disabled options) and event side effects, which an agent calling a stateful browser mutation would benefit from knowing.
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 value, selector, and session_id all documented, so the schema carries the parameter burden and the baseline is 3. The description adds only a marginal clarification that the selector targets a <select> element rather than any arbitrary node.
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?
Names a specific verb ('select') and a specific resource ('option from a <select> dropdown element'), which is unambiguous on its own. It stops short of differentiating from near-siblings like browser_click or browser_fill, which could also target a select element, so it is clear but not sibling-aware.
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 statement of when to use this instead of browser_click, browser_type, or browser_fill, nor any prerequisite such as the select needing to be present or the session needing a prior browser_navigate. Usage context is left entirely to inference from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_set_cookiesADestructiveInspect
Set one or more cookies in the browser session. A cookie with the same name, domain and path replaces the existing one.
| Name | Required | Description | Default |
|---|---|---|---|
| cookies | Yes | Array of cookie objects to set | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the agent knows this mutates state. The description adds a genuinely useful behavioral detail beyond that: the name/domain/path key determines replacement of an existing cookie, telling the agent what gets overwritten. It stops short of covering effects on subsequent requests or session persistence.
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, zero padding, with the core action stated first and the overwrite rule as a supporting detail. Nothing is redundant with the schema or annotations.
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 2-parameter mutation tool with full schema coverage, rich annotations, and no output schema, the description covers the essential behavior including overwrite semantics. Only minor gaps remain (session prerequisites, effect on in-flight navigation), which are not critical for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters, and the nested cookie object fields (expires, secure, http_only, etc.) are fully typed in the schema. The description adds no parameter-level detail beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ("Set") and resource ("cookies") scoped to "the browser session," so the operation is unambiguous. It does not explicitly name or contrast with siblings like browser_get_cookies or browser_clear_cookies, but the overwrite clause implicitly separates it from those read/clear operations.
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 reach for this tool versus alternatives, nor any stated prerequisites (e.g., that a session_id from browser_navigate must exist first). Usage is only inferable from the tool name and the session mention.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_set_local_storageADestructiveInspect
Write one localStorage value in the current page context. An existing value under the same key is replaced.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Storage key to write | |
| value | Yes | Value to store | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, and openWorldHint=true. The description adds genuinely new context beyond those flags by stating that an existing value under the same key is replaced, which clarifies the overwrite semantics an agent needs 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?
Two short sentences, front-loaded with the operation and followed by the one behavioral caveat. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter write tool with full schema coverage and annotations carrying the safety profile, the description covers purpose and overwrite behavior. Only the session/prerequisite context is left implicit, which is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all three parameters documented in the schema itself. The description adds no syntax, format, or constraint detail beyond what the schema 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?
States a specific verb (write) and resource (localStorage value) with scope (current page context). This cleanly separates it from browser_get_local_storage, browser_clear_local_storage, and browser_set_cookies without needing to name them.
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 implied by 'current page context' and the session_id parameter, but the description never states when to prefer this over alternatives like browser_evaluate or browser_set_cookies, nor any prerequisite such as requiring an active navigated session.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_switch_tabCInspect
Switch focus to a different browser tab.
| Name | Required | Description | Default |
|---|---|---|---|
| tab_id | Yes | Tab ID returned by browser_new_tab | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, and the description adds nothing beyond restating the action. It does not explain side effects, such as whether focus persists for subsequent commands or whether switching invalidates other handles, which is meaningful for a stateful browser 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 tight sentence with no filler and the purpose front-loaded. It is efficient, though it is so terse that it borders on under-specification rather than genuine 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 simple two-parameter tool with no output schema, the description covers the core action adequately. It omits error/staleness behavior and the relationship to browser_new_tab, which an agent would benefit from knowing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters (session_id, tab_id) are documented in the schema, so the baseline is 3. The description adds no format, constraint, or provenance detail beyond what the schema already supplies.
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 (switch) and resource (browser tab) with the notion of focus, so the action is unambiguous. However, it does not distinguish itself from siblings like browser_new_tab, which also deals with tabs, leaving the agent to infer the difference.
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 when-to-use guidance, no prerequisites (e.g., that the tab must already exist), and does not reference alternatives such as browser_new_tab. Usage must be inferred entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_typeAInspect
Type text into an input element. Appends to existing content unless clear_first is set.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to type | |
| selector | Yes | CSS selector of the input element | |
| session_id | Yes | Session ID returned by browser_navigate | |
| clear_first | No | Clear existing content before typing (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, so safety is covered. The description adds a genuinely useful behavioral detail beyond the annotations: content is appended by default rather than replaced, unless clear_first is set. It omits event/focus behavior, but that is a reasonable gap given annotation coverage.
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, front-loaded sentences with no filler. The primary action comes first and the key behavioral caveat second, so every sentence 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 simple typing tool with full schema coverage and annotations covering the safety profile, the description is largely sufficient and no output schema means return values need no explanation. Minor gaps around focus/wait behavior remain but are not critical to correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters, which sets the baseline at 3. The description reinforces the clear_first parameter by explaining the default append behavior, but adds no format, syntax, or edge-case detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Type text into an input element'), making the core action immediately clear. It also implicitly differentiates from the sibling browser_fill by describing append semantics, but it never names that sibling or explicitly contrasts the two, 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?
Usage is only implied: the note about appending unless clear_first is set hints at when this tool is appropriate versus a value-setting tool. There is no explicit when-to-use, when-not-to-use, or named alternative, leaving the agent to infer the choice between browser_type and browser_fill.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_uncheckAInspect
Uncheck a checkbox, found by CSS selector, in a browser session.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector of the checkbox element | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, so the agent knows this is a non-destructive mutation. The description adds only the CSS-selector locating method and adds nothing about behavior when the element is not a checkbox, is already unchecked, or is missing.
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 the action first and the qualifiers after; no filler, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, simple mutation tool with annotations covering safety and full schema coverage, the description is essentially sufficient. Minor gaps remain around failure behavior and whether the target must be specifically a checkbox, but nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (selector, session_id) are already documented in the schema. The description restates the selector idea but adds no syntax, format, or edge-case detail beyond what the schema provides, making the 3 baseline correct.
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 ("Uncheck a checkbox") plus the targeting mechanism (CSS selector) and context (browser session), which clearly separates it from browser_check. It never names that sibling, so differentiation is implied by the verb rather than stated.
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 purpose implies when to use it (when a checkbox needs unchecking), but there is no explicit guidance, no prerequisite that a session must already exist, and no pointer to browser_check for the inverse operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_waitARead-onlyInspect
Wait for a fixed duration. browser_wait_for_selector waits only until an element appears.
| Name | Required | Description | Default |
|---|---|---|---|
| ms | Yes | Milliseconds to wait (max 30000) | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds that the wait is unconditional/fixed rather than event-driven, which is useful, but says nothing about blocking behavior, the 30s ceiling, or what happens if the session is closed. Adequate but thin against an already-covered annotation set.
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, zero filler, with the core semantics front-loaded and the disambiguation second. 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 two-parameter tool with full schema coverage, annotations, and no output schema, the description covers the essentials. It omits only minor operational detail such as the blocking nature of the call and the maximum-duration caveat, which is already 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%: both ms and session_id are documented in the schema, including the 30000 maximum. The description adds no formatting, units, or default information beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('wait') and the scope ('fixed duration'), and immediately contrasts with the sibling browser_wait_for_selector. An agent can distinguish this tool from the selector- and navigation-based wait tools without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence gives the selecting condition by describing what the alternative does ('waits only until an element appears'), which implies this tool is for unconditional fixed delays. It is clear context, but it never states explicitly when to prefer a fixed sleep or warns about its cost, so no full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browser_wait_for_selectorBRead-onlyInspect
Wait until an element matching the CSS selector is stable in the DOM. Set visible=true to also require the element to be visible (not hidden).
| Name | Required | Description | Default |
|---|---|---|---|
| visible | No | Also require the element to be visible, not just present in the DOM (default false) | |
| selector | Yes | CSS selector to wait for | |
| session_id | Yes | Session ID returned by browser_navigate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds genuine behavioral context by defining 'stable in the DOM' as the wait condition and explaining the visible flag's effect, but it omits timeout behavior, what happens when the condition is never met, and any error/return semantics.
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 with zero filler, and the core wait condition is front-loaded before the optional modifier. Every clause 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 three-parameter wait primitive with no output schema, the description covers the condition and the optional flag but is silent on the most operationally important unknown: what happens on timeout or if the element never becomes stable, and whether the call throws or returns a status. Annotations handle safety, so the gap is narrow but real.
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 session_id, selector, and visible are all documented in the schema itself. The description's restatement of the visible flag duplicates the schema text and adds no syntax, format, or edge-case detail beyond it.
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) and a specific resource (an element matching a CSS selector), with the exact condition being waited on (DOM stability). This clearly separates it from browser_wait_for_navigation, but the description never names or contrasts with the other wait siblings (browser_wait, crawl_wait, batch_wait), leaving differentiation to the tool name alone.
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 when-to-use or when-not-to-use guidance, and no mention of the alternative wait tools that exist in the sibling set. The agent must infer from the name that this is the right primitive before interacting with a dynamic element.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_contentARead-onlyInspect
Read the stored page of one URL a crawl kept, in the crawl's output_format. Works only for crawls created with an output_format, and only for results whose content_status is fetched.
Pass crawl_id and content_id: a content id, or content_url from a crawl_results row. Returns the page as stored — raw HTML for output_format "html", Markdown for "markdown" — cut to max_chars (default 20000); a final note says when it was cut. To read a page the crawl did not store, use scrape on its URL instead.
| Name | Required | Description | Default |
|---|---|---|---|
| crawl_id | Yes | Crawl id returned by crawl_create (c_…) | |
| max_chars | No | Max characters of the page to return (default 20000) | |
| content_id | Yes | A content id (ct_…), or content_url from a crawl_results row; its last path segment is the id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint=false, and openWorldHint, but the description adds substantial behavioral context: conditional availability based on crawl output_format and content_status, exact return formats (raw HTML vs Markdown), max_chars truncation with default 20000, and a final note when truncation occurs.
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 front-loaded with the core purpose, then follows with prerequisites, output behavior, and the alternative. Every sentence earns its place with no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description fully explains what is returned, in what format, how truncation works, and under what crawl conditions the tool can be used. It also routes to the correct alternative, leaving no critical gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents crawl_id, content_id, and max_chars thoroughly. The description mostly repeats the same parameter information (content_id can be a content id or content_url from a crawl_results row; max_chars default 20000), adding little beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: reading a stored page of a URL from a crawl, in the crawl's output_format. It distinguishes itself from siblings by naming scrape as the tool for pages the crawl did not store, and by referencing crawl_results rows for content_id.
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 states when the tool works: only for crawls created with an output_format, and only for results whose content_status is fetched. It also names the alternative (scrape) for pages not stored by the crawl, making the selection decision unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_createAInspect
Start a crawl from one URL (Zenrows Crawl API). Crawl follows the links in each page's HTML up to depth hops (no depth limit when depth is omitted), keeps the URLs that match include_patterns / exclude_patterns, and stays on the start URL's registrable domain (subdomains count).
Use crawl when you have one start page (a listing, category, blog index) and need the URLs behind it, optionally with each page's HTML. For a single page, use scrape.
Each page fetched is billed as one scrape on this account; max_pages bounds the cost (default 100), max_items bounds how many URLs are kept (default 100). Without depth, the crawl keeps following links until max_pages or max_items stops it or nothing is left to open, so set max_pages to what you are willing to spend. The start page itself is never a result, but its fetch is billed: a crawl whose include_patterns / exclude_patterns match nothing still costs that one scrape. A crawl whose pages held nothing new to follow (no link, only links to other sites, or only links the patterns reject) ends completed with no results and no error. When patterns are set, check them against the URLs the start page links to. Set output_format "html" or "markdown" to also store each kept URL's page, then read it with crawl_content.
Returns crawl_id, status and the crawl (with coverage) at once; the crawl runs asynchronously. Call crawl_wait, then crawl_results. Set idempotency_key to make a retry safe: the same key returns the crawl the first request created instead of starting another. CRAWL_NOT_ENABLED: Crawl is not enabled for this account; do not retry. CRAWL_TOO_MANY_CRAWLS: the account has reached its limit of active jobs (3 by default), shared with its Batch jobs; retry after retry_after seconds.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Start URL: a public http(s) page, such as a listing or category page | |
| depth | No | Link hops to follow from the start URL. 1 returns the start page's links; 2 also opens those. Omit for no depth limit: the crawl follows links until max_pages or max_items stops it. | |
| discovery | No | How the crawl finds the URLs it follows on each page it walks. ['links'] follows the links in each page's HTML, and is what a crawl runs with when you omit this. | |
| max_items | No | Stop once this many URLs are kept (default 100) | |
| max_pages | No | Stop once this many pages are fetched, each billed as one scrape (default 100). With output_format, every kept URL's page counts too. | |
| output_format | No | 'html' or 'markdown' also stores each kept URL's page for crawl_content, as fetched or converted to Markdown. Omit for URLs only. | |
| idempotency_key | No | Sent as the Idempotency-Key header. Reusing a key returns the crawl it created; reusing it with a different body is CRAWL_INVALID_REQUEST. | |
| exclude_patterns | No | Drop URLs containing any of these substrings, even if they match include_patterns | |
| include_patterns | No | Keep only URLs containing at least one of these substrings, e.g. ["/product/"] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the read/write/open-world profile; the description adds the cost model ('Each page fetched is billed as one scrape'), the defaults (max_pages/max_items=100), non-obvious edge cases (start page never a result but still billed; a crawl matching nothing still costs one scrape; empty crawls end completed with no error), and two named failure codes with recovery guidance — far beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Long but dense and front-loaded: the core purpose and cost warning come first, error codes last. Nearly every sentence carries operational information, though the billing/cost points are restated more than once and could be tightened.
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 an async, mutable, open-world tool with no output schema, the description supplies return shape (crawl_id, status, crawl with coverage), the async follow-up chain (crawl_wait → crawl_results), and the error-code table. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description still adds real semantic value: the cost implication of max_pages, the interaction between output_format and crawl_content, and the retry contract for idempotency_key. It does not, however, add anything for parameters the schema leaves thin (discovery, include/exclude syntax).
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 ('Start a crawl from one URL'), then precisely describes the mechanism: depth hops, pattern filtering, registrable-domain confinement. It explicitly names the sibling it is not ('For a single page, use scrape'), so an agent can distinguish it without opening another 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?
Gives explicit when-to-use ('one start page — a listing, category, blog index — and need the URLs behind it'), the alternative ('scrape' for a single page), and the follow-up workflow ('Call crawl_wait, then crawl_results'). Exclusions and the pattern-checking advice ('check them against the URLs the start page links to') are also present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_downloadAInspect
Save every result of a crawl to one local file, as JSON lines: url, content_status and, once fetched, content (the page). Returns the file's path and line count, not the results, so a crawl of any size costs one small reply. Read the file with your own tools.
The file goes to path when given (a relative path inside ~/.zenrows/crawls; an absolute path or one that leaves that folder fails with INVALID_PATH), else ~/.zenrows/crawls/<crawl_id>.jsonl. An existing file is kept and the call fails with FILE_EXISTS unless overwrite is true.
On a running crawl the file holds only what was kept so far: download again once crawl_wait says it ended. After crawl_stop, pages in flight can still add lines for up to 10 minutes: the reply says so with partial: true. On the hosted server no file is written: the reply gives the download URL and a command to run where your API key is set.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | File to write, relative to ~/.zenrows/crawls (default <crawl_id>.jsonl) | |
| crawl_id | Yes | Crawl id returned by crawl_create (c_…) | |
| overwrite | No | Replace the file if it exists (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: exact path resolution rules (~/.zenrows/crawls vs. absolute paths failing with INVALID_PATH), FILE_EXISTS behavior unless overwrite=true, partial:true semantics for in-flight pages after stop, and the hosted-server fallback returning a URL plus a command. This is rich, non-obvious operational detail an agent could not infer.
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?
Dense but front-loaded: the purpose and cheap-reply rationale come first, then path/overwrite rules, then lifecycle caveats. Every sentence carries information, though the three stacked paragraphs are at the upper edge of what's comfortable to parse.
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 carries the return-value burden and does so explicitly ('Returns the file's path and line count'). Error cases, partial results, and the hosted-server variant round out a complete picture for a 3-parameter write 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 meaning: path is relative to ~/.zenrows/crawls, an absolute or escaping path fails with INVALID_PATH, and overwrite's default-false FILE_EXISTS interaction is spelled out. The crawl_id parameter is not elaborated but the schema already covers it (c_…).
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 — 'Save every result of a crawl to one local file, as JSON lines' — and immediately clarifies the unusual return value ('the file's path and line count, not the results'). An agent can distinguish this from crawl_results/crawl_content without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the context for re-invocation ('download again once crawl_wait says it ended'), the post-stop caveat with crawl_stop, and the hosted-server case where no file is written at all. What's missing is an explicit statement of when to prefer this over crawl_results; the contrast ('costs one small reply' vs. reading the file yourself) 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.
crawl_getARead-onlyInspect
Get a crawl and one page of the URLs it kept: crawl_id, status (running, completed, stopped, failed), the crawl (with coverage: pages_fetched, pages_failed, items_found), results and next_cursor.
completed with stop_reason max_items / max_pages means a limit ended it; stopped with stop_reason user means crawl_stop ended it; stopped with no stop_reason and error.code insufficient_credits or api_key_cap_reached means the account ran out of credits or the API key hit a credit cap (the URLs kept before that stay readable); completed with no results and no error means the crawl's pages held nothing new to follow; when include_patterns / exclude_patterns are set, check them against the URLs the start page links to. failed carries error.code and error.detail: seed_unreachable means the start URL could not be fetched or returned an empty page; no_items_found means the crawl read the start page but found no data it could use, so it had nothing to follow; start from a listing or product page. A failed crawl, and a stopped one with an error, answer ok: false: error.code is CRAWL_INSUFFICIENT_CREDITS or CRAWL_KEY_CAP_REACHED (the codes crawl_create gets on a 402) when credits ended it, failed or stopped, else CRAWL_FAILED; error.server_code is the crawl's error.code. Pass next_cursor as cursor for the next page; while the crawl runs, next_cursor is never null. To read many pages at once, use crawl_results.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Results in this page (default 100, max 10000) | |
| cursor | No | next_cursor from a previous crawl_get call, to continue from there | |
| crawl_id | Yes | Crawl id returned by crawl_create (c_…) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld annotations by decoding every status (running/completed/stopped/failed), the meaning of each stop_reason, credit-exhaustion cases, empty-result semantics, and the ok:false error codes. This is the behavioral context an agent needs and cannot get from 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 first sentence front-loads the purpose well, but the remainder is a dense run-on block mixing statuses, stop_reasons, and error codes without bullets or headings, which hurts scannability. It is informative but over-packed rather than tight.
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 carries the full burden and does so thoroughly: it details the returned fields, every status/stop_reason combination, error-code semantics, and pagination behavior. An agent has everything needed to call and interpret 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 coverage is 100% so the baseline is 3, and the description adds the key relational detail that next_cursor from a prior call is passed as cursor and that next_cursor is never null while a crawl runs. It does not elaborate on the limit parameter beyond the schema's default/max.
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+resource (get a crawl plus one page of kept URLs) and enumerates the returned fields (crawl_id, status, coverage, results, next_cursor). It explicitly differentiates itself from the sibling crawl_results for multi-page reads.
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?
Names the alternative crawl_results and the condition that selects it ('to read many pages at once'), and explains how to continue paging via next_cursor/cursor. It does not, however, distinguish itself from crawl_wait or crawl_list, so sibling routing is not fully covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_listARead-onlyInspect
List this account's crawls, newest first, with status and coverage (no results). Pass next_cursor as cursor for the next page; next_cursor is absent on the last page.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Crawls per page (default 20, max 100) | |
| cursor | No | next_cursor from a previous crawl_list call |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, openWorldHint=true, destructiveHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: result ordering, that entries are summary-only, and that next_cursor is absent on the last page, which is what an agent needs to terminate a paging loop.
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, front-loaded with what the tool returns before the paging mechanics. No filler, no restatement of the tool name or annotations.
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 carries the return-value burden and does so: shape (status and coverage), ordering (newest first), exclusions (no results), and the cursor contract. Nothing an agent needs to invoke and iterate this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description goes slightly further by spelling out the paging contract ('pass next_cursor as cursor') and the last-page sentinel, which the schema's terse cursor description does not convey. It stops short of restating the limit/default 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?
States a specific verb (list), resource (crawls), account scope, ordering (newest first), and exactly what each entry carries (status and coverage). The '(no results)' parenthetical cleanly separates it from crawl_results, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The '(no results)' qualifier implicitly tells the agent to reach for crawl_results when actual content is needed, and the pagination sentence gives the exact condition for the next call. It never names the alternative tool outright, so it falls short of an explicit when/when-not statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_resultsARead-onlyInspect
List the URLs a crawl kept, in the order it kept them, following the API's pages up to limit.
Each result has url and, when the crawl has output_format, content_status (pending, fetched, failed) and, once fetched, content_url: pass it to crawl_content as content.
While the crawl runs the list is partial (partial=true): call again later with the returned next_cursor to get only the URLs kept since. A stopped crawl can still add URLs from pages fetched before the stop for up to 10 minutes, so next_cursor stays set during that window: call again later. next_cursor is null once the crawl ended and every URL was read.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results to return in this call (default 100, max 10000) | |
| cursor | No | next_cursor from a previous crawl_results call, to continue from there | |
| crawl_id | Yes | Crawl id returned by crawl_create (c_…) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only/safe, but the description adds substantial behavior beyond them: partial=true during a run, the 10-minute post-stop window where next_cursor stays set, the exact condition for next_cursor becoming null, and the content_status lifecycle (pending/fetched/failed). This is rich, non-obvious disclosure.
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 paragraphs, each front-loaded with the point (what it lists, what a result contains, pagination lifecycle) and no filler. Slightly longer than strictly necessary but every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully carries the burden: it names the returned fields (url, content_status, content_url) and their meaning, plus the cursor lifecycle an agent must handle to call this correctly across runs.
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 semantics the schema lacks: next_cursor returns only URLs kept since the last read (incremental pagination) rather than a plain continuation. Limit behavior is left to the schema, which already documents it fully.
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 (list), resource (URLs a crawl kept), and ordering/scope constraint (in the order it kept them, paginated up to limit). This clearly separates it from crawl_get (status), crawl_content (fetch body), and crawl_list (enumerate crawls).
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 explicit operational context: call again with next_cursor while partial=true, and wait up to 10 minutes after a stop. It also routes the agent onward ('pass it to crawl_content as content'). It stops short of explicitly contrasting when to prefer crawl_get or crawl_wait instead, so it is strong context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_stopADestructiveIdempotentInspect
Stop a running crawl. No page still waiting is fetched or billed; pages already in flight finish. The URLs kept so far stay readable with crawl_results. A stopped crawl cannot resume.
Idempotent: a crawl that already ended answers with its final status. A 429, 502, 503 or 504 is retried up to 3 times, waiting at most 50 seconds in all; a 503 crawl_busy means the stop was not saved yet, and if it persists, CRAWL_BUSY says when to call again. Pages in flight still finish, so coverage and results can keep growing for up to 10 minutes after the stop; read them with crawl_get and crawl_results.
| Name | Required | Description | Default |
|---|---|---|---|
| crawl_id | Yes | Crawl id returned by crawl_create (c_…) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: no billing for unfetched pages, in-flight pages still complete, no resume, idempotent behavior on an already-ended crawl, retry policy for 429/502/503/504 (3 retries, ≤50s total), the meaning of a 503 crawl_busy and CRAWL_BUSY, and the up-to-10-minute window where results keep growing.
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 the most decision-relevant facts (billing, no resume) before the operational details. Dense but nearly every sentence carries distinct information; the second paragraph is somewhat packed but not 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 no output schema, the description still covers what a caller needs: final status on an idempotent call, billing behavior, retry/failure semantics, and the eventual-consistency window for results. Nothing material is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single crawl_id parameter, and the description adds no syntax or format detail beyond it. Baseline 3 is appropriate when the schema fully documents the only parameter.
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 ('Stop a running crawl') and immediately scopes it: pages still waiting are not fetched or billed, in-flight pages finish. It distinguishes itself from the read-side siblings by pointing to crawl_results for the URLs already kept.
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?
Explains the context clearly: use it to halt a running crawl, then read retained output with crawl_results/crawl_get, and it cannot be resumed. It does not explicitly contrast against a hypothetical 'cancel' alternative, but the routing to crawl_results and crawl_get is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crawl_waitARead-onlyInspect
Poll a crawl until it ends (completed, stopped, or failed) and return its status, its counts and the first 20 URLs (first_urls). For every result, call crawl_download (one file) or crawl_results (pages). A crawl that ends completed with no results and no error finished; it is not a failure (see crawl_get). If the wait runs out first, it returns the crawl with status running and a note: call crawl_wait again. A call that carries a progressToken gets a progress notification after each poll, with the status and counts.
| Name | Required | Description | Default |
|---|---|---|---|
| timeout | No | Max wait in seconds (default 50). Many MCP clients cancel a call after 60 s. | |
| crawl_id | Yes | Crawl id returned by crawl_create (c_…) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/destructive annotations: it discloses the timeout-retry contract, the progressToken progress-notification behavior, and the subtle semantic that a completed crawl with no results and no error is not a failure. This is exactly the kind of edge-case behavior 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?
Front-loads purpose before routing, edge cases, retry, and progress details. Every sentence carries information, though the list of return fields and the parenthetical state enumeration make it slightly denser than strictly needed.
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 must convey return values and it does (status, counts, first_urls), plus timeout/retry behavior and progress notifications. Nothing an agent needs to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents both crawl_id and timeout (default 50, 60s client cancellation caveat). The description only alludes to timeout behavior via 'if the wait runs out first' and adds no parameter detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Poll a crawl until it ends'), enumerates the terminal states (completed, stopped, failed), and names the return payload (status, counts, first_urls). It is clearly distinguishable from crawl_get, crawl_results, and crawl_download, which are explicitly referenced.
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 clear routing guidance: after results, call crawl_download for one file or crawl_results for pages; if the wait times out, call crawl_wait again. It also points to crawl_get for the completed-with-no-results case. It lacks an explicit 'do not use when you only want a one-shot status check' exclusion, so it falls just short of 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extractARead-onlyInspect
Extract structured data from a webpage via Zenrows.
Returns JSON fields (products, articles, listings) in "data" rather than a full page body. Set include_html to also get the page HTML. Modes:
auto (default): extract=auto, site-tailored Extract (currently free, billing may apply later). Works on any prepared domain, with any API key. Error REQS007 says why in "reason":
domain_not_prepared: call prepare_domain with the domain and 1 to 5 example URLs (one works; we recommend 3 or more of the same page type; a few minutes, no credits), poll prepared_domain_status about every 30 seconds until it says ready, then call extract again.
page_not_recognised: the domain is prepared, but this page is not one Extract extracts (a page with nothing to extract, such as a home page). Try a product, article or listing page instead; if this page should work, retry it once in a few minutes; otherwise use mode=css. Do not prepare the domain again.
domain_not_enabled: preparing does not help; use mode=css.
autoparse: deprecated general-purpose structured JSON on any domain; use only when asked for
css: css_extractor with an explicit selector map
Requests use automatic mode (mode=auto) by default: Zenrows enables JS rendering and premium proxies only when the site needs them, and charges only for the configuration that succeeds. Pass just the URL. Set js_render or premium_proxy only to force a fixed configuration; that turns automatic mode off and bills every request at that configuration's cost.
Check "empty" in the result: true means no field came back with a value. "noDataExtracted": true means Extract processed the page and found nothing to extract (not charged); retrying the same request returns the same answer. Full-page markdown, HTML and screenshots come from scrape.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The webpage URL to extract from | |
| mode | No | Extraction mode: auto (extract=auto, default), css (requires css_extractor), or the deprecated autoparse | auto |
| wait | No | Milliseconds to wait after load. Requires js_render=true; without it, including in automatic mode, it may be ignored. | |
| wait_for | No | CSS selector to wait for before extracting. Requires js_render=true; without it, including in automatic mode, it may be ignored. | |
| js_render | No | Force JS rendering on every request. Overrides automatic mode (mode=auto), which already renders when needed. | |
| mode_auto | No | Automatic mode (mode=auto) is on by default; leave unset. False sends a plain request without it. | |
| include_html | No | mode=auto only: also return the full page HTML. Default false; the HTML is most of the response size. | |
| css_extractor | No | Required when mode=css. JSON map of field→selector, e.g. '{"title":"h1","price":".price"}' | |
| premium_proxy | No | Force premium residential proxies on every request (10x cost). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them. | |
| proxy_country | No | ISO 3166-1 alpha-2 country code. Works in automatic mode (mode=auto); with js_render or mode_auto=false it requires premium_proxy. | |
| fallback_autoparse | No | Deprecated, has no effect: Extract no longer falls back to autoparse. Prepare the domain with prepare_domain instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, the description adds substantial behavioral context: automatic mode billing behavior, cost implications of js_render and premium_proxy, the meaning of "empty" and "noDataExtracted", no-charge behavior for noDataExtracted, and deterministic retry behavior.
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 well structured and front-loads the core purpose, return shape, and modes before error handling and billing details. It is somewhat long and repeats automatic-mode behavior in multiple places, but nearly all content is relevant for an 11-parameter tool with billing and error-mode complexity.
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 still explains the return shape, the include_html behavior, the "empty" and "noDataExtracted" signals, and the key error cases. Given the tool's complexity and the presence of annotations covering safety, it provides enough context for an agent 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?
Even though schema description coverage is 100%, the description adds meaningful semantics beyond the schema: it clarifies that wait and wait_for require js_render, that premium_proxy forces 10x-cost residential proxies, that proxy_country has mode-dependent requirements, and that fallback_autoparse is deprecated and has no effect.
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 that this tool extracts structured data from a webpage via Zenrows, specifying that it returns JSON fields such as products, articles, and listings in "data" rather than a full page body. It also explicitly distinguishes itself from the sibling scrape tool by noting that full-page markdown, HTML, and screenshots come from scrape.
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 explicit mode selection guidance: auto is default, autoparse is deprecated and only used when asked for, and css requires an explicit selector map. It also explains remediation paths for specific errors, including calling prepare_domain, polling prepared_domain_status, retrying, or switching to mode=css.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepared_domain_statusARead-onlyInspect
Check a domain submitted with prepare_domain, and the account's monthly allowance.
Returns status (preparing, ready or failed), state (the current step), roles (one per page kind), a failure code and detail when it failed, the allowance (used, limit, remaining) and "next": what to do now. Poll about every 30 seconds; preparation takes a few minutes. Call extract again once status is "ready". Costs no credits.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The domain passed to prepare_domain, e.g. example.com |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description adds value beyond that: the expected latency ('a few minutes'), a recommended polling cadence, the zero-credit cost, and the shape of the returned payload (status/state/roles/failure code/allowance/next).
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?
Purpose and status-query are front-loaded, then the return fields, then the polling cadence and next action. Every sentence carries actionable information with no filler or repetition of the 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?
With no output schema, the description carries the return-shape burden and does so by enumerating status, state, roles, failure code/detail, allowance (used/limit/remaining) and 'next'. Combined with the polling and follow-up (extract) guidance, an agent has everything needed to call and act on this 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 description coverage is 100% and there is a single required 'domain' parameter whose schema text already explains it is the domain passed to prepare_domain. The description reinforces that linkage but adds no syntax, format, or constraint details beyond the schema, so the 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?
Specific verb (check) plus a clearly scoped resource: the domain submitted via the sibling prepare_domain, along with the account's monthly allowance. It names prepare_domain and extract explicitly, so an agent can tell it apart from siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit operational guidance: poll about every 30 seconds, preparation takes a few minutes, and call extract again once status is 'ready'. It also states the tool costs no credits, removing cost as a reason to avoid polling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_domainAIdempotentInspect
Prepare a domain so extract (mode=auto) works on it.
Use this when extract returns error REQS007 with reason domain_not_prepared. Send the domain (the host, e.g. shop.example.com; a leading www. is dropped, and each host is prepared separately) and 1 to 5 example URLs of real pages you want extracted. One works; we recommend 3 or more of the same page type, so pass 3 or more when you can, up to 5 (e.g. 3 product pages: https://www.example.com/products/a, /products/b and /products/c), because Extract compares pages of one type to check the fields it found and fill in fields one page is missing. Several page types can share the 5 (e.g. 3 product pages + 2 search-result pages). It returns at once with status "preparing" and never waits; preparation takes a few minutes and costs no credits. Then call prepared_domain_status about every 30 seconds until status is "ready", and call extract again. Each new domain uses one slot of the account's monthly allowance (prepared_domain_status shows it). A domain already being prepared returns its current status; a domain already prepared returns "ready" at once with already_prepared: true and uses no slot.
Do not call this for REQS007 with reason page_not_recognised: the domain is already prepared and preparing again does not change that answer.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The host to prepare, e.g. shop.example.com (a URL is accepted; a leading www. is dropped) | |
| example_urls | Yes | 1 to 5 full URLs of real pages on this domain that you want to extract. One works; we recommend 3 or more of the same page type when you can | |
| idempotency_key | No | Optional. Resending the same key with the same body returns the original submission |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: returns immediately with status "preparing", never blocks, takes a few minutes, costs no credits, and consumes one slot of the monthly allowance per new domain. It also discloses the already-in-progress and already-prepared short-circuits (already_prepared: true, no slot used), which the idempotentHint alone would not 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?
Purpose and trigger are front-loaded and the polling instructions follow in order. It is dense and slightly repetitive on the 1-vs-3+ example URL point, but nearly every sentence carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the full lifecycle an agent needs for a 3-param, no-output-schema tool: trigger, exclusions, immediate return shape, polling cadence, cost, quota impact, and idempotent re-entry behavior. No output schema is needed given the described return statuses.
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 semantics: a leading www. is dropped and each host is prepared separately, and 3+ same-type example URLs are recommended (up to 5) because Extract compares pages of one type to fill missing fields, with page types allowed to share the budget. That is guidance the schema cannot express.
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 — "Prepare a domain so extract (mode=auto) works on it" — and ties it to the sibling tool it unblocks. An agent can distinguish it from extract and prepared_domain_status without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger (extract returns REQS007 with reason domain_not_prepared) and an explicit exclusion (do not call for page_not_recognised, with the reason why preparing again will not help). It also names the follow-up sequence: poll prepared_domain_status, then call extract.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scrapeARead-onlyInspect
Scrape any webpage and return its content using Zenrows (Fetch).
Returns full-page content (markdown/HTML/PDF/screenshot). For structured JSON fields (products, articles, listings), the extract tool returns parsed fields instead of a full page body.
By default the request uses automatic mode (mode=auto): Zenrows adds JS rendering or premium proxies per page only when a plain request does not return the page, and charges only for the configuration that succeeds. Pass just the URL.
Set js_render or premium_proxy only to force a fixed configuration. Doing so switches off automatic mode, and every request is billed at that configuration's cost (premium_proxy with js_render is 25x a basic request).
Examples: Default: { url: "https://example.com" } Geo: { url: "https://example.com", proxy_country: "US" } Forced: { url: "https://spa.com", js_render: true }
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The webpage URL to scrape | |
| wait | No | Milliseconds to wait after page load before capturing content. Max 30000 (30s). Requires js_render=true; without it, including in automatic mode, it may be ignored. | |
| outputs | No | Comma-separated list of data types to extract as structured JSON. Available: emails, headings, links, menus, images, videos, audios. Use '*' for all types. Returns JSON instead of full page content. | |
| wait_for | No | CSS selector to wait for before capturing. Use when key content loads after the initial page render. Requires js_render=true; without it, including in automatic mode, it may be ignored. | |
| autoparse | No | Deprecated: general-purpose structured JSON from the page. Prefer the extract tool (extract=auto on a prepared domain, or css_extractor). | |
| js_render | No | Force JavaScript rendering on every request. Overrides automatic mode (mode=auto), which already renders JavaScript when a page needs it. Leave unset unless you need a fixed configuration. | |
| screenshot | No | Capture an above-the-fold screenshot of the page. Returns an image instead of text content. Useful for visual verification or debugging. | |
| css_extractor | No | Extract specific elements using CSS selectors. JSON object mapping names to selectors, e.g. '{"title":"h1","price":".price-tag"}'. Returns JSON instead of full page content. | |
| premium_proxy | No | Force premium residential proxies on every request (10x credit cost). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them. Leave unset unless you need a fixed configuration. | |
| proxy_country | No | Country for geo-targeted scraping. ISO 3166-1 alpha-2 code (e.g. 'US', 'GB', 'DE'). Works in automatic mode (mode=auto); if you set js_render without premium_proxy, it requires premium_proxy=true. | |
| response_type | No | Output format. 'markdown' (default) preserves structure and is ideal for LLMs. 'plaintext' strips all formatting for pure text extraction. 'pdf' returns a PDF of the page. 'html' returns the raw HTML source (omits the response_type param; Zenrows default). Ignored when autoparse, css_extractor, outputs, or screenshot params are set. | markdown |
| js_instructions | No | JSON array of browser interactions to run before scraping. Works in automatic mode (mode=auto), which then renders the page and bills it at the JS rendering rate, or with js_render=true. Example: [{"click":"#load-more"},{"wait":1000},{"wait_for":".results"}] | |
| screenshot_fullpage | No | Capture a full-page screenshot including content below the fold. Returns an image instead of text content. | |
| screenshot_selector | No | Capture a screenshot of a specific element using a CSS selector. Example: ".product-card". Returns an image instead of text content. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and non-destructive behavior, but the description adds substantive context beyond them: automatic mode bills only the successful configuration, forcing a fixed configuration changes billing, and premium_proxy with js_render is 25x a basic request. It also warns that wait/wait_for may be ignored without js_render.
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-loads the purpose and return types, then moves to the extract alternative, default mode behavior, forced configurations, and examples. Every sentence supports correct invocation or cost awareness, and the length is justified by the 14-parameter surface.
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 14 parameters, no output schema, and annotations covering safety, the description covers return formats, the sibling alternative, default vs forced behavior, and cost implications. Nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description still adds cross-parameter meaning and examples (URL-only default, geo proxy_country, forced js_render) plus the 25x combined premium_proxy+js_render cost, but most individual parameter semantics remain in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Scrape') and resource ('any webpage'), plus the return medium ('content using Zenrows (Fetch)'). It explicitly contrasts itself with the sibling extract tool for structured JSON fields, so an agent can distinguish the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Directly routes structured-field needs to extract and gives clear when-to-use guidance for default automatic mode versus forcing js_render/premium_proxy. The included examples cover default, geo, and forced configurations, making the selection conditions concrete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v2.17.0- Changed
prepare_domain1 field changed- changed
Input schema / properties / example_urls / descriptionPrevious value: -"1 to 5 full URLs of real pages on this domain that you want to extract, one per page kind"New value: +"1 to 5 full URLs of real pages on this domain that you want to extract. One works; we recommend 3 or more of the same page type when you can"
1 tool update
v2.16.1- Added
account_signup_answer
19 tool updates
v2.15.1- Changed
batch_cancel2 fields changed- changed
Input schema / properties / job_id / descriptionPrevious value: -"Batch job id to stop"New value: +"Batch job id returned by batch_create or batch_list" - added
Input schema / properties / job_id / minLengthAdded value: +1
- Added
batch_content - Changed
batch_create14 fields changed- added
Input schema / properties / idempotency_keyAdded value: +{ + "anyOf": [ + { + "maxLength": 128, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Sent as the Idempotency-Key header, up to 128 characters; generated per call when unset. Reusing a key with the identical request within 24 hours returns the original response instead of doing it again; with a different request it is BATCH_IDEMPOTENCY_CONFLICT." +} - changed
Input schema / properties / js_render / descriptionPrevious value: -"Force js_render on all tasks. Overrides automatic mode (mode=auto), which already renders when needed."New value: +"Force js_render on all tasks (5 credits each). Overrides automatic mode (mode=auto), which already renders when needed." - changed
Input schema / properties / premium_proxy / descriptionPrevious value: -"Force premium_proxy on all tasks (10x cost). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them."New value: +"Force premium_proxy on all tasks (10 credits each, 25 with js_render). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them." - changed
Input schema / properties / response_type / anyOfPrevious value: -[ - { - "enum": [ - "markdown", - "plaintext", - "html", - "pdf" - ], - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "markdown", + "plaintext", + "pdf" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / response_type / descriptionPrevious value: -"Job-level response_type"New value: +"Job-level output format. Leave unset for the raw HTML, the default." - changed
Input schema / properties / tasks / anyOfPrevious value: -[ - { - "items": { - "additionalProperties": false, - "properties": { - "external_id": { - "description": "Optional stable id echoed back on results", - "type": [ - "string", - "null" - ] - }, - "metadata": { - "anyOf": [ - {}, - { - "type": "null" - } - ], - "description": "Opaque per-task metadata carried through to results" - }, - "url": { - "description": "Target URL for this task", - "format": "uri", - "type": "string" - }, - "zenrows_params": { - "anyOf": [ - { - "additionalProperties": { - "type": [ - "string", - "number", - "boolean" - ] - }, - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Per-task Zenrows scrape params (js_render, premium_proxy, extract, autoparse, …)" - } - }, - "required": [ - "url" - ], - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } -]New value: +[ + { + "items": { + "additionalProperties": true, + "description": "A task. Scrape params may go in zenrows_params or flat on the task (e.g. extract, js_render); a flat key wins over the same key in zenrows_params.", + "properties": { + "body": { + "description": "Request body, only with method POST, up to 16 KiB. An object or array is sent as JSON; a string is sent as is, form encoded." + }, + "external_id": { + "anyOf": [ + { + "maxLength": 128, + "pattern": "^[A-Za-z0-9._-]+$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional id of your own, echoed back on results: up to 128 characters, letters, digits, '.', '_' and '-' only (no spaces). Need not be unique. Put free text in metadata instead." + }, + "metadata": { + "anyOf": [ + { + "additionalProperties": { + "maxLength": 1024, + "type": "string" + }, + "propertyNames": { + "maxLength": 64, + "minLength": 1, + "pattern": "^[A-Za-z0-9._-]+$" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Optional string-to-string map echoed back on results: up to 20 entries; keys 1 to 64 characters of letters, digits, '.', '_' and '-'; values up to 1,024 characters; 4 KiB in all. Values must be strings: convert numbers and booleans first." + }, + "method": { + "anyOf": [ + { + "enum": [ + "GET", + "POST" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "description": "HTTP method for this task (default GET). POST is for read-only queries such as search or GraphQL endpoints: the target can receive the same POST more than once. POST cannot be combined with js_render, js_instructions or json_response." + }, + "url": { + "description": "Target URL for this task: http or https, up to 2,048 characters", + "format": "uri", + "maxLength": 2048, + "type": "string" + }, + "zenrows_params": { + "anyOf": [ + { + "additionalProperties": { + "type": [ + "string", + "number", + "boolean" + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Per-task scrape params, over the job's. Accepted: allowed_status_codes, autoparse, block_resources, css_extractor, custom_headers, extract, extract_fields, js_instructions, js_render, json_response, mode, original_status, outputs, premium_proxy, proxy_country, response_type, session_id, wait, wait_for. Booleans as true/false. Screenshot params are not supported in Batch." + } + }, + "required": [ + "url" + ], + "type": "object" + }, + "maxItems": 100000, + "type": "array" + }, + { + "type": "null" + } +] - changed
Input schema / properties / tasks / descriptionPrevious value: -"List of tasks (each needs a url). Prefer this over urls when you need per-task params."New value: +"Tasks (each needs a url), up to 100,000. Prefer this over urls when you need per-task params." - changed
Input schema / properties / urls / anyOfPrevious value: -[ - { - "items": { - "format": "uri", - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -]New value: +[ + { + "items": { + "format": "uri", + "maxLength": 2048, + "type": "string" + }, + "maxItems": 100000, + "type": "array" + }, + { + "type": "null" + } +] - changed
Input schema / properties / urls / descriptionPrevious value: -"Shorthand: list of URLs (converted to tasks). Ignored when tasks is provided."New value: +"Shorthand: list of URLs (converted to tasks), up to 100,000. Ignored when tasks is provided." - changed
Input schema / properties / wait / descriptionPrevious value: -"If true, poll until the job reaches a terminal state before returning"New value: +"If true, poll before returning until the run ends or pauses, or wait_timeout passes; a timeout returns the current state with ok:true" - added
Input schema / properties / wait_timeoutAdded value: +{ + "anyOf": [ + { + "maximum": 3600, + "minimum": 1, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Max wait in seconds when wait=true (default 50). Many MCP clients cancel a call after 60 s." +} - changed
Input schema / properties / wait_timeout_ms / descriptionPrevious value: -"Max wait time when wait=true (default 600000)"New value: +"Deprecated: the same wait in milliseconds. Use the seconds parameter instead." - changed
Input schema / properties / zenrows_params / anyOfPrevious value: -[ - { - "additionalProperties": { - "type": [ - "string", - "number", - "boolean" - ] - }, - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "$ref": "#/properties/tasks/anyOf/0/items/properties/zenrows_params/anyOf/0" + }, + { + "type": "null" + } +] - changed
Input schema / properties / zenrows_params / descriptionPrevious value: -"Additional job-level zenrows_params merged with the flags above"New value: +"Additional job-level scrape params merged with the flags above. Accepted: allowed_status_codes, autoparse, block_resources, css_extractor, custom_headers, extract, extract_fields, js_instructions, js_render, json_response, mode, original_status, outputs, premium_proxy, proxy_country, response_type, session_id, wait, wait_for."
- Added
batch_delete - Added
batch_list - Added
batch_pause - Added
batch_rerun - Changed
batch_results7 fields changed- added
Input schema / properties / cursorAdded value: +{ + "description": "next_cursor from a previous batch_results call", + "type": [ + "string", + "null" + ] +} - changed
Input schema / properties / job_id / descriptionPrevious value: -"Batch job id"New value: +"Batch job id returned by batch_create or batch_list" - added
Input schema / properties / job_id / minLengthAdded value: +1 - added
Input schema / properties / limitAdded value: +{ + "anyOf": [ + { + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Max rows to return (default 100, max 1000)" +} - added
Input schema / properties / run_idAdded value: +{ + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "An earlier run's id (from batch_status or batch_rerun). Default: the job's latest run." +} - changed
Input schema / properties / status / anyOfPrevious value: -[ - { - "enum": [ - "successful", - "failed", - "all" - ], - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "successful", + "failed", + "processing", + "all" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / status / descriptionPrevious value: -"Filter results by status (default: all)"New value: +"Filter rows by status (default all). processing = tasks not finished yet. successful also returns expired rows."
- Added
batch_resume - Changed
batch_status2 fields changed- changed
Input schema / properties / job_id / descriptionPrevious value: -"Batch job id returned by batch_create"New value: +"Batch job id returned by batch_create or batch_list" - added
Input schema / properties / job_id / minLengthAdded value: +1
- Changed
batch_wait4 fields changed- changed
Input schema / properties / job_id / descriptionPrevious value: -"Batch job id"New value: +"Batch job id returned by batch_create or batch_list" - added
Input schema / properties / job_id / minLengthAdded value: +1 - added
Input schema / properties / timeoutAdded value: +{ + "anyOf": [ + { + "maximum": 3600, + "minimum": 1, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Max wait in seconds (default 50). Many MCP clients cancel a call after 60 s." +} - changed
Input schema / properties / timeout_ms / descriptionPrevious value: -"Max wait time in ms (default 600000)"New value: +"Deprecated: the same wait in milliseconds. Use the seconds parameter instead."
- Added
browser_clear_local_storage - Added
browser_get_local_storage - Removed
browser_local_storage - Added
browser_set_local_storage - Changed
extract4 fields changed- removed
Input schema / properties / fallback_autoparse / defaultRemoved value: -true - changed
Input schema / properties / fallback_autoparse / descriptionPrevious value: -"When mode=auto and the domain isn't prepared for Extract yet (REQS007, or the legacy AUTH010), retry once with autoparse (default true)"New value: +"Deprecated, has no effect: Extract no longer falls back to autoparse. Prepare the domain with prepare_domain instead." - added
Input schema / properties / include_htmlAdded value: +{ + "default": false, + "description": "mode=auto only: also return the full page HTML. Default false; the HTML is most of the response size.", + "type": [ + "boolean", + "null" + ] +} - changed
Input schema / properties / mode / descriptionPrevious value: -"Extraction mode: auto (extract=auto, default), autoparse, or css (requires css_extractor)"New value: +"Extraction mode: auto (extract=auto, default), css (requires css_extractor), or the deprecated autoparse"
- Added
prepare_domain - Added
prepared_domain_status - Changed
scrape1 field changed- changed
Input schema / properties / autoparse / descriptionPrevious value: -"Automatically extract structured data from the page into JSON. Best for product pages, articles, and listings."New value: +"Deprecated: general-purpose structured JSON from the page. Prefer the extract tool (extract=auto on a prepared domain, or css_extractor)."
2 tool updates
v2.10.2- Changed
crawl_content1 field changed- changed
Input schema / properties / max_chars / descriptionPrevious value: -"Max characters of HTML to return (default 20000)"New value: +"Max characters of the page to return (default 20000)"
- Changed
crawl_create3 fields changed- added
Input schema / properties / discoveryAdded value: +{ + "anyOf": [ + { + "items": { + "enum": [ + "links" + ], + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "How the crawl finds the URLs it follows on each page it walks. ['links'] follows the links in each page's HTML, and is what a crawl runs with when you omit this." +} - changed
Input schema / properties / output_format / anyOfPrevious value: -[ - { - "enum": [ - "html" - ], - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "html", + "markdown" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / output_format / descriptionPrevious value: -"'html' also stores each kept URL's page for crawl_content. Omit for URLs only."New value: +"'html' or 'markdown' also stores each kept URL's page for crawl_content, as fetched or converted to Markdown. Omit for URLs only."
52 tool updates
v2.7.0- Added
account_usage - Added
batch_cancel - Added
batch_create - Added
batch_results - Added
batch_status - Added
batch_wait - Added
browser_batch - Added
browser_check - Added
browser_clear_cookies - Added
browser_click - Added
browser_close - Added
browser_drag - Added
browser_evaluate - Added
browser_fill - Added
browser_focus - Added
browser_generate_pdf - Added
browser_get_accessibility_tree - Added
browser_get_attribute - Added
browser_get_cookies - Added
browser_get_html - Added
browser_get_text - Added
browser_get_title - Added
browser_get_url - Added
browser_go_back - Added
browser_go_forward - Added
browser_hover - Added
browser_local_storage - Added
browser_navigate - Added
browser_new_tab - Added
browser_press_key - Added
browser_query_selector_all - Added
browser_reload - Added
browser_screenshot - Added
browser_scroll - Added
browser_select_option - Added
browser_set_cookies - Added
browser_switch_tab - Added
browser_type - Added
browser_uncheck - Added
browser_wait - Added
browser_wait_for_navigation - Added
browser_wait_for_selector - Added
crawl_content - Added
crawl_create - Added
crawl_download - Added
crawl_get - Added
crawl_list - Added
crawl_results - Added
crawl_stop - Added
crawl_wait - Added
extract - Changed
scrape27 fields changed- changed
Input schema / properties / autoparse / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - changed
Input schema / properties / css_extractor / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Input schema / properties / js_instructions / descriptionPrevious value: -"JSON array of browser interactions to run before scraping. Requires js_render=true. Example: [{\"click\":\"#load-more\"},{\"wait\":1000},{\"wait_for\":\".results\"}]"New value: +"JSON array of browser interactions to run before scraping. Works in automatic mode (mode=auto), which then renders the page and bills it at the JS rendering rate, or with js_render=true. Example: [{\"click\":\"#load-more\"},{\"wait\":1000},{\"wait_for\":\".results\"}]" - changed
Input schema / properties / js_instructions / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Input schema / properties / js_render / defaultRemoved value: -false - changed
Input schema / properties / js_render / descriptionPrevious value: -"Enable JavaScript rendering via headless browser. Required for SPAs (React, Vue, Angular) and pages that load content dynamically."New value: +"Force JavaScript rendering on every request. Overrides automatic mode (mode=auto), which already renders JavaScript when a page needs it. Leave unset unless you need a fixed configuration." - changed
Input schema / properties / js_render / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - changed
Input schema / properties / outputs / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Input schema / properties / premium_proxy / defaultRemoved value: -false - changed
Input schema / properties / premium_proxy / descriptionPrevious value: -"Use premium residential proxies to bypass anti-bot protection. Required for heavily protected sites. Implies higher credit cost."New value: +"Force premium residential proxies on every request (10x credit cost). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them. Leave unset unless you need a fixed configuration." - changed
Input schema / properties / premium_proxy / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - changed
Input schema / properties / proxy_country / descriptionPrevious value: -"Country for geo-targeted scraping. ISO 3166-1 alpha-2 code (e.g. 'US', 'GB', 'DE'). Requires premium_proxy=true."New value: +"Country for geo-targeted scraping. ISO 3166-1 alpha-2 code (e.g. 'US', 'GB', 'DE'). Works in automatic mode (mode=auto); if you set js_render without premium_proxy, it requires premium_proxy=true." - changed
Input schema / properties / proxy_country / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Input schema / properties / response_type / anyOfAdded value: +[ + { + "enum": [ + "markdown", + "plaintext", + "pdf", + "html" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / response_type / descriptionPrevious value: -"Output format. 'markdown' (default) preserves structure and is ideal for LLMs. 'plaintext' strips all formatting for pure text extraction. 'pdf' returns a PDF of the page. 'html' returns the raw HTML source (omits the response_type param; ZenRows default). Ignored when autoparse, css_extractor, outputs, or screenshot params are set."New value: +"Output format. 'markdown' (default) preserves structure and is ideal for LLMs. 'plaintext' strips all formatting for pure text extraction. 'pdf' returns a PDF of the page. 'html' returns the raw HTML source (omits the response_type param; Zenrows default). Ignored when autoparse, css_extractor, outputs, or screenshot params are set." - removed
Input schema / properties / response_type / enumRemoved value: -[ - "markdown", - "plaintext", - "pdf", - "html" -] - removed
Input schema / properties / response_type / typeRemoved value: -"string" - changed
Input schema / properties / screenshot / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - changed
Input schema / properties / screenshot_fullpage / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - changed
Input schema / properties / screenshot_selector / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Input schema / properties / wait / anyOfAdded value: +[ + { + "maximum": 30000, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / wait / descriptionPrevious value: -"Milliseconds to wait after page load before capturing content. Max 30000 (30s). Requires js_render=true."New value: +"Milliseconds to wait after page load before capturing content. Max 30000 (30s). Requires js_render=true; without it, including in automatic mode, it may be ignored." - removed
Input schema / properties / wait / maximumRemoved value: -30000 - removed
Input schema / properties / wait / minimumRemoved value: -0 - removed
Input schema / properties / wait / typeRemoved value: -"integer" - changed
Input schema / properties / wait_for / descriptionPrevious value: -"CSS selector to wait for before capturing. Use when key content loads after the initial page render. Requires js_render=true."New value: +"CSS selector to wait for before capturing. Use when key content loads after the initial page render. Requires js_render=true; without it, including in automatic mode, it may be ignored." - changed
Input schema / properties / wait_for / typePrevious value: -"string"New value: +[ + "string", + "null" +]
1 tool update
v1.1.5- First observed
scrape
TDQS
Scored across 63 tools
The tool set is largely separable by prefix and resource/action: crawl_*, batch_*, browser_*, plus scrape/extract/account tools. A few boundaries could still confuse an agent—scrape versus extract versus crawl_create/batch_create, and snapshot versus polling tools like batch_status/batch_wait and crawl_get/crawl_results—but the descriptions generally resolve these.
Names consistently use lowercase snake_case with clear domain prefixes (browser_, crawl_, batch_, account_) and predictable verb/noun phrasing such as browser_get_url or batch_cancel. The few unprefixed tools (scrape, extract, prepare_domain, prepared_domain_status) still follow the same casing convention.
63 tools is a very large surface for one MCP server, even allowing for the broad scraping, crawling, batch, and browser-automation scope. The roughly 40 granular browser tools in particular create a heavy set that is hard to navigate without a more consolidated or staged interface.
Coverage is strong across the major workflows: single-page scrape/extract, crawl lifecycle, batch lifecycle, and extensive browser interaction and inspection. Minor gaps exist—such as browser file upload/download, dialog handling, frame handling, and batch scheduling/webhooks/exports being API-only—but core workflows are well covered.
Maintenance
Related MCP Connectors
Web scraping MCP server — scrape, extract structured data, screenshot any site with anti-bot bypass.
Web scraping MCP server: any URL to Markdown or JSON, with JavaScript rendering and batch jobs.
Web scraping, browser automation, screenshots and AI data extraction for AI agents via MCP.
One MCP for the Web. Easily search, crawl, navigate, and extract websites without getting blocked.…
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP-native web scraping and search API for AI agents. Converts any URL to clean Markdown with 90% success rate, including Cloudflare-protected sites and JS SPAs. Real-time web search via Brave Search API. CAPTCHA solving built-in. 10 free scrapes/day.510 npm5MIT
- AlicenseAqualityBmaintenanceWeb extraction MCP server for AI agents. Extract structured data from any URL with built-in Cloudflare bypass, JavaScript rendering, and intelligent parsing. Returns clean markdown or JSON.5794 npm2MIT
- AlicenseNot gradedqualityBmaintenanceRemote MCP server for web scraping with anti-bot evasion. Provides stealth HTTP fetching, headless browser with Cloudflare bypass, CSS selectors, YouTube transcripts, and Markdown conversion.1MIT
- AlicenseNot gradedqualityDmaintenanceMCP server to scrape web pages to clean Markdown via headless Chromium, with support for single or batch URLs.MIT