Provides tools for managing Cloudflare DNS zones and records, including listing zones, performing CRUD and bulk operations on records, and exporting zone data as BIND files.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cloudflare-dns-mcp-serverCreate a proxied A record for app.example.com pointing to 203.0.113.10"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
cloudflare-dns-mcp-server
A best-of-breed MCP server for Cloudflare DNS management. Designed for extreme token efficiency, full CRUD coverage, and easy deployment as both a local MCP server and a Cloudflare Worker.
Features
10 DNS tools covering zones, records, bulk operations, and BIND export
Token-efficient by default — concise output strips 60-80% of Cloudflare API bloat
Summary mode — get record counts + type distribution without fetching individual records
Random sampling — audit large zones without loading everything
Safety gates — deletes require explicit
confirm: trueDual transport — stdio for Claude Desktop, Streamable HTTP for remote access
Worker-ready — deploy to Cloudflare Workers with
npm run deploy
Quick Start
1. Create a Cloudflare API Token
Go to Cloudflare API Tokens and create a token with:
Zone → Zone → Read
Zone → DNS → Edit
Scope: All zones (or specific zones you want to manage)
2. Install
git clone https://github.com/piersdd/cloudflare-platform-mcp.git
cd cloudflare-platform-mcp
npm install
npm run build3. Configure Claude Desktop
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"cloudflare-dns": {
"command": "node",
"args": ["/path/to/cloudflare-platform-mcp/dist/index.js"],
"env": {
"CLOUDFLARE_API_TOKEN": "your-api-token-here"
}
}
}
}Restart Claude Desktop. The server validates your token on startup.
Tools
Read Tools
Tool | Description |
| List zones with optional name/status/account filters |
| Get zone by ID or domain name |
| List records with filters, pagination, summary mode, random sampling |
| Get a single record by ID |
| Export zone as BIND zonefile |
Write Tools
Tool | Description |
| Create any DNS record type (A, AAAA, CNAME, MX, TXT, SRV, CAA, etc.) |
| Partial update (PATCH) — only changed fields |
| Delete with mandatory |
| Create up to 100 records in one call |
| Update up to 100 records in one call |
Token Efficiency
Every tool defaults to concise output. Here's what that means:
Concise (default) — only the fields an LLM needs:
{ "id": "abc123", "type": "A", "name": "www.example.com", "content": "203.0.113.10", "proxied": true, "ttl": "auto" }Full Cloudflare response (with include_details=true) — includes zone_id, zone_name, meta, settings, proxiable, locked, etc. ~5x more tokens.
Efficiency Modes for cf_dns_list_records
Mode | Tokens | Use Case |
| ~50 | "How many records? What types?" |
| ~200 | "Show me a few records to check" |
Filtered + concise | ~500 | "Show me all CNAME records" |
Full details | ~2500 | "I need all metadata for debugging" |
Example Prompts
"List all my Cloudflare zones"
"Show me the DNS records for example.com"
"How many DNS records does example.com have, broken down by type?"
"Create an A record for app.example.com pointing to 203.0.113.10 with proxy enabled"
"Set up email DNS for example.com with Google Workspace MX records"
"Switch the A record for api.example.com from 10.0.0.1 to 10.0.0.2"
"Delete the old staging CNAME record"
"Export all DNS records for example.com as a BIND file"
"Audit example.com for unproxied A records that might expose our origin IP"HTTP Transport (Remote Access)
Run as an HTTP server instead of stdio:
TRANSPORT=http CLOUDFLARE_API_TOKEN=your-token node dist/index.jsThe server starts on port 8787 (configurable via PORT env var). An API key is auto-generated and printed to stderr on first run. Set CLOUDFLARE_DNS_MCP_API_KEY to persist it.
Endpoints:
POST /mcp— MCP Streamable HTTP (requiresX-API-Keyheader)GET /health— Health check
Remote MCP Client Config
{
"mcpServers": {
"cloudflare-dns": {
"url": "http://localhost:8787/mcp",
"headers": {
"X-API-Key": "your-mcp-api-key"
}
}
}
}Deploy as a Cloudflare Worker
The same codebase deploys to Cloudflare Workers for always-on remote access:
# Set secrets
npx wrangler secret put CLOUDFLARE_API_TOKEN
npx wrangler secret put CLOUDFLARE_DNS_MCP_API_KEY
# Deploy
npm run deployYour MCP server is now at https://cloudflare-dns-mcp.your-subdomain.workers.dev/mcp.
Public Exposure with Custom Domain
For production use behind a custom domain:
Add a custom domain in the Cloudflare dashboard for your Worker
TLS is automatic via Cloudflare's edge certificates
Optionally put it behind Cloudflare Access for SSO authentication
Bearer Token Authentication
When exposing the server through a tunnel or reverse proxy, set MCP_API_TOKEN to require a bearer token on every request:
export MCP_API_TOKEN=your-secret-token-hereAll HTTP requests must then include the header:
Authorization: Bearer your-secret-token-hereRequests without a valid token receive 401 Unauthorized. If the env var is unset or empty, bearer auth is disabled and the server falls back to the existing X-API-Key mechanism (suitable for localhost-only access).
Via Cloudflare Tunnel
For exposing a local instance:
cloudflared tunnel --url http://localhost:8787Environment Variables
Variable | Required | Default | Description |
| Yes | — | Cloudflare API token with Zone:Read + DNS:Edit |
| No |
|
|
| No |
| HTTP server port (http transport only) |
| No | (none) | Bearer token for HTTP auth — if set, requires |
| No | auto-generated | API key for HTTP transport authentication (X-API-Key header) |
Development
npm run dev # stdio mode with auto-reload
npm run dev:http # HTTP mode with auto-reload
npm run build # Compile TypeScript
npm run typecheck # Type-check without emitting
npm run deploy # Build + deploy to WorkersLicense
MIT