Services → Cloudflare

Connect Cloudflare

Zones, DNS, WAF rules, zone settings, TLS, Tunnels, Workers, Pages and the account audit log — twenty-seven tools, one API token, nothing to install. Cloudflare is in front of production, so it is where a lot of outages are actually explained.

Tier 2 A Cloudflare API Token, Read permissions only ~5 min profile cloudflare/read-only

Setting this up with your own agent? Give it these instructions.

The whole setup

  1. Cloudflare dashboard → My Profile → API Tokens → Create Token.
  2. Create Custom Token. Name it prodpeek.
  3. Add Read permissions. A good starting set:

| Scope | Permission |

|---|---|

| Account | Account Settings · Read |

| Account | Workers Scripts · Read |

| Account | Cloudflare Tunnel · Read |

| Account | Access: Apps and Policies · Read |

| Account | Logs · Read |

| Zone | Zone · Read |

| Zone | DNS · Read |

| Zone | Zone Settings · Read |

| Zone | Zone WAF · Read |

  1. Zone Resources: pick the specific zones, not "All zones", if you can.
  2. Set a TTL. Add an IP filter if your Prodpeek has a static egress address.
  3. Create, and copy the token.
  4. In Prodpeek: Services → Add a service, pick cloudflare/read-only, leave the upstream alone, paste the token, Test connection.

!!! danger "Never the Global API Key"

It is on the same page, it is easier to find, and it is account-wide with no

scoping and no read-only mode. If you paste one here, the gateway becomes the

only thing standing between an agent and your entire Cloudflare account.

Prodpeek cannot tell the difference — only you can.

Why there is no MCP server to install

Cloudflare publishes MCP servers at *.mcp.cloudflare.com. They authenticate

with OAuth 2.1 browser authorization scoped to the signed-in user — the same

model as Grafana Cloud's, and unusable for the same reason: Prodpeek is a

server-side gateway holding a stored team credential, with no browser and no

signed-in user.

Cloudflare's API v4 takes a scoped bearer token, which is exactly the shape

Prodpeek is built around. So it speaks it directly.

What your agent can then do


cf__list_zones               which domains, and whether each is active
cf__list_dns_records         why it still resolves to the old origin
cf__get_zone_settings        SSL mode, minimum TLS, development mode left on
cf__list_rulesets            what Cloudflare is doing to requests
cf__get_ruleset              which WAF expression is blocking that client
cf__list_tunnels             whether the connector is actually up
cf__list_workers_routes      which paths a Worker handles instead of your origin
cf__list_waiting_rooms       a waiting room left enabled — an outage that looks like success
cf__list_certificate_packs   what expires, and when
cf__list_audit_logs          who changed what, just before this broke

list_audit_logs is the one nobody thinks to ask for and the one that most often

ends the discussion. get_zone_settings is second: development mode left on, or

SSL set to Flexible, explains a surprising number of "it works for me" reports.

What it refuses, and the four that matter

/cfd_tunnel/{id}/token has no tool. That endpoint returns the token that

*runs* the tunnel. Anyone holding it can stand up a connector into the

network that tunnel reaches — it is not a credential for reading Cloudflare, it

is a credential for being inside your infrastructure. list_tunnels and

get_tunnel exist because "is the connector up" is a real question, and the

adapter strips token and tunnel_secret from those records on the way out.

Access service tokens have no tool. They are how machines get past your Zero

Trust policies.

Worker source has no tool. list_workers gives names, sizes and modified

dates. The script body is not a secret by design and is routinely one in

practice — hardcoded API keys in Workers are common enough that this is not

theoretical.

purge_cache has no tool, and it is the one people argue about. It reads

like housekeeping. It is a production change, and a global purge during an

incident makes the incident worse: every request arrives at your origin at once,

while the origin is already the thing in trouble.

Pages env var values are stripped and the keys kept, on the same

reasoning as everywhere else — "is API_KEY set at all" is the question.

Why Tier 2

The Tier 1 half is real: a token built from Read permission groups refuses every

write in this profile *at Cloudflare*, independently of the gateway. Keep it that

way.

It is Tier 2 anyway, because several allowed reads return infrastructure detail —

origin IPs behind the proxy, WAF expressions, who changed what and from where —

and Cloudflare has no permission group meaning "may list DNS records but not read

their content". The roll-up decides the label.

Cloudflare also offers no honest introspection: /user/tokens/verify says the

token is live, not what it may do, and /user/tokens needs a permission a

properly scoped token will not have. So this profile carries no scope probe,

and [prove](../use/prove.md) reports the scope as *not introspectable* rather

than claiming a check it never made.

Checking the token really cannot write


CF=https://api.cloudflare.com/client/v4

# Should succeed, and say "active"
curl -sS -H "Authorization: Bearer $CF_TOKEN" "$CF/user/tokens/verify" | head -c 200

# Should FAIL: a cache purge is the cheapest reversible write to attempt
ZONE=your_zone_id
curl -sS -o /dev/null -w '%{http_code}\n' -X POST \
-H "Authorization: Bearer $CF_TOKEN" -H 'Content-Type: application/json' \
-d '{"purge_everything":false,"files":["https://example.com/prodpeek-permission-test"]}' \
"$CF/zones/$ZONE/purge_cache"

A 403 on the second is the vendor fence doing its half. A 200 means the token

holds Zone.Cache Purge — remake it without that permission group.

Screenshots

My Profile → API Tokens → Create Token → Custom token, with Read permissions only. Screenshot pending — the steps above stand on their own.
My Profile → API Tokens → Create Token → Custom token, with Read permissions only.