claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Missing `scope` Parameter in Dynamic Client Registration and Authorization Requests

Open vobornik opened this issue 5 months ago • 15 comments

Description:

We have observed that the Claude Code client, when attempting to integrate with an OAuth2 Authorization Server (ORY Hydra) and a Memory Control Plane (MCP) endpoint, consistently fails to include the scope parameter during both the dynamic client registration request and the subsequent authorization request. This behavior deviates from standard OAuth2 practices and prevents proper scope negotiation and authorization.

Our system correctly advertises supported scopes via the OAuth2 Discovery Endpoint (/.well-known/oauth-authorization-server), but the Claude client does not appear to utilize this information when constructing its requests.

Steps to Reproduce:

  1. Configure the Claude Code client to connect to an MCP server that supports OAuth2 Authorization Code Flow with PKCE and dynamic client registration.
  2. Initiate the connection process from the Claude Code client.
  3. Observe the network requests and server-side logs.

Expected Behavior:

  1. During dynamic client registration (POST /register), the Claude client should include a scope parameter in its request body, indicating the desired permissions (e.g., mcp:read, mcp:write, offline_access).
  2. Subsequently, when redirecting to the authorization endpoint (/oauth2/auth), the Claude client should include the scope parameter in the query string, reflecting the permissions it seeks from the user.
  3. According to RFC 6749, Section 3.3 (Access Token Scope): "If the client omits the scope parameter when requesting authorization, the authorization server MUST NOT assume a default scope. Instead, the authorization server SHOULD either deny the request or process the request with a zero-length scope." Therefore, the client is responsible for explicitly requesting scopes.

Actual Behavior:

  1. The Claude Code client successfully performs dynamic client registration, but the scope parameter is entirely absent from the POST /register request body.
  2. The authorization URL generated by the Claude client and sent to the authorization server also lacks the scope parameter.

Technical Details:

1. OAuth2 Discovery Endpoint (/.well-known/oauth-authorization-server) - Supported Scopes:

Our system correctly advertises the following supported scopes:

{
  "scopes_supported": [
    "mcp:read",
    "mcp:write",
    "mcp:search",
    "offline_access"
  ],
 "response_types_supported": [
    "code"
  ]
}

2. MCP Server Log - Dynamic Client Registration Request (POST /register):

The mcp service logs show the incoming request data for dynamic client registration. As seen below, the scope parameter is missing from the request_data payload:

2025-07-27 17:42:31,108 - main - INFO - 2025-07-27T17:42:31.108694 [info     ] Dynamic client registration requested [main] has_client_id=False request_data={'client_name': 'Claude Code (LLMory)', 'redirect_uris': ['http://localhost:65068/callback'], 'grant_types': ['authorization_code', 'refresh_token'], 'response_types': ['code'], 'token_endpoint_auth_method': 'none'}

3. Claude Debug Output / Auth Proxy Log - Authorization URL:

The authorization URL generated by the Claude client and captured in our auth-proxy logs (and also visible in the Claude debug output) explicitly lacks the scope parameter:

[DEBUG] MCP server "LLMory": Authorization URL: https://mcp.llmory.com/oauth2/auth?response_type=code&client_id=claude-code--llmory-d255d3fc&code_challenge=nYb27OxYnL7l_tIs3lj5pzh0qBrEtG_j-_5YhqSpV_4&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A63692%2Fcallback&state=Zy_iztgf_LsRux2bgLa1v7qZcoyCH_6cxu1QhDgZb2w&resource=https%3A%2F%2Fmcp.llmory.com%2F

(Note: client_id and redirect_uri may vary based on the specific run, but the absence of scope is consistent.)

Impact:

This issue prevents the Claude client from requesting necessary permissions from the user, leading to:

  • Functional limitations: The client will not receive an access token with the required scopes to interact with the MCP server's protected resources.
  • User experience issues: The consent screen presented to the user will not display any requested permissions, potentially confusing the user and hindering the authorization process.

Recommendation:

We request that the Claude Code client be updated to:

  1. Properly parse and utilize the scopes_supported (and ideally mcp_default_scopes) values from the OAuth2 Discovery Endpoint.
  2. Include the appropriate scope parameter in both dynamic client registration requests and authorization requests, as per RFC 6749.

vobornik avatar Jul 27 '25 18:07 vobornik