Explore
Topics
Collections
Documents
FAQ
GitHub
Explore repos
Explore
Topics
Collections
Documents
FAQ
GitHub
Explore repos
Explore
/
TypeScript
/
mcp
cloudflare
cloudflare/mcp
MCP server for the Cloudflare API
View on GitHub
Website / Demo
Copy link
Back to listing
1k
stars
156
forks
14
contributors
TypeScript
README.md
View on GitHub
# Cloudflare MCP Server > A token-efficient MCP server for the entire Cloudflare API. 2500 endpoints in 1k tokens, powered by [Code Mode](https://blog.cloudflare.com/code-mode-mcp/). ## Token Comparison | Approach | Tools | Token cost | Context used (200K) | | ------------------------------------------- | ----- | ---------- | ------------------- | | Raw OpenAPI spec in prompt | — | ~2,000,000 | 977% | | Native MCP (full schemas) | 2,594 | 1,170,523 | 585% | | Native MCP (minimal — required params only) | 2,594 | 244,047 | 122% | | Code mode | 3 | ~1,100 | 0.5% | ## Get Started MCP URL: `https://mcp.cloudflare.com/mcp` ### Option 1: OAuth (Recommended) Just connect to the MCP server URL - you'll be redirected to Cloudflare to authorize and select permissions. #### Example JSON Configuration ```json { "mcpServers": { "cloudflare-api": { "type": "http", "url": "https://mcp.cloudflare.com/mcp" } } } ``` ### Option 2: API Token For CI/CD, automation, or if you prefer managing tokens yourself. Create a [Cloudflare API token](https://dash.cloudflare.com/profile/api-tokens) with the permissions you need. Both **user tokens** and **account tokens** are supported. For account tokens, include the **Account Resources : Read** permission so the server can auto-detect your account ID. > **Note:** API tokens with **Client IP Address Filtering** enabled are not currently supported. ### Add to Agent | Setting | Value | | ------------ | --------------------------------------------------------------------------- | | MCP URL | `https://mcp.cloudflare.com/mcp` | | Bearer Token | Your [Cloudflare API Token](https://dash.cloudflare.com/profile/api-tokens) | ### Disable Code Mode If your MCP client already uses code mode, or you're composing this server with another server that uses code mode, you can disable it with the `?codemode=false` query parameter. This registers an individual tool for each of the ~2,500 Cloudflare API endpoints instead of the code mode API tools. The `docs` and `whoami` tools remain available in both modes. ``` https://mcp.cloudflare.com/mcp?codemode=false ``` #### Example JSON Configuration ```json { "mcpServers": { "cloudflare-api": { "type": "http", "url": "https://mcp.cloudflare.com/mcp?codemode=false" } } } ``` When code mode is disabled: - Each API endpoint is registered as its own tool (e.g., `get_workers_scripts`, `post_d1_database`) - Tool input schemas are derived from the endpoint's path parameters, query parameters, and request body - Tools make direct API calls — no code execution involved - Path parameters like `account_id` are auto-resolved when possible (single account) > **Note:** Disabling code mode significantly increases the token cost (~244k tokens vs ~1k tokens). Only disable it when necessary for composition with other code mode systems. ### Tool Result Truncation In code mode, the server caps each `search` and `execute` result at ~6,000 tokens, to avoid context overload. Oversized JSON stays valid JSON: long lists keep their first items whole, long strings are clipped, and every cut is marked with `--- TRUNCATED ---`. An agent that writes a result straight to a file or pipe, rather than reading it into the conversation, can pass `truncate: false` to that call to get the whole result. > **Note:** Without the cap, a broad query can return megabytes. Only turn it off when the result doesn't go to the model. With code mode disabled, endpoint tools return whole results. The clients that disable it usually run code mode themselves: they call the endpoint tools from their own code and parse each result, so a capped result would lose data. ### Missing Permissions When Cloudflare refuses a call because the OAuth connection lacks a scope, the server asks the client to re-authorize with that scope added to the ones it already has. Claude and other clients that follow the [MCP authorization spec](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization#scope-challenge-handling) get a `403 insufficient_scope` challenge. Codex and ChatGPT get it in the tool result, which is where they look for it. Either way, the tool error says which scope is missing. Some endpoints, such as `GET /zones`, don't refuse: they answer with an empty list when the scope is missing. An empty list from a read the connection holds no accepted scope for is refused the same way, so it isn't mistaken for an empty account. ## The Problem The Cloudflare OpenAPI spec is **2 million tokens**. Even with native MCP tools using minimal schemas, it's still **~244k tokens**. Traditional MCP servers that expose every endpoint as a tool leak this entire context to the main agent. This server solves the problem by using **code execution** in a [Code Mode](https://blog.cloudflare.com/code-mode-mcp/) pattern - the spec lives on the server, and only the result of the code execution is returned to the agent. ## Tools Agent writes code to search the spec and execute API calls. It can also search Cloudflare's developer documentation directly. | Tool | Description | | --------- | ----------------------------------------------------------------------------- | | `docs` | Search Cloudflare developer documentation | | `search` | Write JavaScript to query `spec.paths` and find endpoints | | `execute` | Write JavaScript to call `cloudflare.request()` with the discovered endpoints | | `whoami` | Return the Cloudflare user or account this connection is authenticated as | ``` Agent MCP Server │ │ ├──search({code: "..."})───────►│ Execute code against spec.json │◄──[matching endpoints]────────│ │ │ ├──execute({code: "..."})──────►│ Execute code against Cloudflare API │◄──[API response]──────────────│ ``` `whoami` takes no arguments and returns `{ id, email }` for a user credential or `{ id, name }` for an account token. The `id` is `user:<user id>` or `account:<account id>`, so it stays the same across token refresh, reconnection and permission changes. Clients can use it to tell connected accounts apart; it is marked as an [OpenAI profile tool](https://developers.openai.com/plugins/build/auth#implement-and-declare-your-profile-tool). ## Skills The server also serves the [Cloudflare skills](https://github.com/cloudflare/skills) (Wrangler, Durable Objects, Agents SDK, Workers best practices and more) through the MCP [Skills extension](https://modelcontextprotocol.io/extensions/skills/overview). Clients that support it discover them with `skills/list` and read each file at `skill://<name>/<path>`. The catalog is synced from GitHub every six hours. ## Supported Products Workers, KV, R2, D1, Pages, DNS, Firewall, Load Balancers, Stream, Images, AI Gateway, Vectorize, Access, Gateway, and more. The server ships the OpenAPI document from a pinned [Forge](https://github.com/cloudflare/forge) release (`openapi.forge.json`), updated by pull request. ## Usage Once configured, just ask your agent to do things with Cloudflare: - "List all my Workers" - "Create a KV namespace called 'my-cache'" - "Add an A record for api.example.com pointing to 192.0.2.1" The agent will search for the right endpoints and execute the API calls. Here's what happens behind the scenes: ```javascript // 1. Search for endpoints search({ code: `async () => { const results = []; for (const [path, methods] of Object.entries(spec.paths)) { for (const [method, op] of Object.entries(methods)) { if (op.tags?.some(t => t.toLowerCase() === 'workers')) { results.push({ method: method.toUpperCase(), path, summary: op.summary }); } } } return results; }`, }); // 2. Execute API call (user token - account_id required) execute({ code: `async () => { const response = await cloudflare.request({ method: "GET", path: \`/accounts/\${accountId}/workers/scripts\` }); return response.result; }`, account_id: "your-account-id", }); // 2. Execute API call (account token - account_id auto-detected) execute({ code: `async () => { const response = await cloudflare.request({ method: "GET", path: \`/accounts/\${accountId}/workers/scripts\` }); return response.result; }`, }); ``` ### GraphQL Analytics API The server automatically detects and handles Cloudflare's GraphQL Analytics API endpoints. GraphQL queries work seamlessly through the same `execute` tool: ```javascript execute({ code: `async () => { const response = await cloudflare.request({ method: "POST", path: "/client/v4/graphql", body: { query: \`query { viewer { zones(filter: { zoneTag: "your-zone-id" }) { httpRequests1dGroups(limit: 7, orderBy: [date_ASC]) { dimensions { date } sum { requests bytes cachedBytes } } } } }\`, variables: {} } }); return response.result; }`, account_id: "your-account-id", }); ``` ## Build a Code Mode MCP Server Code execution uses Cloudflare's [Dynamic Worker Loader API](https://developers.cloudflare.com/workers/runtime-apis/bindings/worker-loader/) to run generated code in isolated Workers, following the [Code Mode pattern](https://github.com/cloudflare/agents/tree/main/packages/codemode). Read the [Code Mode SDK docs](https://developers.cloudflare.com/agents/api-reference/codemode/) for more info. ### Resources - [Code Mode blog post](https://blog.cloudflare.com/code-mode/) - [Build your own remote MCP server](https://developers.cloudflare.com/agents/guides/remote-mcp-server/) - [Cloudflare's own MCP Servers](https://github.com/cloudflare/mcp-server-cloudflare)
Live Chat