0.0 / 30
What changed in the harness
Selection accuracy 100→100, token cost up 9%, unconfirmed writes 0%→0%.
Category breakdown
Where the score comes from.
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
01Safety
02Legibility
20.7 / 30
03Economics
11.4 / 20
04Discoverability
8.2 / 20
Highest-impact fix
Estimated gain +30 pointsAdd explicit identity and permission preflight tools
Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
Defects and rewrites.
35 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
verify_token |
no_return_description |
Confirm whether the configured Cloudflare API token is valid and return its status together with the permissions it grants and the accounts it can access, so callers can verify credentials are correctly configured before running account- or zone-scoped operations. |
list_accounts |
name_restates_behavior no_return_description |
Return the Cloudflare accounts the configured token can access, each with its display name and account_id, so callers can pick the right account_id to pass to account-scoped tools; set fetch_all to true to merge all paginated pages into a single result. |
list_zones |
name_restates_behavior params_unexplained no_return_description |
Return the zones (domains) the token's accounts have access to, each with its zone_id, name, and status, optionally filtered by exact/substring name or zone status; page selects which page of results to fetch (default 1), per_page sets the page size, and fetch_all merges all pages into one response (ignoring page/per_page). Use the returned zone_id with zone-scoped tools. |
get_zone |
name_restates_behavior no_return_description |
Return the full configuration details of a single zone, including its current status (e.g. active, pending, deactivated), plan, and related settings, given the 32-char hex zone_id from list_zones; useful to inspect a zone before performing operations on it. |
get_zone_analytics |
name_restates_behavior no_return_description |
Return hourly HTTP traffic analytics for a zone between the hour-aligned since and until timestamps, including per-hour httpRequests1hGroups request counts and bandwidth metrics obtained via the GraphQL API; useful for measuring traffic trends or verifying the effect of cache purges. |
get_zone_setting |
name_restates_behavior no_return_description |
Return the current value and configuration of a single zone setting (e.g. ssl, always_use_https, min_tls_version, brotli, http3, security_level) for the given zone, so callers can inspect a zone's configuration before deciding whether to change it. |
list_dns_records |
name_restates_behavior params_unexplained no_return_description |
Return the DNS records for a zone, optionally filtered by record type (e.g. A, CNAME, TXT) or record name (FQDN), each with its record_id, type, name, content, TTL, and proxying status; page selects the page (default 1), per_page sets the page size, and fetch_all merges all pages into one response (ignoring page/per_page). Use the returned record_id with create/update/delete record tools. |
update_dns_record |
params_unexplained |
Update an existing DNS record in a zone as a partial update, changing only the provided fields: type sets the record type (A, AAAA, CNAME, TXT, MX, NS, SRV, CAA, PTR, SPF), name is the record name (e.g. www.example.com or @ for root), content is the record value (IP, target host, or text), ttl is the TTL in seconds (1 = automatic), proxied controls whether traffic is proxied through Cloudflare (A/AAAA/CNAME only), priority sets MX/SRV priority, and comment attaches an optional note. Requires confirm:true (human-approval gate); without it returns a preview only. |
get_dnssec |
name_restates_behavior no_return_description |
Return the DNSSEC status for a zone along with its DS record details (key tag, algorithm, digest type, and digest), which are required to configure DNSSEC at the registrar; useful to verify whether DNSSEC is enabled before enabling or disabling it. |
export_dns_records |
name_restates_behavior no_return_description |
Return all DNS records of a zone as a BIND zone file in text format, given the zone_id, suitable for backup or migrating records to another DNS provider or tool. |
list_workers |
name_restates_behavior no_return_description |
Return the Worker scripts deployed in an account, each with its script name and deployment metadata such as modified date and version, so callers can see what is deployed before creating, updating, or deleting scripts. |
get_worker |
name_restates_behavior no_return_description |
Return the settings and metadata of a single Worker script (not its source code), such as modules, bindings, triggers, and compatibility settings, given the script_name; useful for inspecting configuration before modifying the script. |
list_worker_routes |
name_restates_behavior no_return_description |
Return the Worker routes defined on a zone, each with its route_id, URL pattern, and the Worker script it maps to, given the zone_id; useful for reviewing traffic routing and for selecting a route_id before editing or deleting a route. |
list_kv_namespaces |
name_restates_behavior params_unexplained no_return_description |
List the Workers KV namespaces in the account, with pagination. Use page (page number) and per_page (results per page) to control pagination; set fetch_all to true to fetch and combine all pages instead (page/per_page are then ignored). Returns the list of KV namespaces and their metadata. |
kv_list_keys |
name_restates_behavior no_return_description |
List the keys stored in the given KV namespace, optionally only those matching prefix. Use limit to cap how many keys are returned (default 1000). Returns the matching keys and their metadata. |
kv_get |
no_return_description |
Read the value currently stored under the given key in the KV namespace. Returns the stored value for that key. |
list_r2_buckets |
name_restates_behavior no_return_description |
List the R2 buckets in the account, optionally filtered to those whose name contains name_contains. Returns the matching buckets and their metadata. |
list_d1_databases |
name_restates_behavior params_unexplained no_return_description |
List the D1 databases in the account, optionally filtered by name. Use page (page number) and per_page (results per page) to control pagination; set fetch_all to true to fetch and combine all pages instead (page/per_page are then ignored). Returns the list of D1 databases and their metadata. |
list_pages_projects |
name_restates_behavior no_return_description |
List the Cloudflare Pages projects in the account. Returns the projects and their configuration details. |
get_pages_project |
name_restates_behavior no_return_description |
Fetch the details of a single Cloudflare Pages project by its project_name. Returns the project's configuration and status details. |
list_firewall_rulesets |
no_return_description |
List the WAF rulesets configured on the given zone (zone_id). Returns the configured rulesets and their metadata for inspection. |
get_ruleset |
name_restates_behavior no_return_description |
Fetch a single ruleset by zone_id and ruleset_id. Returns the ruleset together with its rules so it can be inspected. |
list_access_rules |
name_restates_behavior params_unexplained no_return_description |
List the IP/ASN/country access rules on the zone, optionally filtered by mode (block, challenge, whitelist, js_challenge, managed_challenge). Use page (page number) and per_page (results per page) to control pagination; set fetch_all to true to fetch and combine all pages instead (page/per_page are then ignored). Returns the matching access rules and their details. |
list_page_rules |
name_restates_behavior no_return_description |
List the page rules on the zone, optionally filtered by status (active or disabled). Returns the matching page rules and their details. |
list_certificate_packs |
name_restates_behavior no_return_description |
List the SSL/TLS certificate packs on the zone, optionally filtered by status (all, pending, active, expired; default all). Returns the certificate packs and their details. |
get_ssl_verification |
name_restates_behavior no_return_description |
Retrieve whether SSL/TLS certificate verification is complete for a zone, including which certificates still need validation and any verification errors. Pass the zone_id from list_zones. Returns the zone's SSL verification status and related details. |
list_custom_hostnames |
name_restates_behavior params_unexplained no_return_description |
Retrieve the custom hostnames (SSL for SaaS) configured on a zone, optionally filtering by exact hostname. Pass zone_id from list_zones; page and per_page control pagination, or set fetch_all=true to follow pagination and return all pages combined (ignores page/per_page). Returns the matching custom hostnames with their SSL configuration and status. |
list_email_rules |
name_restates_behavior no_return_description |
Retrieve the Email Routing rules configured for a zone, which define how incoming mail addresses are forwarded. Pass the zone_id from list_zones. Returns the rules with their source address, destination, name, and enabled state. |
list_email_destinations |
name_restates_behavior no_return_description |
Retrieve the verified destination addresses available for Email Routing in the account, so they can be used as forward_to targets for Email Routing rules. Pass account_id, or omit it to fall back to CLOUDFLARE_ACCOUNT_ID. Returns the verified addresses and their verification status. |
list_queues |
name_restates_behavior no_return_description |
Retrieve the Cloudflare Queues configured for the account, along with their IDs and settings. Pass account_id, or omit it to fall back to CLOUDFLARE_ACCOUNT_ID. Returns the list of queues with their names and details. |
list_tunnels |
name_restates_behavior no_return_description |
Retrieve the Cloudflare Tunnels (cloudflared) configured for the account. Pass account_id, or omit it to fall back to CLOUDFLARE_ACCOUNT_ID; set is_deleted=true to include deleted tunnels, otherwise only active ones are returned. Returns the tunnels with their IDs, names, and connection status. |
get_tunnel |
name_restates_behavior no_return_description |
Retrieve the configuration and status of a single Cloudflare Tunnel. Pass tunnel_id from list_tunnels and account_id, or omit account_id to fall back to CLOUDFLARE_ACCOUNT_ID. Returns the tunnel's details such as its name, connections, and state. |
list_turnstile_widgets |
name_restates_behavior no_return_description |
Retrieve the Turnstile widgets (CAPTCHA alternatives) configured for the account. Pass account_id, or omit it to fall back to CLOUDFLARE_ACCOUNT_ID. Returns the widgets with their IDs, names, allowed domains, and modes. |
list_ai_models |
no_return_description |
Search the catalog of Workers AI models available to the account, optionally filtering by name/task substring via 'search' or by task type via 'task'. Pass account_id, or omit it to fall back to CLOUDFLARE_ACCOUNT_ID. Returns the matching models with their IDs, names, and supported tasks. |
list_logpush_jobs |
name_restates_behavior no_return_description |
Retrieve the Logpush jobs configured to stream dataset logs to destinations, scoped to a zone when zone_id is given or to the account when account_id is given. Returns the jobs with their IDs, names, datasets, destinations, and enabled state. |
Selection evidence
Confusable tool pairs.
12 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
delete_access_rule |
delete_page_rule |
medium | A task like 'delete the rule that blocks IP 1.2.3.4' is clear, but an underspecified 'delete the Cloudflare rule' is ambiguous since both are zone-level rules deleted by rule_id; the asking agent must pick between IP/ASN access rules and URL page rules. |
create_access_rule |
create_page_rule |
medium | Both are phrased as 'create a rule on the zone' and share the trigger verb create; a task that omits whether the rule is IP/country/ASN-based (access rule) versus URL-pattern-based (page rule) lets the agent choose wrongly. |
create_access_rule |
create_email_rule |
low | Both are named 'create_rule' and a bare 'create a rule' is ambiguous, but email rules require match_to/forward_to addresses and access rules IP/ASN targets, so realistic tasks usually disambiguate within the first clause. |
list_access_rules |
list_page_rules |
low | A vague 'list the rules for my zone' could match either (both are zone-level rule listings), but descriptions name distinct domains (IP/ASN/country vs URL patterns) so a task mentioning either quickly resolves it. |
delete_worker |
delete_worker_route |
low | Both triggered by 'delete worker <X>' and share delete/worker tokens, but the schema parameters (script_name for delete_worker, route_id for delete_worker_route) and the strong noun in the task ('route' vs 'script') generally disambiguate. |
delete_worker_route |
delete_worker_secret |
low | Both are 'delete something on a worker' sharing delete/worker tokens, but the concrete object nouns (route vs secret binding) named in a task pick the right tool; leftover ambiguity is mostly from agent hallucinating the wrong full name. |
list_kv_namespaces |
kv_list_keys |
medium | Both start with 'list' and the KV domain; a task 'list my KV keys' versus 'list KV namespaces' is clear, but a sloppy request like 'list KV stuff' or 'list my KV' could select the wrong one since namespaces are containers and keys live inside them. |
list_email_rules |
list_email_destinations |
low | 'List emails' is superficially ambiguous between routing rules and destination addresses, but the descriptions (zone rules vs account-level verified destinations) name different scopes that a concrete task usually fixes. |
list_pages_projects |
get_pages_project |
low | Nearly identical names (pages/project) but the read verbs list vs get, and get_pages_project requires a project_name, so 'list projects' and 'get project X' are distinguishable; confusion only via typo-level name similarity. |
get_zone_analytics |
get_zone_setting |
low | Both are get_zone_* reads on the same zone; tasks explicitly asking for analytics/traffic or a setting are distinguished by their description keywords, so no strong selection ambiguity. |
list_worker_routes |
create_worker_route |
low | Same noun 'worker route' with differing verbs list/create; action word almost always disambiguates, though shared tokens (route/worker/pattern/url) make it near-lexically identical in a tool list. |
create_access_rule |
delete_access_rule |
low | Symmetric create/delete on identical object; operation verb disambiguates unless the task is phrased reversibly ('handle the access rule'), which is unusual. |
Compare the field