mcpField
C
cloudflare-api

cloudflare-api

github.com/jezweb云与 DevOps1.1k992 次安装3 周前更新
代码仓库

关于 cloudflare-api

cloudflare-api 是在 wrangler 或 MCP 工具不适用时调用 Cloudflare REST API 的技能,侧重脚本化的批量与多区域操作。涵盖 DNS、区域设置、防火墙规则、分析数据及 Cloudflare 开发平台资源。

主要功能

  1. 01直接调用 Cloudflare REST API
  2. 02批量处理 DNS 和重定向
  3. 03跨多个区域应用设置
  4. 04管理防火墙、缓存和 Worker 路由
  5. 05通过 GraphQL 查询分析数据
  6. 06按安全规范生成脚本

适用场景

  1. 01迁移或更新大量 DNS 记录
  2. 02为多个区域应用统一设置
  3. 03批量创建重定向规则
  4. 04审计账户资源或查询分析数据

MCP 相关

当 MCP 服务不适合批量或脚本化操作时,该技能改用 Cloudflare API 直接请求;文档也将 MCP 列为单项操作的选择之一。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jezweb/claude-skills --skill cloudflare-api

安装后在 Claude Code 中输入/cloudflare-api确认已加载。

附带文件references/developer-platform-api.md

详细介绍

Cloudflare API

当 wrangler CLI 或 MCP 服务不适用时,直接调用 Cloudflare REST API。适用于批量操作、全域更改,以及 wrangler 未提供的功能。

何时选择此方式,而不是 Wrangler 或 MCP

用例WranglerMCP此工具
部署 Worker是是否
创建 D1 数据库是是否
批量更新 50 条 DNS 记录慢(一次一条)慢(每次工具调用一条)是 — 批处理脚本
为白标服务创建自定义主机名否部分支持是
电子邮件路由规则否部分支持是
WAF/防火墙规则否是,但操作繁琐是 — 直接调用 API
批量重定向规则否一次一条是 — 批处理脚本
在 20 个区域中配置区域设置否分 20 次调用是 — 全域脚本
按标签/前缀清除缓存否是是(编写脚本时)
Worker 路由管理有限是是(批量操作时)
分析/日志查询否部分支持是 — GraphQL
跨数据库查询/导出 D1一次一个数据库一次一个数据库是 — 跨数据库脚本
R2 批量对象操作否一次一个是 — S3 API + 批处理
KV 批量读取/写入/删除一次一个一次一个是 — 批量端点
Vectorize 查询/删除否只能通过 Worker是 — 直接调用 API
注入队列消息否只能通过 Worker是 — 直接调用 API
审计账户中的所有资源否繁琐是 — 资源清单脚本

经验法则:单次操作 → MCP 或 wrangler。批量/全域/脚本化操作 → 直接调用 API。

身份验证设置

API Token(推荐)

在以下位置创建具有限定范围的令牌:Dashboard → My Profile → API Tokens → Create Token

# Store it
export CLOUDFLARE_API_TOKEN="your-token-here"

# Test it
curl -s "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq '.success'

令牌权限范围:始终只授予最低限度的权限。常用预设:

  • “编辑区域 DNS” — 用于 DNS 操作
  • “编辑区域设置” — 用于更改区域配置
  • “编辑 Cloudflare Workers” — 用于 Worker 路由管理
  • “读取分析数据” — 用于 GraphQL 分析
账户和区域 ID
# List your zones (find zone IDs)
curl -s "https://api.cloudflare.com/client/v4/zones?per_page=50" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq '.result[] | {name, id}'

# Get zone ID by domain name
ZONE_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones?name=example.com" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq -r '.result[0].id')

将 ID 存储在环境变量或配置文件中,不要在脚本中硬编码。

工作流

批量 DNS 操作

一次添加或更新多条记录(例如迁移域名、为新客户端进行设置):

# Pattern: read records from a file, create in batch
while IFS=',' read -r type name content proxied; do
  curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"type\":\"$type\",\"name\":\"$name\",\"content\":\"$content\",\"proxied\":$proxied,\"ttl\":1}" \
    | jq '{name: .result.name, id: .result.id, success: .success}'
  sleep 0.25  # Rate limit: 1200 req/5min
done < dns-records.csv

导出某个区域的所有记录(用于备份或迁移):

curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?per_page=100" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  | jq -r '.result[] | [.type, .name, .content, .proxied] | @csv' > dns-export.csv

查找并替换记录中的内容(例如迁移 IP):

OLD_IP="203.0.113.1"
NEW_IP="198.51.100.1"

# Find records pointing to old IP
RECORDS=$(curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?content=$OLD_IP" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq -r '.result[].id')

# Update each one
for RECORD_ID in $RECORDS; do
  curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"content\":\"$NEW_IP\"}" | jq '.success'
done
自定义主机名(白标客户端域名)

适用于客户端使用自有域名的 SaaS 应用(例如 app.clientdomain.com → 你的 Worker):

# Create custom hostname
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "hostname": "app.clientdomain.com",
    "ssl": {
      "method": "http",
      "type": "dv",
      "settings": {
        "min_tls_version": "1.2"
      }
    }
  }' | jq '{id: .result.id, status: .result.status, ssl_status: .result.ssl.status}'

# List custom hostnames
curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames?per_page=50" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  | jq '.result[] | {hostname, status, ssl_status: .ssl.status}'

# Check status (client needs to add CNAME)
curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/$HOSTNAME_ID" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq '.result.status'

客户端设置:他们添加一条 CNAME:app.clientdomain.com → your-worker.your-domain.com

