Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.
This repository was archived by the owner on May 15, 2026. It is now read-only.

[ENHANCEMENT] Support MCP OAuth 2.1 for HTTP MCP servers (discovery + PKCE) #8119

Description

@hannesrudolph

Type

Enhancement

Problem / Value

When Roo connects to a protected HTTP-based MCP server, it should initiate a standard OAuth 2.1 flow automatically so users can securely use enterprise/protected MCP servers. Today, Roo does not consistently trigger this flow after a 401 + WWW-Authenticate challenge, which blocks connections to compliant servers.

Context

  • Original report: “Roo does not initiate the OAuth flow if the remote MCP server implements Authorization.”
  • Example setup from the report: fastmcp with Azure provider; server returns 401 with WWW-Authenticate and advertises OAuth resource metadata.
  • User environment noted in the report:
    • App Version: 3.25.20
    • OS: macOS Sequoia 15.5
    • VS Code: 1.103.0 (Universal)
    • API Provider: OpenAI Compatible
    • Model: Claude Sonnet 4

Desired Behavior (at a high level)

Roo should:
1 Parse HTTP 401 WWW-Authenticate to discover the OAuth 2.0 Protected Resource Metadata (RFC 9728).
2) Fetch the resource metadata (/.well-known/oauth-protected-resource) to obtain authorization_servers and select one.
3) Discover authorization server metadata (RFC 8414 and OpenID Connect Discovery 1.0) using the required precedence for issuers with/without path components.
4) If supported, perform Dynamic Client Registration (RFC 7591) to obtain a client_id (and client_secret if confidential).
5) Start Authorization Code + PKCE (S256), including the resource parameter (RFC 8707) in both authorization and token requests.
6) Exchange the authorization code for tokens, store them securely, then retry MCP requests with Authorization: Bearer .
7) Handle token refresh/expiry and error conditions per spec.

Implementation Notes (standards summary for assignees)

  • Roles

    • MCP Server: OAuth 2.1 Resource Server
    • Roo (MCP Client): OAuth 2.1 Client
    • Authorization Server: issues access tokens for use at the MCP server
  • Resource Server Discovery (RFC 9728)

    • On 401, parse WWW-Authenticate and obtain resource metadata URL
    • GET /.well-known/oauth-protected-resource
    • Use authorization_servers (may be multiple; client selects per RFC guidance)
  • Authorization Server Discovery (RFC 8414 + OIDC Discovery 1.0)

    • Issuer with path (e.g., https://auth.example.com/tenant1):
      1. /.well-known/oauth-authorization-server/tenant1
      2. /.well-known/openid-configuration/tenant1
      3. /tenant1/.well-known/openid-configuration
    • Issuer without path (e.g., https://auth.example.com):
      1. /.well-known/oauth-authorization-server
      2. /.well-known/openid-configuration
    • MUST attempt in this priority and support both specs
  • Dynamic Client Registration (RFC 7591) [SHOULD]

    • POST /register to obtain client_id (and client_secret if confidential)
    • If not supported, Roo needs config/UI to provide client_id(/secret)
  • Authorization Code + PKCE (OAuth 2.1)

    • PKCE S256 required; verify PKCE support via AS metadata:
      • RFC 8414: if code_challenge_methods_supported is absent → refuse
      • OIDC Discovery: verify code_challenge_methods_supported present → if absent → refuse
    • Redirect URIs must be HTTPS or localhost
    • Include state; open browser for authorization
  • Resource Indicators (RFC 8707) [MUST]

  • Token Usage and Validation

    • Authorization: Bearer on every HTTP request (never in query string)
    • Resource server validates tokens per OAuth 2.1 §5.2 and audience per RFC 8707
    • No token passthrough to upstream APIs; obtain separate tokens if the MCP server calls upstream APIs
  • Error Handling

    • 401 Unauthorized: auth required/invalid or expired token (use WWW-Authenticate)
    • 403 Forbidden: insufficient scope/permissions
    • 400 Bad Request: malformed auth request
  • Security Considerations (Required)

    • HTTPS for AS endpoints; redirect URIs HTTPS or localhost
    • PKCE S256 mandatory with metadata verification as above
    • Use/verify state to mitigate open redirection
    • Secure token storage; prefer short-lived access tokens; refresh-token rotation for public clients
    • Enforce audience validation; forbid token passthrough (“confused deputy”)

Acceptance Criteria

  • After a 401 with WWW-Authenticate from an HTTP MCP server:

    • Roo fetches RFC 9728 resource metadata and selects an authorization server
    • Roo discovers AS metadata using the ordered endpoints above (RFC 8414 + OIDC Discovery)
    • If available, Roo performs RFC 7591 dynamic client registration and persists client details
    • Roo runs Authorization Code + PKCE (S256) and:
      • Includes resource in both authorization and token requests
      • Verifies code_challenge_methods_supported via metadata; refuses if absent or S256 unsupported
    • Roo securely stores tokens, injects Authorization: Bearer on all MCP HTTP calls, refreshes when needed
    • Roo retries the original MCP request after successful token acquisition
    • Roo surfaces clear UX for 400/401/403 and auth prompts
  • Tests

    • Unit: header parsing (WWW-Authenticate), resource metadata fetch/parse, AS discovery fallback ordering, PKCE generation/verification, resource parameter inclusion, token header injection, error handling
    • Integration: end-to-end against a mock/proxy AS + MCP resource server
    • Manual QA: documented flow with a real provider (e.g., fastmcp Azure)

Non-Goals

  • Proprietary flows outside OAuth 2.1, RFC 9728, RFC 8414/OIDC Discovery, RFC 7591, RFC 8707
  • Token passthrough to upstream APIs

Open Questions

  • Should Roo expose a small UI for manual client_id(/secret) entry when dynamic registration is unavailable?
  • What secure storage mechanism will Roo use for tokens/refresh tokens across platforms?

References

Proposed Labels: feature request; Issue - Needs Scoping
GH_BODY
)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions