cloudflare-mcp
Cloudflare MCP server with multi-user credential management, full Cloudflare API coverage, and schema discovery tools for safe LLM-driven Cloudflare resource management.
README
cloudflare-mcp
Cloudflare MCP server built from a reusable MCP architecture with:
- Vault-backed persistent multi-user Cloudflare credentials
- Postgres-backed persistent per-user configuration
- MCP admin key protection for mutating tools
- Dedicated Cloudflare tools plus full API coverage through a generic request tool
- Query suggestion and schema discovery tools for safer LLM workflows
This solution uses Vault-backed multi-user Cloudflare credentials and Postgres-backed per-user configuration as first-class persistence layers.
Solution Guarantees
- All user credentials are multi-user and scoped by user ID in Vault.
- All secrets are persisted in Vault.
- All non-secret configuration is persisted in Postgres.
- Mutating tools support admin-gate enforcement via
MCP_ADMIN_AUTH_KEY. - API coverage is full through
cloudflare_api_request(method + path + query + body) against Cloudflare API v4.
Architecture
Runtime flow:
src/index.js(stdio) orsrc/http/index.js(HTTP) loads env, Postgres, Vault.src/config/env.jsvalidates Cloudflare, Vault, Postgres, and transport config.src/services/configStore.jspersists user config in Postgres table<app>_config.src/services/vault.jspersists user secrets and HTTP auth token indexes in Vault KV.src/services/targetService.jsis the Cloudflare client with Vault token resolution and API calls.src/mcp/server.jsregisters Cloudflare MCP tools and wraps auth/error handling.src/http/server.jsexposes MCP over HTTP with auth, rate limit, allowlists, and access logs.
Data Model
Vault per-user Cloudflare token path:
<APP_NAME>/users/<normalized-user-id>/cloudflare/tokens
Vault token payload shape:
{
"userId": "team-a",
"activeTokenId": "primary",
"tokens": {
"primary": {
"tokenId": "primary",
"tokenType": "api_token",
"apiToken": "<secret>",
"active": true,
"notes": "prod",
"createdAt": "2026-07-29T00:00:00.000Z",
"updatedAt": "2026-07-29T00:00:00.000Z"
}
}
}
Postgres config scope:
- Table:
<APP_NAME>_config - PK:
(user_id, key) - Common keys:
cloudflare.default.accountIdcloudflare.default.zoneIdcloudflare.default.tokenId
Environment
Copy .env.example to .env and set values.
Required runtime groups:
- Postgres:
POSTGRES_HOST,POSTGRES_PORT,POSTGRES_DB,POSTGRES_USER,POSTGRES_PASSWORD - Vault:
VAULT_ADDR,VAULT_TOKEN,VAULT_KV_MOUNT(+ optional agent config) - Cloudflare:
CLOUDFLARE_API_BASE_URL,CLOUDFLARE_API_TIMEOUT_MS,CLOUDFLARE_API_DOCS_INDEX_URL - MCP auth gate:
MCP_ADMIN_AUTH_KEY(optional but recommended)
Run
Install and run stdio:
npm ci
npm run start:stdio
Run HTTP transport:
npm run start:http
Run both:
npm run start:both
Run tests:
npm test
Docker
Local full stack (app + Postgres + Vault):
docker compose up -d
External Services Mode (app only, external Vault/Postgres):
docker compose -f docker-compose.external.yml up -d
Tool Catalog
Common response envelope (success):
{
"ok": true,
"status": 200,
"data": {}
}
Common error envelope (isError=true):
{
"ok": false,
"status": 401,
"error": "Unauthorized: invalid authorizationKey for mutating operation"
}
cloudflare_connection_info
- Use when: you need runtime metadata and auth/scope state.
- Do not use when: you need actual Cloudflare resource data.
- Classification: read-only, low risk.
- Required permissions: none.
- Environment behavior: returns current app/user scope defaults and service connection info.
- Parameters: none.
- Response shape:
{ server, service }. - Common failures: unexpected runtime metadata serialization errors.
- Prerequisite tools: none.
- Follow-up tools:
cloudflare_scope_info,cloudflare_verify_token. - Example:
{"name":"cloudflare_connection_info","arguments":{}}
cloudflare_scope_info
- Use when: you need exact Vault/Postgres scope details for a user.
- Do not use when: you only need API data.
- Classification: read-only, low risk.
- Required permissions: none.
- Environment behavior: defaults
userIdtoMCP_CONFIG_DEFAULT_USER_ID. - Parameters:
userId?: string
- Response shape:
{ appName, userId, postgres, vault }. - Common failures: normalization/path construction errors.
- Prerequisite tools:
cloudflare_connection_info. - Follow-up tools: token/config tools.
- Example:
{"name":"cloudflare_scope_info","arguments":{"userId":"team-a"}}
cloudflare_schema_discovery
- Use when: you need API operation discovery and docs links.
- Do not use when: path/method are already known.
- Classification: read-only, low risk.
- Required permissions: outbound network to docs URL.
- Environment behavior: loads from
CLOUDFLARE_API_DOCS_INDEX_URL, with caching. - Parameters:
categoryFilter?: stringactionFilter?: stringlimit?: integer(1..1000)forceRefresh?: boolean
- Response shape:
{ totalOperations, filteredOperations, operations[] }. - Common failures: docs fetch unavailable; markdown structure changes.
- Prerequisite tools:
cloudflare_connection_info. - Follow-up tools:
cloudflare_query_suggestion,cloudflare_api_request. - Safety warnings: discovery only, no mutations.
- Example:
{"name":"cloudflare_schema_discovery","arguments":{"categoryFilter":"Zones","limit":25}}
cloudflare_query_suggestion
- Use when: you want tool sequencing and safer invocation hints.
- Do not use when: you are already executing a known workflow.
- Classification: advisory/read-only, low risk.
- Required permissions: none.
- Environment behavior: infers mutating behavior from method/operation type and reports admin-key requirement.
- Parameters:
intent?: stringoperationType?: discover|read|mutate|token|config|dnsmethod?: stringpath?: stringincludeExamples?: booleanincludeToolSchemas?: boolean
- Response shape:
{ summary, recommendedOrder, safetyChecks, toolSchemas?, examples? }. - Common failures: recommendation logic failures.
- Prerequisite tools: none.
- Follow-up tools: whichever sequence is returned.
- Example:
{"name":"cloudflare_query_suggestion","arguments":{"intent":"rotate token and patch dns","operationType":"mutate"}}
cloudflare_token_list
- Use when: you need token metadata for a user.
- Do not use when: you need to create/rotate credentials.
- Classification: read-only, medium risk (metadata exposure).
- Required permissions: none.
- Environment behavior: reads user-scoped Vault path.
- Parameters:
userId?: string
- Response shape:
{ userId, activeTokenId, tokens[] }(secret values redacted). - Common failures: Vault read errors.
- Prerequisite tools:
cloudflare_scope_info. - Follow-up tools:
cloudflare_token_set_active,cloudflare_verify_token. - Example:
{"name":"cloudflare_token_list","arguments":{"userId":"default"}}
cloudflare_token_upsert
- Use when: you need to create or rotate Cloudflare credentials for a user.
- Do not use when: you only need metadata read.
- Classification: mutating, high risk.
- Required permissions/prerequisites:
- If
MCP_ADMIN_AUTH_KEYis set,authorizationKeymust match. tokenType=api_token: requiresapiToken.tokenType=global_api_key: requiresapiKeyandemail.
- If
- Environment behavior: writes to user-scoped Vault path; optional active-token switch.
- Parameters:
userId?: stringtokenId?: string(defaults toprimary)tokenType?: api_token|global_api_keyapiToken?: stringapiKey?: stringemail?: stringsetActive?: boolean(defaulttrue)notes?: stringauthorizationKey?: string
- Response shape:
{ userId, activeTokenId, token(metadata) }. - Common failures: admin auth mismatch, missing required token fields, Vault write failures.
- Prerequisite tools:
cloudflare_scope_info. - Follow-up tools:
cloudflare_token_list,cloudflare_verify_token. - Safety warnings: changes live credentials for API execution.
- Example:
{
"name":"cloudflare_token_upsert",
"arguments":{
"userId":"team-a",
"tokenId":"primary",
"tokenType":"api_token",
"apiToken":"<token>",
"setActive":true,
"authorizationKey":"<admin-key-if-required>"
}
}
cloudflare_token_set_active
- Use when: multiple tokens exist and you need to switch active token.
- Do not use when: token is missing; create it first.
- Classification: mutating, high risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringtokenId: stringauthorizationKey?: string
- Response shape:
{ userId, activeTokenId }. - Common failures: token not found, Vault write failure, auth mismatch.
cloudflare_token_delete
- Use when: decommissioning a user token.
- Do not use when: uncertain if token is in active use.
- Classification: mutating, high risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringtokenId: stringauthorizationKey?: string
- Response shape:
{ deleted, userId, tokenId, activeTokenId? }. - Common failures: Vault write failure; auth mismatch.
- Safety warnings: irreversible token removal.
cloudflare_config_list
- Use when: you need all or prefixed config rows in Postgres.
- Do not use when: you need one key only.
- Classification: read-only, low risk.
- Required permissions: none.
- Parameters:
userId?: stringprefix?: string
- Response shape:
{ userId, configs[] }.
cloudflare_config_get
- Use when: you need one config value.
- Do not use when: you need bulk config listing.
- Classification: read-only, low risk.
- Required permissions: none.
- Parameters:
userId?: stringkey: string
- Response shape:
row|null.
cloudflare_config_set
- Use when: setting default account/zone/token or custom config.
- Do not use when: no persisted config change is needed.
- Classification: mutating, medium risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringkey: stringvalue: any JSONauthorizationKey?: string
- Response shape: upserted row.
cloudflare_config_delete
- Use when: removing obsolete config keys.
- Do not use when: key may still be required for production defaults.
- Classification: mutating, medium risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringkey: stringauthorizationKey?: string
- Response shape:
{ deleted: boolean }.
cloudflare_verify_token
- Use when: validate selected credential health before operations.
- Do not use when: token validity is already confirmed in current workflow.
- Classification: read-only, low risk.
- Required permissions: valid Cloudflare token in Vault for selected scope.
- Parameters:
userId?: stringtokenId?: string
- Response shape: proxied
/user/tokens/verifypayload. - Common failures: missing/invalid token, Cloudflare auth errors.
cloudflare_list_accounts
- Use when: discover accessible accounts.
- Do not use when: account ID already known and not needed.
- Classification: read-only, low risk.
- Parameters:
userId?: stringtokenId?: stringpage?: integerperPage?: integer
cloudflare_list_zones
- Use when: discover zones, optionally per account/name.
- Do not use when: exact zone ID already known and no listing required.
- Classification: read-only, low risk.
- Parameters:
userId?: stringtokenId?: stringaccountId?: stringname?: stringpage?: integerperPage?: integer
cloudflare_list_dns_records
- Use when: review DNS records before mutating operations.
- Do not use when: only direct create/update/delete is needed and target IDs are verified.
- Classification: read-only, medium risk.
- Parameters:
userId?: stringtokenId?: stringzoneId?: string(falls back tocloudflare.default.zoneId)type?: stringname?: stringpage?: integerperPage?: integer
cloudflare_create_dns_record
- Use when: adding a DNS record.
- Do not use when: uncertain about current zone state; list first.
- Classification: mutating, high risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringtokenId?: stringzoneId?: stringrecord: object(Cloudflare DNS record create payload)authorizationKey?: string
- Safety warnings: writes production DNS.
cloudflare_update_dns_record
- Use when: patching/replacing an existing record.
- Do not use when: record ID is not validated.
- Classification: mutating, high risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringtokenId?: stringzoneId?: stringdnsRecordId: stringrecord: objectreplace?: boolean(false= PATCH,true= PUT)authorizationKey?: string
cloudflare_delete_dns_record
- Use when: deleting DNS records intentionally.
- Do not use when: rollback plan is missing.
- Classification: mutating, high risk.
- Required permissions: admin key when configured.
- Parameters:
userId?: stringtokenId?: stringzoneId?: stringdnsRecordId: stringauthorizationKey?: string
- Safety warnings: destructive and irreversible.
cloudflare_api_request
- Use when: any Cloudflare endpoint access is needed, including APIs without dedicated tools.
- Do not use when: dedicated tools already cover the operation and are safer.
- Classification: read-only or mutating depending on
method; variable risk. - Required permissions/prerequisites:
- Active user-scoped Vault token.
- If mutating (
POST|PUT|PATCH|DELETE) andMCP_ADMIN_AUTH_KEYis set,authorizationKeyis required.
- Environment behavior:
- Normalizes path to Cloudflare v4 route under
/client/v4. - Resolves default token from user config and active token state.
- Normalizes path to Cloudflare v4 route under
- Parameters:
method: stringpath: stringquery?: object<string, string|number|boolean>body?: jsonheaders?: object<string,string>userId?: stringtokenId?: stringauthorizationKey?: string
- Expected response shape:
{ method, path, url, status, tokenId, userId, data }
- Common failure conditions:
- Missing token in Vault
- Invalid Cloudflare credentials
- Cloudflare API 4xx/5xx
- Admin auth key mismatch for mutating operations
- Recommended prerequisite tools:
cloudflare_verify_tokencloudflare_schema_discovery
- Recommended follow-up tools:
cloudflare_config_set(to persist defaults)cloudflare_query_suggestion(for workflow refinement)
- Safety warnings:
- Mutating calls can alter/delete production resources.
- Short valid invocation examples:
{"name":"cloudflare_api_request","arguments":{"method":"GET","path":"/zones","userId":"default"}}
{"name":"cloudflare_api_request","arguments":{"method":"PATCH","path":"/zones/<zone>/settings/cache_level","body":{"value":"aggressive"},"authorizationKey":"<admin-key-if-required>"}}
Suggested Playbooks
- Bootstrap new user credentials
cloudflare_scope_infocloudflare_token_upsertcloudflare_verify_token
- Configure user defaults
cloudflare_config_set(cloudflare.default.accountId)cloudflare_config_set(cloudflare.default.zoneId)cloudflare_config_set(cloudflare.default.tokenId)
- Safe DNS mutation
cloudflare_list_dns_recordscloudflare_create_dns_recordorcloudflare_update_dns_recordorcloudflare_delete_dns_record
- Full API call flow
cloudflare_schema_discoverycloudflare_query_suggestioncloudflare_api_request
License
MIT. See LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.