Cloudflare MCP Server

Access Cloudflare Analytics including traffic, bandwidth, and breakdowns by country/status code. More coming soon

Documentation

@urdigital/mcp-server-cloudflare

An MCP (Model Context Protocol) server exposing Cloudflare's GraphQL Analytics API to Claude, Claude Code, and any other MCP-compatible client — traffic, bandwidth, threats, and breakdowns by country/status code, for a single Cloudflare zone.

Install

No install needed — run directly with npx:

npx -y @urdigital/mcp-server-cloudflare

Configure

Create a scoped API token at dash.cloudflare.com → My Profile → API Tokens → Create Custom Token, with permission Zone → Analytics → Read, scoped to the specific zone (or all zones) you want data from.

You also need the Zone ID, found on that zone's Overview page in the Cloudflare dashboard (right-hand sidebar).

Add to your MCP client config (e.g. Claude Desktop's claude_desktop_config.json):

{
  "mcpServers": {
    "cloudflare": {
      "command": "npx",
      "args": ["-y", "@urdigital/mcp-server-cloudflare"],
      "env": {
        "CLOUDFLARE_API_TOKEN": "your-api-token",
        "CLOUDFLARE_ZONE_ID": "your-zone-id"
      }
    }
  }
}

This server is currently scoped to one zone per instance (matching one token to one zone). Managing multiple zones means running multiple instances with different env vars — same tradeoff as the Clarity server's one-token-per-project design.

Tools

ToolDescription
cloudflare_get_traffic_statsDaily requests, bandwidth, page views, unique visitors, threats
cloudflare_get_hourly_traffic_statsSame metrics, hourly granularity — ~3 day retention limit, see below
cloudflare_get_traffic_by_countryVisits/bandwidth by client country — 1 day query-window limit, see below
cloudflare_get_traffic_by_status_codeVisits by HTTP status code — 1 day query-window limit, see below
cloudflare_get_security_eventsFirewall/WAF events by action, country, ASN — plan-gated, may not be available, see below

Real limits confirmed by testing against a live zone

Cloudflare's GraphQL Analytics API exposes 70+ datasets, and access/limits to each vary by plan tier — these aren't hypothetical, all three were hit directly during testing:

  • httpRequestsAdaptiveGroups (used by the country and status-code breakdown tools) rejects any query window wider than 1 day on standard plans, with an explicit error: cannot request a time range wider than 1d, but your query time range spans 1w. If you need a longer trend, call once per day and aggregate client-side — don't request a wide range and expect it to work.
  • Hourly granularity data (httpRequests1hGroups) is only retained for about 3 days 1 hour back from the current time. Requesting older hourly data returns: cannot request data older than 3d1h, but your query requests data from Xd.... For anything further back, use daily granularity (cloudflare_get_traffic_stats) instead.
  • firewallEventsAdaptiveGroups (security events) is not available on all plans. On a Free-tier zone, this returned: zone '...' does not have access to the path. This is a documented, known Cloudflare limitation (confirmed via their own community forums, not specific to this server) — not a bug, not a token permission issue. If you hit this, it means the zone's current plan doesn't include this dataset.

GraphQL-specific behavior worth knowing

Unlike the REST APIs the other servers in this monorepo talk to, GraphQL APIs (Cloudflare's included) can return HTTP 200 with a failure — the error shows up in an errors array in the response body instead of the HTTP status code. This client checks for that explicitly on every call; a plain status-code check would silently treat a failed query as success.

License

MIT