You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(cloudflare): correct verified API defects and stop filters leaking into writes
Independent re-validation of all 48 tools against developers.cloudflare.com
turned up defects that the shipped tools would have hit on their happy path.
Delete DNS record reported every success as a failure. That endpoint is the
one Cloudflare v4 response with no envelope — its documented body is
`{"result":{"id":...}}` with no `success` — so `!data.success` was always
true. Branch on an explicit `=== false` instead.
The two replace-semantics PATCH endpoints could silently destroy live config.
Update rate limit rule defaulted a missing action to `block`, converting an
existing `log` or challenge rule into a hard block on real traffic; update
ruleset rule left action and expression optional and had no `ratelimit` or
`logging` passthrough, so updating a rate limiting rule stopped it rate
limiting. Both now require the fields the replacement needs, and the ruleset
rule carries the two nested objects through.
Access applications were unbuildable for most types: `domain` was required,
but it does not exist on the saas, app_launcher, warp, biso, dash_sso,
infrastructure, mcp, mcp_portal, or proxy_endpoint request variants. The
application type enum was also six values behind. Access group `is_default`
is an array of rule objects, not a boolean.
Purge cache merged every supplied target into one body, but the purge body is
a one-of over the five target kinds; it now names the conflict instead.
The remaining fixes are documentation drift: the priority field is MX and URI
only (an SRV record carries priority inside its content), the certificate
status filter documents only "all", the Worker tag filter takes tag:allowed
pairs, and the managed-rule override list conflated the DDoS-only
sensitivity_level with the WAF rule-level set.
Separately, controls that share a subBlock id share one stored value, and
`shouldSerializeSubBlock` short-circuits on `mode: 'advanced'` before it
evaluates `condition` — so a hidden list filter was reaching a write. A
`list_dns_records` content filter could overwrite a record's content, cache
tags could be written onto a DNS record, and the zone status enum could reach
the tunnel list, whose enum is disjoint. Filters that differ from the value
they collided with now carry their own id, remapped through one table before
any coercion. Sharings that mean the same thing everywhere are unchanged.
Aliases are cleared by explicit assignment rather than destructuring, because
the executor merges the mapper's output over the raw inputs and a merely
omitted key survives as its raw subBlock string. The tests assert on that
merged result, and three mechanical invariants now go red on a new collision:
no id spans a read filter and a written value, no dropdown id carries two
option sets, and no hidden advanced control feeds an operation that cannot
render it. That last one found the name filter reaching three list operations.
Copy file name to clipboardExpand all lines: apps/docs/content/docs/en/integrations/cloudflare.mdx
+16-14Lines changed: 16 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -282,7 +282,7 @@ Creates a new DNS record for a zone.
282
282
|`content`| string | Yes | DNS record content \(e.g., IP address for A records, target for CNAME\)|
283
283
|`ttl`| number | No | Time to live in seconds \(1 = automatic, default: 1\)|
284
284
|`proxied`| boolean | No | Whether to enable Cloudflare proxy \(default: false\)|
285
-
|`priority`| number | No |Priority for MX and SRV records |
285
+
|`priority`| number | No |Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority, weight, port, and target inside the record content instead|
286
286
|`comment`| string | No | Comment for the DNS record |
287
287
|`tags`| string | No | Comma-separated tags for the DNS record |
288
288
|`apiKey`| string | Yes | Cloudflare API Token |
@@ -301,7 +301,7 @@ Creates a new DNS record for a zone.
301
301
|`proxied`| boolean | Whether Cloudflare proxy is enabled |
302
302
|`ttl`| number | Time to live in seconds \(1 = automatic\)|
303
303
|`locked`| boolean | Whether the record is locked |
304
-
|`priority`| number |Priority for MX and SRV records |
304
+
|`priority`| number |Record priority, returned for MX and URI records |
305
305
|`comment`| string | Comment associated with the record |
306
306
|`tags`| array | Tags associated with the record |
307
307
|`comment_modified_on`| string | ISO 8601 timestamp when the comment was last modified |
@@ -382,7 +382,7 @@ Lists SSL/TLS certificate packs for a zone.
382
382
| Parameter | Type | Required | Description |
383
383
| --------- | ---- | -------- | ----------- |
384
384
|`zoneId`| string | Yes | The zone ID to list certificates for |
385
-
|`status`| string | No |Filter certificate packs by status \(e.g., "all", "active", "pending"\)|
385
+
|`status`| string | No |Set to "all" to include every certificate pack regardless of status. Cloudflare documents no other value for this filter; omitting it returns only active packs|
386
386
|`page`| number | No | Page number of paginated results \(default: 1\)|
387
387
|`per_page`| number | No | Number of certificate packs per page \(default: 20, min: 5, max: 50\)|
388
388
|`deploy`| string | No | Filter by deployment environment: "staging" or "production" |
@@ -763,12 +763,14 @@ Updates a rule in a zone ruleset. Cloudflare replaces the rule definition rather
763
763
|`zoneId`| string | Yes | The zone ID that owns the ruleset |
764
764
|`rulesetId`| string | Yes | The ruleset ID containing the rule |
765
765
|`ruleId`| string | Yes | The rule ID to update |
766
-
|`action`| string |No| The action the rule performs, e.g. block, challenge, js_challenge, managed_challenge, log, skip, or execute |
|`action`| string |Yes| The action the rule performs, e.g. block, challenge, js_challenge, managed_challenge, log, skip, or execute. Required because this endpoint replaces the rule definition — omitting it resets the stored action|
767
+
|`expression`| string |Yes| Cloudflare filter expression selecting matching requests. Required because this endpoint replaces the rule definition — omitting it resets the stored expression|
768
768
|`description`| string | No | Human-readable description of the rule |
769
769
|`enabled`| boolean | No | Whether the rule is enabled |
770
770
|`ref`| string | No | Reference tag that stays stable across rule updates |
771
-
|`actionParameters`| string | No | JSON object of action-specific parameters, e.g. \{"id":"<MANAGED_RULESET_ID>","overrides":\{"rules":\[\{"id":"<RULE_ID>","action":"log","enabled":true\}\]\}\}|
771
+
|`actionParameters`| string | No | JSON object of action-specific parameters, e.g. \{"id":"<MANAGED_RULESET_ID>","overrides":\{"rules":\[\{"id":"<RULE_ID>","action":"log","enabled":true,"score_threshold":40\}\]\}\}|
772
+
|`ratelimit`| string | No | JSON rate limiting configuration to preserve on a rule in the http_ratelimit phase, e.g. \{"characteristics":\["cf.colo.id","ip.src"\],"period":60,"requests_per_period":100\}. Because the update replaces the rule, omitting this on a rate limiting rule stops it rate limiting |
773
+
|`logging`| string | No | JSON logging configuration to preserve, e.g. \{"enabled":true\}. Omitting it on a rule that had logging configured resets it to the default |
772
774
|`apiKey`| string | Yes | Cloudflare API Token |
773
775
774
776
#### Output
@@ -856,7 +858,7 @@ Lists the WAF managed rulesets deployed on a zone together with the overrides ap
856
858
| ↳ `description`| string | Description of the deployment rule |
857
859
| ↳ `expression`| string | Filter expression scoping which requests the managed ruleset runs on |
858
860
| ↳ `enabled`| boolean | Whether the deployment is enabled |
859
-
| ↳ `overrides`| json | Overrides applied to the managed ruleset, at three levels — ruleset \(top level\), categories, and rules. The Rulesets engine documents actionand enabled as the properties overridable at every level; individual managed rulesets may add more, and the OWASP Core Ruleset also accepts score_threshold on a rule override|
861
+
| ↳ `overrides`| json | Overrides applied to the managed ruleset, at three levels. Cloudflare documents action, enabled, and sensitivity_level at the ruleset \(top\) level; category, action, enabled, and sensitivity_level per category; and id, action, enabled, score_threshold, and sensitivity_level per rule. Rule overrides beat category overrides, which beat the ruleset-level override. sensitivity_level applies only to the DDoS phases, so for a WAF managed ruleset the rule-level properties are action, enabled, and score_threshold|
860
862
|`total_count`| number | Number of managed ruleset deployments found |
861
863
862
864
### Cloudflare List Rate Limiting Rules
@@ -957,7 +959,7 @@ Updates a rate limiting rule in the http_ratelimit phase entry point ruleset of
957
959
|`characteristics`| string | Yes | Comma-separated counting characteristics. cf.colo.id is mandatory, plus exactly one of ip.src or cf.unique_visitor_id |
958
960
|`period`| number | Yes | Counting window in seconds. Cloudflare accepts only 10, 60, 120, 300, 600, or 3600 |
959
961
|`requestsPerPeriod`| number | Yes | Number of requests allowed within the counting period before the action fires |
960
-
|`action`| string |No| Action applied once the limit is exceeded, e.g. block, managed_challenge, js_challenge, challenge, or log. Defaults to block |
962
+
|`action`| string |Yes| Action applied once the limit is exceeded: block, managed_challenge, js_challenge, challenge, or log. Required because this endpoint replaces the rule rather than merging into it — a defaulted action would silently convert an existing log or challenge rule into a hard block |
961
963
|`mitigationTimeout`| number | No | Seconds the action stays applied. Cloudflare accepts only 0, 10, 60, 120, 300, 600, 3600, or 86400 |
962
964
|`counting_expression`| string | No | Optional expression defining which requests are counted |
963
965
|`requestsToOrigin`| boolean | No | When true, only requests that reach the origin are counted |
@@ -1073,8 +1075,8 @@ Creates a Cloudflare Access (Zero Trust) application that puts an identity check
1073
1075
| Parameter | Type | Required | Description |
1074
1076
| --------- | ---- | -------- | ----------- |
1075
1077
|`accountId`| string | Yes | The Cloudflare account ID. Access applications are account-scoped |
1076
-
|`type`| string | Yes | Application type, e.g. self_hosted, saas, ssh, vnc, app_launcher, warp, or bookmark |
1077
-
|`domain`| string |Yes| The primary hostname and path secured by Access, e.g. internal.example.com or example.com/admin |
|`domain`| string |No| The primary hostname and path secured by Access, e.g. internal.example.com or example.com/admin. Required for the self_hosted, ssh, vnc, rdp, and bookmark types; the saas, app_launcher, warp, biso, dash_sso, infrastructure, mcp, mcp_portal, and proxy_endpoint types do not accept it|
1078
1080
|`name`| string | No | Friendly name shown in the dashboard and App Launcher |
1079
1081
|`sessionDuration`| string | No | How long an Access session stays valid, e.g. 24h or 30m |
1080
1082
|`allowedIdps`| string | No | Comma-separated identity provider IDs users may authenticate with. Leave empty to allow all configured providers |
@@ -1118,8 +1120,8 @@ Updates a Cloudflare Access (Zero Trust) application. This replaces the applicat
1118
1120
| --------- | ---- | -------- | ----------- |
1119
1121
|`accountId`| string | Yes | The Cloudflare account ID. Access applications are account-scoped |
1120
1122
|`appId`| string | Yes | The Access application ID to update |
1121
-
|`type`| string | Yes | Application type, e.g. self_hosted, saas, ssh, vnc, app_launcher, warp, or bookmark |
1122
-
|`domain`| string |Yes| The primary hostname and path secured by Access |
|`domain`| string |No| The primary hostname and path secured by Access. Required for the self_hosted, ssh, vnc, rdp, and bookmark types; the saas, app_launcher, warp, biso, dash_sso, infrastructure, mcp, mcp_portal, and proxy_endpoint types do not accept it|
1123
1125
|`name`| string | No | Friendly name shown in the dashboard and App Launcher |
1124
1126
|`sessionDuration`| string | No | How long an Access session stays valid, e.g. 24h or 30m |
1125
1127
|`allowedIdps`| string | No | Comma-separated identity provider IDs users may authenticate with |
@@ -1332,7 +1334,7 @@ Lists the reusable Cloudflare Access (Zero Trust) groups in an account. Groups b
1332
1334
|`groups`| array | Access groups in the account |
1333
1335
| ↳ `id`| string | Access group identifier |
1334
1336
| ↳ `name`| string | Group name |
1335
-
| ↳ `is_default`|boolean|Whether the group is automatically applied to every new application |
1337
+
| ↳ `is_default`|json|Rules that place this group in every Access application by default. Cloudflare returns an array of rule objects here, not a boolean|
1336
1338
| ↳ `include`| json | Rules evaluated with OR logic |
1337
1339
| ↳ `exclude`| json | Rules evaluated with NOT logic |
1338
1340
| ↳ `require`| json | Rules evaluated with AND logic |
@@ -1554,7 +1556,7 @@ Lists the Workers scripts deployed in an account. Requires an API token with Acc
1554
1556
| Parameter | Type | Required | Description |
1555
1557
| --------- | ---- | -------- | ----------- |
1556
1558
|`accountId`| string | Yes | The Cloudflare account ID. Workers scripts are account-scoped |
1557
-
|`tags`| string | No | Filter scripts by tag, using Cloudflare's tag filter syntax|
1559
+
|`tags`| string | No | Filter scripts by tag. Cloudflare expects a comma-separated list of tag:allowed pairs where allowed is yes or no, e.g. team:core:yes,deprecated:no|
0 commit comments