MCP Spotlight: Cloudflare MCP Server — The 2,500-Endpoint Edge Bridge With Code Mode, Two-Tool Minimalism, and the API-Default Reference for Agents
Server: Cloudflare MCP Servers by Cloudflare
License: MIT (open source) · Tools: 2 in the Code Mode profile (mcp_search, mcp_execute); 13+ specialized servers for specific products
Coverage: The entire Cloudflare API — over 2,500 endpoints spanning DNS, Workers, R2, Zero Trust, Workers AI, D1, KV, Pages, Stream, Images, Access, WAF, Analytics, Logs, etc.
Transport: Remote (mcp.cloudflare.com) + stdio (self-hosted) · Auth: Cloudflare API Token (per-zone/per-account, scoped)
GitHub: github.com/cloudflare/mcp-server-cloudflare
Docs: developers.cloudflare.com/agents/model-context-protocol/cloudflare
Blog: blog.cloudflare.com/code-mode-mcp
Every infrastructure agent eventually needs Cloudflare. The naive "wrap Cloudflare's 2,500+ REST endpoints as 2,500+ MCP tools" approach bloats the context window past usability and changes the tool surface on every API release. The "give the agent a full API token with all scopes" approach grants edit access to DNS, Workers, R2, every account resource. The "give the agent nothing" approach blocks the entire edge-infrastructure-automation category.
The official Cloudflare MCP Servers by Cloudflare are the bridge that resolves this. 2 tools in the Code Mode profile (mcp_search, mcp_execute), built around an API-as-code execution model — the agent searches the API surface, gets back TypeScript code that calls the API, executes the code, gets the result. The 2-tool profile gives access to all 2,500+ Cloudflare API endpoints while keeping the context footprint at ~1,000 tokens. MIT-licensed, official Cloudflare-maintained, available as 13+ specialized servers for specific products.
This is the edge-infrastructure default for AI agents in 2026. Two-tool minimalism, API-as-code, ubiquitous use across the entire Cloudflare platform.
The Architecture: Code Mode (2-Tool Minimalism for 2,500 Endpoints)
Cloudflare's boldest design choice: the entire 2,500-endpoint API is exposed via 2 MCP tools. The genius is in the execution model.
mcp_search: Find the right endpoint
mcp_search(
query="purge cache by URL or tag",
max_results=5
)
→ Returns:
[
{
"name": "purgeCache",
"description": "Purge cached content by URL, tag, prefix, or entire zone.",
"params": [
{"name": "zone_id", "type": "string", "required": true},
{"name": "purge_everything", "type": "boolean"},
{"name": "files", "type": "string[]"},
{"name": "tags", "type": "string[]"},
{"name": "hosts", "type": "string[]"}
],
"endpoint": "POST /zones/{zone_id}/purge_cache"
},
...
]
The agent searches the API surface using natural language. The result is structured metadata — name, description, parameters, endpoint URL. The agent doesn't memorize API paths; it queries for what it needs.
mcp_execute: Run the API call as code
mcp_execute(
code=`
const result = await cloudflare.zones.purgeCache({
zone_id: 'abc123',
files: ['https://acme.com/about'],
});
return result;
`
)
→ Returns the API response
The agent writes TypeScript code that calls the API, the server executes it in a sandboxed runtime, returns the result. Code as API calls.
This is the right primitive because:
- The 2,500 endpoints collapse to 2 MCP tools (vs 2,500)
- The agent's context stays bounded (~1,000 tokens regardless of how many endpoints exist)
- The API surface evolves without breaking the tool surface
- The agent composes calls naturally using familiar TypeScript syntax
The Code Mode pattern (Cloudflare's term) is the design lesson every "broad-API-as-MCP" server should copy. Don't expose endpoints as tools; expose them as a TypeScript API the agent writes code against.
The 13+ Specialized MCP Servers
Beyond the Code Mode profile, Cloudflare ships 13+ specialized MCP servers for common workflows:
| Server | Purpose |
|---|---|
| Cloudflare API | The universal Code Mode server (2,500 endpoints) |
| Workers / Pages | Worker deployment, logs, bindings |
| R2 | Object storage operations |
| D1 | SQLite-compatible serverless database |
| KV | Key-value storage |
| Workers AI | LLM inference, embeddings, image generation |
| Stream | Video streaming + playback |
| Images | Image transformations, variants |
| DNS | DNS record management (separate from full API) |
| Analytics | Performance + traffic analytics |
| Logs | Log push + tail queries |
| Zero Trust | Access policies, tunnels, gateways |
| Browser | Headless browser rendering |
For workflows that benefit from focused tool surfaces (e.g., "manage DNS records" or "upload to R2"), the specialized servers expose the right primitives directly. For workflows that span multiple Cloudflare products, the Code Mode universal server is the right choice.
The Killer Combination: Search + Execute
The two highest-leverage primitives:
Search to discover
mcp_search(query="add DNS A record")
→ Returns the create_dns_record endpoint spec
// Or for multiple things
mcp_search(query="upload file to R2 and get public URL")
→ Returns both put_object and presigned_url endpoint specs
Execute to run
mcp_execute(`
// Add DNS record
const dnsResult = await cloudflare.dns.records.create({
zone_id: 'abc123',
type: 'A',
name: 'api.acme.com',
content: '192.0.2.1',
proxied: true,
});
// Upload file to R2
const r2Result = await cloudflare.r2.objects.put({
bucket: 'my-bucket',
key: 'deploy/v1.json',
body: '{"version": "1.0.0"}',
content_type: 'application/json',
});
return { dns: dnsResult, r2: r2Result };
`);
The agent searches for the endpoints it needs, then writes code that calls those endpoints in sequence. The result is a structured, typed return value.
The API-as-Code Pattern: Why Code Mode Wins
For any large API (Cloudflare has 2,500; AWS has 10,000+; Microsoft Graph has 1,000+; Salesforce has 200+; Stripe has 100+; Notion has 50+), the Code Mode pattern is the right default.
| Approach | Tools | Context Footprint | Drift Risk | Composition |
|---|---|---|---|---|
| Flat tools (one per endpoint) | 2,500 | 50,000+ tokens | High (every API change = tool change) | Hard (no way to combine) |
| Domain-grouped tools (Stripe/Resend-style) | ~30 | 5,000 tokens | Medium | Medium (explicit param passing) |
| Code Mode (Cloudflare-style) | 2 | 1,000 tokens | Low (API evolves transparently) | Natural (TypeScript composition) |
Code Mode wins on context footprint, drift resistance, and composition. The two-tool surface never changes regardless of how the API grows. The agent's context stays bounded. The API can evolve without breaking the MCP surface.
For multi-API agent workflows (Cloudflare + Stripe + Notion), the pattern is one Code Mode MCP per API. Each is 2 tools, each composes independently, the agent writes TypeScript that calls all of them.
The Multi-Product Workflow
For agents that orchestrate across Cloudflare products:
User: "Deploy the new worker, invalidate the cache, and update the DNS record."
Agent (via Code Mode):
mcp_search(query="deploy worker script", max_results=1)
→ Returns workers.scripts.put
mcp_search(query="purge cache by tag", max_results=1)
→ Returns zones.purgeCache
mcp_search(query="update DNS A record", max_results=1)
→ Returns dns.records.update
mcp_execute(`
// Step 1: Deploy the worker
const deployed = await cloudflare.workers.scripts.put({
script_name: 'edge-api',
account_id: 'xyz789',
content: workerSourceCode,
});
// Step 2: Wait for deployment
await new Promise(r => setTimeout(r, 1000));
// Step 3: Purge cache by tag
const purged = await cloudflare.zones.purgeCache({
zone_id: 'abc123',
tags: ['edge-api'],
});
// Step 4: Update DNS A record
const dns = await cloudflare.dns.records.update({
zone_id: 'abc123',
record_id: 'rec_xyz',
type: 'A',
content: '192.0.2.42', // new worker IP
});
return { deployed, purged, dns };
`);
The agent searches for the right endpoints, composes them into a typed script, executes it. The agent has the same power as a human engineer writing curl commands + jq.
The DNS Automation Pattern
For agents managing DNS:
mcp_execute(`
const records = await cloudflare.dns.records.list({
zone_id: 'abc123',
type: 'A',
name: 'api.acme.com',
});
return records;
`);
For bulk updates:
mcp_execute(`
// Read current records
const current = await cloudflare.dns.records.list({
zone_id: 'abc123',
match: 'any',
type: 'A',
});
// Update each
const updates = await Promise.all(
current.result
.filter(r => r.content !== '192.0.2.1')
.map(r => cloudflare.dns.records.update({
zone_id: 'abc123',
record_id: r.id,
type: 'A',
name: r.name,
content: '192.0.2.1',
proxied: r.proxied,
}))
);
return updates;
`);
The agent can do bulk DNS changes correctly with hit-listing, filtering, and atomicity.
The R2 + Workers AI Pipeline
For agents building content pipelines:
mcp_execute(`
// 1. Generate embedding with Workers AI
const embedding = await cloudflare.workers_ai.run({
account_id: 'xyz',
model: '@cf/baai/bge-base-en-v1.5',
input: { text: 'Document content here' },
});
// 2. Store embedding in Vectorize
await cloudflare.vectorize.upsert({
index_name: 'docs-index',
vectors: [{
id: 'doc-123',
values: embedding.result.data[0],
metadata: { source: 'doc-123' },
}],
});
// 3. Cache original document in R2
await cloudflare.r2.objects.put({
bucket: 'docs',
key: 'doc-123',
body: 'Document content here',
});
return { embedding_stored: true, original_stored: true };
`);
The agent composes multiple Cloudflare products in one code execution. Vectorize + Workers AI + R2 in one transaction.
The Auth Pattern: Scoped API Tokens
For scoped access, Cloudflare API Tokens are the right primitive:
| Scope | Allows |
|---|---|
| Zone:DNS:Edit | Modify DNS records |
| Zone:Cache Purge:Purge | Purge cache |
| Account:Workers Scripts:Edit | Deploy Workers |
| Account:R2:Edit | Write to R2 buckets |
| Account:Workers AI:Run | Run inference |
| Account:Vectorize:Edit | Modify Vectorize indexes |
For an agent that just manages DNS and purges cache, the scopes are:
Zone:DNS:Editfor specific zonesZone:Cache Purge:Purgefor specific zones
The token is scoped to specific zones + specific operations. The agent can't touch unrelated zones or products.
For multi-account setups (one Cloudflare account per team, per product, per region), one API token per account with per-account scopes. The agent switches context per account.
For multi-tenant SaaS setups, per-tenant tokens scoped to that tenant's resources only.
Facio Integration
{
"mcpServers": {
"cloudflare": {
"url": "https://mcp.example.com/cloudflare",
"headers": {
"Authorization": "Bearer ${credentials.CLOUDFLARE_API_TOKEN}"
}
}
}
}
Or self-host via the official server:
{
"mcpServers": {
"cloudflare": {
"command": "npx",
"args": ["-y", "@cloudflare/mcp-server-cloudflare"],
"env": {
"CLOUDFLARE_API_TOKEN": "${credentials.CLOUDFLARE_API_TOKEN}"
}
}
}
}
Facio's audit trail captures every Code Mode call with the search query, the discovered endpoints, the executed code, the result, and any errors. For a regulated team (financial compliance, multi-tenant SaaS), this is the complete Cloudflare-automation record: "Agent at 14:32 UTC searched 'purge cache', executed code calling zones.purgeCache on zone abc123 with tags['edge-api'], returned 247 cache entries purged."
For HITL workflows, Code Mode's destructive surface is enormous but bounded — the agent can call any of 2,500+ endpoints, but the operator controls the API token's scope:
| Tool | Severity | Suggested Gate |
|---|---|---|
mcp_search | Read | None — autonomous |
mcp_execute (read-only endpoints) | Read | None — autonomous |
mcp_execute (write endpoints: DNS, deploys, R2 writes) | Write, contextual | Hard confirm (review the code before execution) |
mcp_execute (destructive endpoints: zone delete, account changes) | Write, destructive | Hard confirm + reason required + code review |
The mcp_execute tool deserves special attention — it's a code execution primitive. Facio should:
- Detect the endpoints called via static analysis of the code (Cloudflare's TypeScript API has typed endpoints)
- Apply severity based on the highest-severity endpoint in the code
- Apply additional rules for destructive endpoints (zone deletion, account changes require explicit confirmation)
- Show the code preview in the approval card so the human sees exactly what runs
- Apply sandboxing — the code runs in a VM/container, can't escape
For multi-zone setups (one Cloudflare zone per customer's domain), the pattern is one API token per zone with per-zone scopes. The agent switches context per zone, the audit trail is per-zone.
For multi-tenant SaaS setups, per-tenant API tokens scoped to that tenant's zone. Tenant isolation at the credential level.
Quickstart
# 1. Create a Cloudflare API Token
# https://dash.cloudflare.com/profile/api-tokens
# Scopes: select only the permissions needed
# Zone Resources: specific zones
# 2. Connect to Cloudflare's hosted MCP (easiest)
{
"mcpServers": {
"cloudflare": {
"url": "https://mcp.example.com/cloudflare",
"headers": {
"Authorization": "Bearer {CLOUDFLARE_TOKEN}"
}
}
}
}
# 3. First prompts
# "List my zones and their status"
# "Add an A record for api.acme.com pointing to 192.0.2.1"
# "Purge the cache for /products/*"
# "Deploy this Worker script"
# "What's my edge analytics for the last 24h?"
Use Cases
DNS automation: "Add an A record for staging.acme.com pointing to 192.0.2.5." DNS.records.create.
Cache management: "Purge the cache for /api/* because we just deployed." zones.purgeCache.
Worker deployment: "Deploy this Worker script and verify it works." workers.scripts.put + workers.scripts.get.
R2 file upload: "Upload this build artifact to R2." r2.objects.put.
Vectorize indexing: "Embed these documents and store in Vectorize." workers_ai.run + vectorize.upsert.
Zone analytics: "What's our Q2 traffic to acme.com?" analytics.zones.get.
SSL/TLS management: "Check the SSL mode for acme.com and switch to Full if needed." ssl.get + ssl.update.
Workers AI inference: "Run sentiment analysis on these 100 reviews." workers_ai.run with batching.
Page Rules / Redirects: "Set up a redirect from /old-path to /new-path." rules.create.
WAF rules: "Add a WAF rule to block requests without a User-Agent." waf.create.
Load balancer management: "Add a backend pool with 3 origins, weighted 1/2/3." load_balancers.pools.create.
Workers KV operations: "Read the configuration from KV." kv.get.
D1 SQL queries: "Query the D1 database: SELECT * FROM users WHERE active = 1." d1.query.
Stream upload: "Upload this video and get the playback URL." stream.create.
Image transformations: "Generate variants (thumbnail, hero) for this uploaded image." images.variants.create.
Multi-step deployment: "Deploy worker → invalidate cache → update DNS → verify." Composed Code Mode execution.
Compliance auditing: "List all zones with their SSL mode and WAF status. Export as compliance report." Multi-endpoint scan.
Cost optimization: "For each R2 bucket, show me the storage class and access frequency." Multi-bucket scan + analysis.
Backup automation: "Snapshot all R2 buckets to a backup bucket nightly." Scheduled Code Mode execution.
The Code Mode Pattern
The Cloudflare MCP server's defining innovation — expose a large API as 2 tools via code execution — is the design lesson every "broad-API-as-MCP" server should copy.
Why Code Mode wins:
- Bounded context — 2 tools, ~1,000 tokens regardless of API size
- Drift-resistant — the API evolves transparently, the tool surface never changes
- Composability — TypeScript composition vs explicit param passing
- Familiar to agents — agents write TypeScript fluently
- Sandboxed — code runs in a VM, can't escape to the host
- Auditable — the code is the audit trail
For any MCP server that wraps a large API (Cloudflare 2,500+, AWS 10,000+, Microsoft Graph 1,000+), Code Mode is the right default. The alternative — flat lists of 100+ tools — bloats the context window and confuses the agent.
The pattern applies to:
- AWS MCP — Code Mode wrapping 10,000+ endpoints
- Microsoft 365 MCP — Code Mode for the entire Graph API
- Google Cloud MCP — Code Mode wrapping ~200 services × multiple endpoints
- Salesforce MCP — Code Mode for SOQL, SOSL, sObject operations
For any service with more than ~30 endpoints, Code Mode is the right primitive.
The Scoped-Token Pattern
The Cloudflare MCP server's second defining innovation — per-zone + per-action API token scoping — is the design lesson every "platform-with-many-resources-as-MCP" server should copy.
Why scoped tokens win:
- Per-zone scope — limit to specific zones, no cross-zone access
- Per-action scope — granular permissions, not coarse "Zone:Edit"
- Time-bounded — keys expire automatically
- Cancellable — revoked instantly
- IP-restricted — optional source-IP allowlist
For any agent that touches multi-tenant resources (Cloudflare zones, AWS accounts, Stripe customers, GitHub repos), scoped tokens are the right default. Full-credential alternatives are too powerful; OAuth tokens are too coarse; per-resource SSH keys are operationally heavy.
Bottom Line
The Cloudflare MCP Servers are the edge-infrastructure default for AI agents in 2026. 2 tools in the Code Mode profile (mcp_search, mcp_execute), 13+ specialized product servers, access to all 2,500+ Cloudflare API endpoints, MIT-licensed, official Cloudflare-maintained.
For any agent that participates in edge workflows — DNS automation, cache management, Worker deployment, R2 storage, Workers AI inference, vector indexing, analytics — this is the bridge. The agent searches the API surface, writes TypeScript code that calls the endpoints, executes in a sandbox, gets typed results.
For the broader MCP ecosystem, the Cloudflare pattern is the design lesson every "broad-API-as-MCP" server should copy. Code Mode + scoped tokens + sandboxed execution. When the API primitive is right, the agent's infrastructure automation is right.
npx -y @cloudflare/mcp-server-cloudflare with CLOUDFLARE_API_TOKEN=... (scoped to specific zones + actions) — or use the hosted remote MCP — and your agent has the entire Cloudflare platform.
MCP Spotlight is a series covering servers that give AI agents real capabilities. Every server is evaluated for design clarity, ecosystem impact, and integration fit with Facio's HITL-first agent runtime.