电子邮件路由规则
# Enable email routing on zone
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/enable" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

# Create a routing rule (forward info@ to a real address)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/rules" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Forward info@",
    "enabled": true,
    "matchers": [{"type": "literal", "field": "to", "value": "[email protected]"}],
    "actions": [{"type": "forward", "value": ["[email protected]"]}]
  }' | jq '.success'

# Create catch-all rule
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/rules" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Catch-all",
    "enabled": true,
    "matchers": [{"type": "all"}],
    "actions": [{"type": "forward", "value": ["[email protected]"]}]
  }' | jq '.success'

# List rules
curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/email/routing/rules" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq '.result[] | {name, enabled, matchers, actions}'
清除缓存
# Purge everything (nuclear option)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"purge_everything": true}'

# Purge specific URLs
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"files": ["https://example.com/styles.css", "https://example.com/app.js"]}'

# Purge by cache tag (requires Enterprise or cache tag headers)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tags": ["product-123", "homepage"]}'

# Purge by prefix
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"prefixes": ["https://example.com/images/"]}'
重定向规则(批量)
# Create a redirect rule
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_request_dynamic_redirect/entrypoint" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {
        "expression": "(http.request.uri.path eq \"/old-page\")",
        "description": "Redirect old-page to new-page",
        "action": "redirect",
        "action_parameters": {
          "from_value": {
            "target_url": {"value": "https://example.com/new-page"},
            "status_code": 301
          }
        }
      }
    ]
  }'

批量重定向(来自 CSV 的 301 重定向),可通过编程方式生成规则数组:

import json, csv

rules = []
with open('redirects.csv') as f:
    for row in csv.reader(f):
        old_path, new_url = row
        rules.append({
            "expression": f'(http.request.uri.path eq "{old_path}")',
            "description": f"Redirect {old_path}",
            "action": "redirect",
            "action_parameters": {
                "from_value": {
                    "target_url": {"value": new_url},
                    "status_code": 301
                }
            }
        })
print(json.dumps({"rules": rules}, indent=2))
区域设置(全域)

在多个区域中应用相同的设置:

# Settings to apply
SETTINGS='{"value":"full"}'  # SSL mode: full (strict)

# Get all active zones
ZONES=$(curl -s "https://api.cloudflare.com/client/v4/zones?status=active&per_page=50" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq -r '.result[].id')

# Apply to each zone
for ZONE in $ZONES; do
  curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE/settings/ssl" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d "$SETTINGS" | jq "{zone: .result.id, success: .success}"
  sleep 0.25
done

常见的全域设置:

  • ssl — “full” 或 “strict”
  • min_tls_version — “1.2”
  • always_use_https — “on”
  • security_level — “medium”
  • browser_cache_ttl — 14400
WAF/防火墙规则
# Create a WAF custom rule (block by country)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_request_firewall_custom/entrypoint" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [{
      "expression": "(ip.geoip.country in {\"RU\" \"CN\"})",
      "action": "block",
      "description": "Block traffic from RU and CN"
    }]
  }'

# Rate limiting rule
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_ratelimit/entrypoint" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [{
      "expression": "(http.request.uri.path contains \"/api/\")",
      "action": "block",
      "ratelimit": {
        "characteristics": ["ip.src"],
        "period": 60,
        "requests_per_period": 100
      },
      "description": "Rate limit API to 100 req/min per IP"
    }]
  }'
Worker 路由
# List routes
curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq '.result[] | {pattern, id}'

# Create route
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pattern": "api.example.com/*", "script": "my-worker"}'

# Delete route
curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
分析(GraphQL)
# Worker analytics (requests, errors, CPU time)
curl -s -X POST "https://api.cloudflare.com/client/v4/graphql" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ viewer { zones(filter: {zoneTag: \"'$ZONE_ID'\"}) { httpRequests1dGroups(limit: 7, filter: {date_gt: \"2026-03-10\"}) { dimensions { date } sum { requests pageViews } } } } }"
  }' | jq '.data.viewer.zones[0].httpRequests1dGroups'

速率限制

端点限制
大多数 API 调用每 5 分钟 1200 个请求
DNS 记录操作每 5 分钟 1200 次(与上述限制共用)
清除缓存每天 1000 次清除调用
创建区域每分钟 5 个

编写脚本时:持续操作期间,每次调用间添加 sleep 0.25。使用 p-limit 或 xargs -P 4 控制并行度。

脚本生成

当用户描述需求时,在 .jez/scripts/ 中生成脚本,该脚本:

  • 从环境变量读取 API 令牌(绝不硬编码)
  • 为列表操作处理分页
  • 包含错误检查(每次调用后执行 jq '.success')
  • 在调用之间添加限速等待
  • 记录执行内容
  • 尽可能支持 --dry-run

简单操作优先使用 curl + jq。复杂逻辑(分页循环、错误处理、CSV 处理)使用 Python。大型脚本使用 TypeScript 和 cloudflare npm 包,以确保类型安全。

API 参考

基础 URL:https://api.cloudflare.com/client/v4/

完整文档:https://developers.cloudflare.com/api/

API 遵循一致的模式:

  • GET /zones — 列出
  • POST /zones — 创建
  • GET /zones/:id — 读取
  • PATCH /zones/:id — 更新
  • DELETE /zones/:id — 删除
  • PUT /zones/:id/settings/:name — 更新设置

每个响应都包含 { success: bool, errors: [], messages: [], result: {} }。

参考文件

何时阅读
D1、R2、KV、Workers、Vectorize、Queues API 模式references/developer-platform-api.md

评论

支持 Markdown