| cf_list_accountsA | List Cloudflare accounts the configured API token can see. Calls: GET /accounts (auto-paginated, up to 5 pages).
Returns the envelope (§6.5) with `data` = list of account dicts
(each has at least `id`, `name`, `type`, `created_on`).
|
| cf_list_zonesA | List Cloudflare zones (domains) the token can see. Args:
account_id: optional account-ID filter. Defaults to CF_ACCOUNT_ID env
var when set, otherwise lists across all accessible accounts.
name_pattern: optional glob filter applied client-side (e.g.
"*.example.*"). Cloudflare's API does not support glob, so this
is a post-filter on the API response.
max_pages: pagination cap (default 5 × per_page 50 = 250 zones).
Calls: GET /zones (auto-paginated).
Returns: envelope with `data = {zones: [...], count, ...}`.
**Compact projection** — each zone is reduced to id, name, status, paused,
type, created_on, modified_on, activated_on, development_mode,
account_id, account_name, plan_name. Full zone config (name_servers,
name_servers_history, owner, permissions, meta, etc.) is dropped to keep
multi-page walks under the 20K-token response ceiling. For full config,
use `cf_get_zone(zone_id)`.
|
| cf_get_zoneA | Get full details for one zone (plan, name servers, settings summary, status). Args:
zone_id: 32-char Cloudflare zone ID.
Calls: GET /zones/{zone_id}.
Allowlist enforcement runs AFTER the API call (we need the zone name to
check against the list). If the zone is outside the allowlist, returns
`zone_not_allowed` error — but a CF quota call has been spent.
|
| cf_resolve_zoneA | Look up a zone ID by its name (the canonical DNS name). Args:
zone_name: e.g. "example.com". Trailing dots are stripped.
Calls: GET /zones?name=<zone_name>&match=all.
Returns: envelope with `data = {zone_id, zone_name, account_id, ...}`.
Errors:
- zone_not_allowed when the resolved zone is outside CF_ZONE_ALLOWLIST.
- not_found when zero zones match.
- validation when more than one zone matches the same name (rare but
possible across multiple accounts — agent must disambiguate).
|
| cf_list_rulesetsA | List all rulesets visible at the given scope. Args:
scope: 'zone' or 'account'.
scope_id: matching Cloudflare ID.
Calls: GET /{zones|accounts}/{scope_id}/rulesets.
Returns: envelope with `data = {rulesets: [...], count, scope, scope_id}`.
Each ruleset summary has: id, name, description, kind (managed/custom/zone),
version, last_updated, phase.
|
| cf_get_rulesetA | Fetch a single ruleset including all its rules. Args:
scope: 'zone' or 'account'.
scope_id: matching CF ID.
ruleset_id: 32-char ruleset ID.
Calls: GET /{zones|accounts}/{scope_id}/rulesets/{ruleset_id}.
Returns: envelope with `data` = full ruleset dict including `rules[]`.
|
| cf_get_entrypoint_rulesetA | Get the ordered list of rules deployed at a zone's entrypoint for a phase. The "entrypoint ruleset" is the in-line custom ruleset Cloudflare runs
at a given phase. For most WAF/rate-limit investigations this is the
ruleset you want — it shows what's actually executing, in order.
Args:
zone_id: 32-char Cloudflare zone ID.
phase: phase name. Common values:
- http_request_firewall_custom (custom WAF rules)
- http_request_firewall_managed (managed WAF deployments)
- http_ratelimit (rate-limiting rules)
- http_request_sbfm (Super Bot Fight Mode rules)
- http_request_transform (Transform Rules — request)
- http_request_origin (Origin Rules)
Calls: GET /zones/{zone_id}/rulesets/phases/{phase}/entrypoint.
Returns: envelope with `data` = the entrypoint ruleset dict including
its ordered `rules[]`.
|
| cf_get_ruleA | Look up a single rule by ID. Cloudflare exposes rule lookup via the parent ruleset; this is a
convenience wrapper that fetches the ruleset and projects the matching
rule. Used heavily for "what does rule X do" resolution when a firewall
event reports an unknown rule ID.
Args:
scope: 'zone' or 'account'.
scope_id: matching CF ID.
ruleset_id: parent ruleset ID.
rule_id: rule ID to extract.
Calls: GET /{zones|accounts}/{scope_id}/rulesets/{ruleset_id} → project rule.
Errors:
not_found when the ruleset returns 200 but no rule matches the ID.
|
| cf_list_custom_rulesA | Convenience: list a zone's custom WAF rules (http_request_firewall_custom). Equivalent to `cf_get_entrypoint_ruleset(zone_id, "http_request_firewall_custom")`
but the return shape is normalized to `{rules: [...], count, zone_id}`.
|
| cf_list_rate_limit_rulesB | Convenience: list a zone's rate-limit rules (http_ratelimit phase). Same shape as `cf_list_custom_rules` but targets a different phase.
|
| cf_list_managed_rulesetsC | List managed ruleset deployments at a zone's firewall_managed phase. These are the Cloudflare Managed Ruleset and OWASP Core Ruleset that
are deployed against incoming requests. Each deployment includes
severity overrides, exposed-credentials check, etc.
Calls: GET /zones/{zone_id}/rulesets/phases/http_request_firewall_managed/entrypoint.
Returns: envelope with `data = {rules: [...], count, zone_id}`.
|
| cf_get_managed_rule_detailsA | Look up details of a specific managed-ruleset rule (account-scoped). Managed rulesets are owned by Cloudflare and live at the account scope;
individual managed rules are referenced from a zone's deployment.
This tool is the bridge: given a managed (ruleset_id, rule_id), it
returns the full rule definition so the agent can determine what the
rule actually matches (used for FP triage on managed-rule hits).
Calls: GET /accounts/{account_id}/rulesets/{ruleset_id} → project rule.
|
| cf_get_bot_management_configA | Get the current Bot Management configuration for a zone. Args:
zone_id: 32-char Cloudflare zone ID.
Calls: GET /zones/{zone_id}/bot_management.
Returns: envelope with `data` = the full BM config dict, including:
- fight_mode (bool)
- using_latest_model (bool)
- enable_js (bool)
- sbfm_definitely_automated (str — block/allow/managed)
- sbfm_likely_automated (str)
- sbfm_verified_bots (str)
- sbfm_static_resource_protection (bool)
- optimize_wordpress (bool)
- suppress_session_score (bool)
- auto_update_model (bool)
- ai_bots_protection (str — block/disabled)
|
| cf_list_super_bot_fight_mode_configA | Get the Super Bot Fight Mode (SBFM) configuration projection. Re-uses the same /bot_management endpoint as cf_get_bot_management_config
but projects only the SBFM-relevant fields — convenient when the agent
is specifically investigating bot-blocking behavior.
Args:
zone_id: 32-char Cloudflare zone ID.
Returns: envelope with `data` = {definitely_automated, likely_automated,
verified_bots, static_resource_protection, optimize_wordpress,
ai_bots_protection}.
|
| cf_query_firewall_events_groupedA | Group firewall events by chosen dimensions over a time window. Calls: POST /graphql, firewallEventsAdaptiveGroups dataset.
Args:
zone_id: zone tag (32-char hex).
since: RFC 3339 / ISO 8601 start, e.g. '2026-05-28T00:00:00Z'.
until: ISO 8601 end, must be after `since`.
group_by: dimensions to group on (e.g. ['action', 'clientCountryName']).
See _FIREWALL_GROUP_DIMENSIONS for the allowed set.
filters: extra Cloudflare filter terms (e.g. {'action': 'block',
'clientCountryName': 'PL'}). Operators like `_in`, `_neq` may be
appended to the key (e.g. 'action_in': ['block', 'managed_challenge']).
limit: rows per page, clamped to [1, 500]. Default 50.
cursor: opaque continuation token from a prior call's `next_cursor`.
Returns: envelope with `data = {rows, count, page}` and `next_cursor`.
|
| cf_query_firewall_events_rawA | Raw firewall events (one row per individual event) over a time window. Calls: POST /graphql, firewallEventsAdaptive dataset.
Args:
zone_id: zone tag.
since, until: ISO-8601 time range.
filters: extra filter terms.
limit: rows per page, clamped to [1, 500]. Default 50.
cursor: continuation token.
verbose: when True, includes additional fields like userAgent,
referer, rayName, clientRequestPath. Subject to the same
~20K-token response ceiling — narrow `limit` accordingly.
Returns: envelope with `data = {rows, count, page}` and `next_cursor`.
|
| cf_query_http_requests_groupedA | Group HTTP request analytics by chosen dimensions over a time window. Calls: POST /graphql, httpRequestsAdaptiveGroups dataset.
Args:
zone_id: zone tag.
since, until: ISO-8601 time range.
group_by: dimensions from _HTTP_GROUP_DIMENSIONS.
filters: extra terms (e.g. {'edgeResponseStatus': 403,
'clientRequestPath': '/oauth/token'}).
limit: page size [1, 500].
cursor: continuation token.
The grouped HTTP dataset also includes a `sum { visits, edgeResponseBytes }`
aggregate block when bytes/visit dimensions aren't already in group_by.
Returns: envelope with `data = {rows, count, page}` and `next_cursor`.
|
| cf_query_http_requests_rawA | Raw HTTP request rows over a time window. Calls: POST /graphql, httpRequestsAdaptive dataset.
Args, returns: see cf_query_firewall_events_raw — same shape, different
dataset. Use this for unsampled per-request drill-down on traffic patterns
(bot scores, cache statuses, origin response codes).
|
| cf_query_bot_events_groupedA | Group bot-management events by dimensions over a time window. Internally queries `firewallEventsAdaptiveGroups` with the
`source = "botManagement"` filter pre-applied — Cloudflare doesn't
expose a standalone `botManagementEventsAdaptiveGroups` dataset on
standard plans (verified against the live schema). Bot decisions
flow into the firewall-events dataset with that source tag.
Allowed `group_by` dimensions are the firewall set
(`_FIREWALL_GROUP_DIMENSIONS`). For per-request bot SCORE distribution
(`botScore`, `botScoreSrcName`), use `cf_query_http_requests_grouped`
instead — those fields live on the HTTP requests dataset, not the
firewall-events one.
|
| cf_baseline_traffic_diffA | Compare attack-window traffic vs a prior baseline window on the same path. Runs two `httpRequestsAdaptiveGroups` queries grouped by
`edgeResponseStatus` and `clientCountryName`, returning a side-by-side
diff suitable for the ATK archetype workflow.
Args:
zone_id: zone tag.
match_path: exact `clientRequestPath` to filter (e.g. '/oauth/token').
attack_since, attack_until: ISO-8601 attack window.
baseline_lookback_days: how many days before `attack_since` to align
the baseline window (defaults to 7).
Calls: POST /graphql, two httpRequestsAdaptiveGroups queries.
Returns: envelope with `data = {attack: {...}, baseline: {...},
window_seconds: N, zone_id, match_path}`.
|
| cf_list_access_appsA | List Cloudflare Access applications configured at the account. Calls: GET /accounts/{account_id}/access/apps (auto-paginated).
Returns: envelope with `data = {apps: [...], count, account_id}`.
**Compact projection**: each app is reduced to {id, name, domain, type,
session_duration, auto_redirect_to_identity, aud, created_at, updated_at}.
Cloudflare returns a much larger payload per app (policies, allowed_idps,
cors_headers, custom_pages, http_only_cookie_attribute, etc.) — at 50
apps × ~3.7KB this blows the 20K-token response ceiling. For full app
config, call `cf_get_access_app(account_id, app_id)`.
|
| cf_get_access_appA | Get a single Access app, including its session and CORS configuration. Calls: GET /accounts/{account_id}/access/apps/{app_id}.
|
| cf_list_access_policiesA | List Access policies — either account-wide or for a specific app. Args:
account_id: account ID.
app_id: when provided, returns policies attached to that app.
When omitted, returns all account-level reusable policies.
Calls:
- GET /accounts/{account_id}/access/apps/{app_id}/policies (app-scoped)
- GET /accounts/{account_id}/access/policies (account-scoped)
|
| cf_list_gateway_rulesA | List Cloudflare Gateway (Zero Trust DNS/network/HTTP) rules. Args:
account_id: account ID.
rule_type: 'dns', 'network', or 'http'. Defaults to 'http'.
Calls: GET /accounts/{account_id}/gateway/rules with filter.
|
| cf_list_warp_devicesB | List WARP-enrolled devices in the account. Calls: GET /accounts/{account_id}/devices (auto-paginated).
|
| cf_get_warp_deviceB | Get a single WARP device's posture and metadata. Calls: GET /accounts/{account_id}/devices/{device_id}.
|
| cf_list_service_tokensA | List Access service tokens — METADATA ONLY (never returns the secret). Cloudflare's API only returns the token secret on creation, so this
endpoint's response is intrinsically metadata-only.
Calls: GET /accounts/{account_id}/access/service_tokens.
|
| cf_list_identity_providersC | List configured Access Identity Providers (Okta, AzureAD, etc.). Calls: GET /accounts/{account_id}/access/identity_providers.
|
| cf_list_logpush_jobsA | List configured Logpush jobs at a given scope. Args:
scope: 'zone' or 'account'.
scope_id: Cloudflare zone ID or account ID matching the scope.
Calls: GET /{zones|accounts}/{scope_id}/logpush/jobs.
Returns: envelope with `data = {jobs: [...], count: N, scope, scope_id}`.
Each job carries: id, dataset, destination_conf (redacted of secrets by
Cloudflare), enabled, frequency, last_complete, last_error, error_message.
|
| cf_get_logpush_jobA | Get a single Logpush job's configuration + last delivery status. Args:
scope: 'zone' or 'account'.
scope_id: Cloudflare zone ID or account ID matching the scope.
job_id: Logpush job ID (integer-as-string from CF).
Calls: GET /{zones|accounts}/{scope_id}/logpush/jobs/{job_id}.
|
| cf_build_dashboard_urlA | Construct a deep link into the Cloudflare dashboard for a given view. Args:
view_type: one of:
security_events, waf_custom_rules, rate_limiting_rules,
bot_management, analytics_traffic, logpush,
access_apps, gateway_rules.
account_id: Cloudflare account ID. Required for all views. Falls back
to CF_ACCOUNT_ID env var when not supplied.
zone: zone name or zone ID for zone-scoped views (e.g. "example.com").
filters: optional `?key=value` query-string overrides (e.g.
`{"action": "block"}` on security_events).
Returns: envelope with `data = {url, view_type, account_id, zone}`.
Errors:
validation when view_type is unknown, account_id is missing, or a
zone-scoped view was called without a zone.
|
| cf_validate_wirefilterA | Best-effort syntactic check of a Cloudflare Wirefilter (Rules language) expression. NOT a full grammar — catches balanced-paren violations, unknown operator
spellings, and obvious typos. A `{valid: true}` response does NOT
guarantee Cloudflare's evaluator will accept the expression at runtime.
Args:
expression: the wirefilter source, e.g. `(http.request.uri.path
contains "/admin" and ip.src in {1.2.3.4 5.6.7.8})`.
Returns: envelope with `data = {valid: bool, errors: list, expression}`.
Note: this tool returns success-envelope even when `valid=false`;
the validator's purpose IS to report syntactic issues.
|