Speed up Cloudflare Agent Readiness scans with one Cache Rule
If your Cloudflare Agent Readiness dashboard reports Royal MCP’s discovery documents as “not found” even though every path returns valid JSON, the scanner’s parallel probes are racing an uncached origin fetch. One 3-minute Cache Rule at the edge fixes it, works on Cloudflare Free, and helps every downstream agent runtime that polls these paths.
Is this your issue?
The symptom pattern is specific. All of these should be true:
- Your site is behind Cloudflare (DNS proxied through CF)
- Royal MCP 1.5.1 or later is installed and enabled
- Curl to each discovery path returns 200 OK with valid JSON (verify with the commands in the Verify section below)
- Cloudflare’s Agent Readiness dashboard shows Level 3 items like MCP Server Card or Skills Index as grey / not-detected
- Clicking the audit trail for a failed item shows “Network error fetching” for one or more well-known paths, even though the same paths respond fine to your own curl
If your discovery paths return 404 or non-JSON instead of 200 JSON, that’s a different issue (plugin not enabled, host blocking .well-known/, or the plugin isn’t installed). See the Royal MCP support hub for those paths.
Why this happens
Cloudflare Free does not auto-cache application/json responses by default. Every Agent Readiness scanner probe to Royal MCP’s discovery documents becomes an uncached origin fetch that goes through the full WordPress bootstrap, taking 500 to 900 milliseconds per request.
Cloudflare’s scanner probes multiple candidate paths for MCP Server Card in parallel (/.well-known/mcp/server-card.json, /.well-known/mcp/server-cards.json, /.well-known/mcp.json) with a short internal timeout on each. When origin latency stacks up, one or more probes race the timeout and the scanner reports the whole check as “not found”, even though the paths are healthy.
Edge-caching the responses drops response time to under 200 milliseconds. Scanner probes complete comfortably inside the timeout, race conditions vanish, and the checks turn green.
The Fix: 5 steps (3 minutes)
Open Cloudflare Dashboard → your zone → Caching → Cache Rules
Log into dash.cloudflare.com, select the zone in front of your WordPress site, click Caching in the left sidebar, then Cache Rules.
Create a new Cache Rule
Click Create rule. Give it a descriptive name like Cache Royal MCP discovery paths. Choose the Custom filter expression radio.
Add four OR-joined URI Path conditions
Using the visual expression builder, add four rows joined with Or (not And). Cloudflare Free doesn’t allow regex operators, so use starts with:
| # | Field | Operator | Value |
|---|---|---|---|
| 1 | URI Path | starts with | /.well-known/mcp |
| 2 | URI Path | starts with | /.well-known/skills |
| 3 | URI Path | starts with | /.well-known/agent-skills |
| 4 | URI Path | starts with | /.well-known/oauth- |
All four rows join with Or. Together they match every Royal MCP discovery path: MCP Server Card (all three path variants Cloudflare’s scanner probes), Skills Index (both aliases), OAuth Protected Resource, and OAuth Authorization Server metadata.
If your CF dashboard exposes the custom-expression text box, paste this verbatim to skip the visual builder:
(starts_with(http.request.uri.path, "/.well-known/mcp")) or (starts_with(http.request.uri.path, "/.well-known/skills")) or (starts_with(http.request.uri.path, "/.well-known/agent-skills")) or (starts_with(http.request.uri.path, "/.well-known/oauth-"))
Set cache behavior
Configure the following under the Then section:
- Cache eligibility: Eligible for cache
- Edge TTL: Use cache-control header from origin, bypass cache if not present
- Browser TTL: Use cache-control header from origin, bypass cache if not present
- Leave Vary, Cache Reserve, and every other optional setting empty
Honoring the origin cache-control keeps Royal MCP’s plugin in charge of the TTL, so there’s no CF-side TTL to keep in sync when the plugin updates.
Deploy and verify
Click Deploy. Then verify the rule took effect by curling a discovery path twice (the first request warms the cache, the second returns HIT):
curl -sSI https://your-site.com/.well-known/mcp/server-cards.json curl -sSI https://your-site.com/.well-known/mcp/server-cards.json
The second response should include cf-cache-status: HIT. Response time on the second request should drop from ~800ms to under 200ms.
Verify all discovery paths
Once the rule is deployed and CF has warmed the cache, every Royal MCP discovery path should return cf-cache-status: HIT on the second request. Copy-paste this into your terminal:
for path in \ "/.well-known/mcp/server-cards.json" \ "/.well-known/mcp/server-card.json" \ "/.well-known/mcp.json" \ "/.well-known/skills/index.json" \ "/.well-known/agent-skills/index.json" \ "/.well-known/oauth-authorization-server" \ "/.well-known/oauth-authorization-server/mcp" \ "/.well-known/oauth-protected-resource"; do curl -sSI "https://your-site.com$path" | grep -i "cf-cache-status" curl -sSI "https://your-site.com$path" | grep -i "cf-cache-status" done
You should see cf-cache-status: MISS on the first probe of each path (warming) and cf-cache-status: HIT on the second. If any path stays MISS after the second probe, that path isn’t matching your Cache Rule expression, so re-check the URI Path values in step 3.
Re-run the Agent Readiness scan
Once the caches are warm, return to the Cloudflare Agent Readiness dashboard for your zone and click Rescan. Level 3 items that were grey should turn green: MCP Server Card, Skills Index, and OAuth Protected Resource. If any still show grey, click the audit trail and check whether the failure is “Network error” (still a caching issue, so wait a few minutes for CF’s scanner to hit the edge cache) or a shape/schema issue (unrelated to this rule).