Bug Report
MCP Client
OpenAI Codex Desktop / Codex Cloudflare plugin
Authentication Type
OAuth
MCP Server Configuration
{
"mcpServers": {
"cloudflare-api": {
"type": "http",
"url": "https://mcp.cloudflare.com/mcp"
}
}
}
OAuth Scopes
Maximum access was selected in every authorization screen shown during the OAuth flow.
The first Cloudflare MCP permission picker was set to full access (78 / 78). The selected scope list included ssl_certs:write / "SSL certificates Write" along with Workers, DNS, Pages, D1, and the other available read/write permissions.
The subsequent Cloudflare OAuth authorization screen also used maximum available access, with access granted for all visible Cloudflare accounts/organizations. That screen showed a smaller final consent set (48 total permissions) even though the previous MCP permission picker had 78 / 78 selected.
After completing authorization, the Cloudflare user settings page for connected applications showed the Cloudflare MCP Server authorization as 77 / 77 permissions granted. That 78 -> 77 difference may be unrelated, but it is worth noting because the user attempted to grant maximum access throughout the flow.
Despite that, the live OAuth token can read zones and Workers resources, but cannot read zone SSL/custom-hostname endpoints.
Failing Endpoints
These fail through the execute tool using cloudflare.request():
GET /zones/{zone_id}/custom_hostnames
GET /zones/{zone_id}/custom_hostnames/quota
GET /zones/{zone_id}/custom_hostnames/fallback_origin
GET /zones/{zone_id}/ssl/universal/settings
GET /zones/{zone_id}/ssl/certificate_packs
Bug Description
With maximum OAuth access selected for https://mcp.cloudflare.com/mcp in both authorization stages, and with access granted across all visible Cloudflare accounts/organizations, the Cloudflare API MCP server can successfully authenticate, list accounts, read the target account, read the target zone, and read Workers/D1/Pages resources. However, the same OAuth-authenticated session cannot access zone SSL and Cloudflare-for-SaaS custom-hostname endpoints.
This looks like an OAuth scope mapping or authorization-boundary issue rather than an account-selection issue:
GET /user succeeds.
GET /accounts shows the expected accounts.
GET /accounts/{account_id} succeeds for the target account.
GET /zones/{zone_id} succeeds for the target zone.
GET /accounts/{account_id}/workers/scripts succeeds.
GET /accounts/{account_id}/workers/domains succeeds.
GET /accounts/{account_id}/d1/database succeeds.
GET /accounts/{account_id}/pages/projects succeeds.
- Passing the account ID explicitly to the MCP
execute call does not change the failure.
- The failure reproduces on two separate accounts/zones where the user has admin-level access.
The repository appears to intend to support this permission via src/auth/scopes.ts:
'ssl_certs:write': 'Manage SSL certificates'
But the OAuth token issued after full-access consent does not appear able to use zone SSL/certificate APIs or Cloudflare-for-SaaS custom hostname APIs.
Steps to Reproduce
- Configure an MCP client with
https://mcp.cloudflare.com/mcp.
- Authenticate using OAuth.
- Select full access in the Cloudflare MCP permission picker (
78 / 78).
- Complete the following Cloudflare OAuth authorization screen with maximum available permissions and access to all visible Cloudflare accounts/organizations.
- After authorization, verify the connected application appears in Cloudflare user settings. In this reproduction it showed
77 / 77 permissions granted, not 78 / 78.
- Confirm ordinary account/zone/product access works:
await cloudflare.request({ method: "GET", path: "/user" })
await cloudflare.request({ method: "GET", path: "/accounts/{account_id}" })
await cloudflare.request({ method: "GET", path: "/zones/{zone_id}" })
await cloudflare.request({ method: "GET", path: "/accounts/{account_id}/workers/scripts" })
await cloudflare.request({ method: "GET", path: "/accounts/{account_id}/workers/domains" })
- Try zone SSL/custom-hostname endpoints:
await cloudflare.request({
method: "GET",
path: "/zones/{zone_id}/custom_hostnames",
query: { page: 1, per_page: 1 }
})
await cloudflare.request({
method: "GET",
path: "/zones/{zone_id}/custom_hostnames/fallback_origin"
})
await cloudflare.request({
method: "GET",
path: "/zones/{zone_id}/ssl/universal/settings"
})
await cloudflare.request({
method: "GET",
path: "/zones/{zone_id}/ssl/certificate_packs",
query: { page: 1, per_page: 1 }
})
Expected Behavior
An OAuth session that selected maximum available access throughout the flow, includes ssl_certs:write / "SSL certificates Write", and was granted access to all visible Cloudflare accounts/organizations should be able to read and manage zone SSL/certificate endpoints. It should also be able to at least read Cloudflare-for-SaaS custom hostname/fallback-origin state for zones the user can administer.
If these endpoints are intentionally outside OAuth support, the MCP server should document that boundary and surface a clearer error recommending API-token mode with the required zone-level API token permissions.
Actual Behavior
The same MCP OAuth session succeeds on account/zone/Workers/D1/Pages reads but fails on zone SSL/custom-hostname endpoints:
GET /zones/{zone_id}/custom_hostnames
Cloudflare API error: 10000: Authentication error
GET /zones/{zone_id}/custom_hostnames/quota
Cloudflare API error: 10000: Authentication error
GET /zones/{zone_id}/custom_hostnames/fallback_origin
Cloudflare API error: 10000: Authentication error
GET /zones/{zone_id}/ssl/universal/settings
Cloudflare API error: 9109: Unauthorized to access requested resource
GET /zones/{zone_id}/ssl/certificate_packs
Cloudflare API error: 9109: Unauthorized to access requested resource
Additional Context
This does not appear to be the MCP client selecting the wrong account. The account selector was tested explicitly and the same failures remained.
It also does not appear to be general Workers/DNS access failure. Workers scripts, Workers custom domains, D1, Pages, accounts, and zones all worked through the same OAuth connection.
The practical workaround is likely API-token mode with explicit zone-level permissions, including:
- Zone -> Zone -> Read
- Zone -> SSL and Certificates -> Edit
- Zone -> DNS -> Edit, if DNS automation is needed
- Account -> Workers Scripts / Workers Routes permissions, if Workers automation is needed
However, for OAuth/full-access mode, either the ssl_certs:write scope is not mapping to the required zone-level SSL permission, custom-hostname endpoints require an additional OAuth scope that is not available in the permission picker, or these endpoints currently do not accept this OAuth token type.
Could you confirm whether https://mcp.cloudflare.com/mcp OAuth full-access mode is expected to support:
/zones/{zone_id}/ssl/*
/zones/{zone_id}/custom_hostnames*
If yes, this looks like a scope mapping/authorization bug. If no, the README and/or tool error handling should make the limitation explicit and recommend API-token mode for Cloudflare-for-SaaS custom-hostname work.
Bug Report
MCP Client
OpenAI Codex Desktop / Codex Cloudflare plugin
Authentication Type
OAuth
MCP Server Configuration
{ "mcpServers": { "cloudflare-api": { "type": "http", "url": "https://mcp.cloudflare.com/mcp" } } }OAuth Scopes
Maximum access was selected in every authorization screen shown during the OAuth flow.
The first Cloudflare MCP permission picker was set to full access (
78 / 78). The selected scope list includedssl_certs:write/ "SSL certificates Write" along with Workers, DNS, Pages, D1, and the other available read/write permissions.The subsequent Cloudflare OAuth authorization screen also used maximum available access, with access granted for all visible Cloudflare accounts/organizations. That screen showed a smaller final consent set (
48 total permissions) even though the previous MCP permission picker had78 / 78selected.After completing authorization, the Cloudflare user settings page for connected applications showed the Cloudflare MCP Server authorization as
77 / 77permissions granted. That78->77difference may be unrelated, but it is worth noting because the user attempted to grant maximum access throughout the flow.Despite that, the live OAuth token can read zones and Workers resources, but cannot read zone SSL/custom-hostname endpoints.
Failing Endpoints
These fail through the
executetool usingcloudflare.request():Bug Description
With maximum OAuth access selected for
https://mcp.cloudflare.com/mcpin both authorization stages, and with access granted across all visible Cloudflare accounts/organizations, the Cloudflare API MCP server can successfully authenticate, list accounts, read the target account, read the target zone, and read Workers/D1/Pages resources. However, the same OAuth-authenticated session cannot access zone SSL and Cloudflare-for-SaaS custom-hostname endpoints.This looks like an OAuth scope mapping or authorization-boundary issue rather than an account-selection issue:
GET /usersucceeds.GET /accountsshows the expected accounts.GET /accounts/{account_id}succeeds for the target account.GET /zones/{zone_id}succeeds for the target zone.GET /accounts/{account_id}/workers/scriptssucceeds.GET /accounts/{account_id}/workers/domainssucceeds.GET /accounts/{account_id}/d1/databasesucceeds.GET /accounts/{account_id}/pages/projectssucceeds.executecall does not change the failure.The repository appears to intend to support this permission via
src/auth/scopes.ts:But the OAuth token issued after full-access consent does not appear able to use zone SSL/certificate APIs or Cloudflare-for-SaaS custom hostname APIs.
Steps to Reproduce
https://mcp.cloudflare.com/mcp.78 / 78).77 / 77permissions granted, not78 / 78.Expected Behavior
An OAuth session that selected maximum available access throughout the flow, includes
ssl_certs:write/ "SSL certificates Write", and was granted access to all visible Cloudflare accounts/organizations should be able to read and manage zone SSL/certificate endpoints. It should also be able to at least read Cloudflare-for-SaaS custom hostname/fallback-origin state for zones the user can administer.If these endpoints are intentionally outside OAuth support, the MCP server should document that boundary and surface a clearer error recommending API-token mode with the required zone-level API token permissions.
Actual Behavior
The same MCP OAuth session succeeds on account/zone/Workers/D1/Pages reads but fails on zone SSL/custom-hostname endpoints:
Additional Context
This does not appear to be the MCP client selecting the wrong account. The account selector was tested explicitly and the same failures remained.
It also does not appear to be general Workers/DNS access failure. Workers scripts, Workers custom domains, D1, Pages, accounts, and zones all worked through the same OAuth connection.
The practical workaround is likely API-token mode with explicit zone-level permissions, including:
However, for OAuth/full-access mode, either the
ssl_certs:writescope is not mapping to the required zone-level SSL permission, custom-hostname endpoints require an additional OAuth scope that is not available in the permission picker, or these endpoints currently do not accept this OAuth token type.Could you confirm whether
https://mcp.cloudflare.com/mcpOAuth full-access mode is expected to support:/zones/{zone_id}/ssl/*/zones/{zone_id}/custom_hostnames*If yes, this looks like a scope mapping/authorization bug. If no, the README and/or tool error handling should make the limitation explicit and recommend API-token mode for Cloudflare-for-SaaS custom-hostname work.