Skip to content

OAuth grant with DNS Read cannot list zone DNS records through https://mcp.cloudflare.com/mcp (error 10000) — zones list works #202

Description

@tirandigit

MCP Client

Other (please specify below)

MCP Client Version

opencode 1.18.21

Authentication Type

OAuth

OAuth Scopes (if applicable)

Read-only grant, 193 permissions total (verified in My Profile → Access Management → Connected Applications). Includes, among others:

  • DNS Read
  • Zone Read
  • Zone DNS Settings Read
  • Account DNS Settings Read
  • Zone Settings Read
  • Account Read / Memberships Read

Account restriction at consent: 1 account selected (the account that owns the affected zone).

MCP Server Configuration

Server URL: https://mcp.cloudflare.com/mcp
Access path: Cloudflare Zero Trust MCP server portal → upstream mcp.cloudflare.com
Server auth mode: OAuth credentials = Automatic (dynamic client registration, RFC 7591)
Client: [opencode]

Failing Endpoint / Tool

MCP tool: execute API endpoint: GET /zones/{zone_id}/dns_records

Bug Description

An OAuth grant that explicitly includes DNS Read and Zone Read can list zones and resolve a zone by name, but any call to GET /zones/{zone_id}/dns_records through the execute tool is deterministically rejected with Cloudflare error 10000 (Authentication error).

The zone belongs to the single account selected at OAuth consent, so both the permission and the account restriction should cover this call. This looks like the same class of problem as #170 (OAuth full-access grant rejected on zone SSL/custom-hostname endpoints), affecting a different endpoint family: DNS records.

Steps to Reproduce

  1. Connect an MCP client to https://mcp.cloudflare.com/mcp via OAuth. At consent, select read permissions including DNS Read, and restrict the grant to one account.
  2. Call the execute tool with: GET /zones?name= → succeeds; returns the zone, owned by the granted account.
  3. Call the execute tool with: GET /zones/<zone_id>/dns_records → fails with error 10000.
  4. Retry with pagination params, with and without an account_id tool argument → same failure.

Expected Behavior

DNS records for the zone are returned, since the grant includes DNS Read and the zone belongs to the account selected at consent.

Actual Behavior

{"success": false, "errors": [{"code": 10000, "message": "Authentication error"}], "messages": [], "result": null}

The failure is deterministic (every attempt), while GET /zones succeeds in the same session with the same grant.

Relevant Logs / Error Output

Session sequence (same OAuth session, consecutive calls):

GET /zones?name=<zone>
→ success: true, returns zone id + account (matches the granted account)

GET /zones/<zone_id>/dns_records
→ success: false, errors: [{ code: 10000, message: "Authentication error" }]

GET /zones/<zone_id>/dns_records (with account_id set)
→ same 10000 error

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions