Skip to content

[v2] Add an end-to-end public-client PKCE server contract #3472

Description

@NgoTuong12345

What happened?

With mcp==2.1.1, an MCP authorization server still cannot advertise and register an OAuth public client consistently without downstream patching:

  • build_metadata() does not include none in token_endpoint_auth_methods_supported.
  • RegistrationHandler defaults an omitted token_endpoint_auth_method to client_secret_post, minting a secret even for clients intending to operate as PKCE public clients.
  • The individual token handler pieces support token_endpoint_auth_method="none" when it is explicitly supplied, but there is no end-to-end SDK test pinning discovery -> DCR -> authorization-code/PKCE token exchange for a public client.

This is related to #2260, which was closed, and #2261, which remains open. The inconsistency is still present in the published v2 SDK.

For a real MCP server integration, we currently have to monkeypatch metadata generation and DCR's omitted-method behavior at import time. Those patches depend on private implementation details and are difficult to remove safely without a supported end-to-end public-client contract.

What did you expect?

The v2 server auth surface should support a complete public-client PKCE flow without monkeypatching:

  1. Authorization-server metadata advertises none.
  2. DCR preserves an explicit token_endpoint_auth_method="none" and has a documented, interoperable default for omitted methods.
  3. The token endpoint accepts the registered public client without a client secret and verifies the PKCE code_verifier against the authorization code's challenge.
  4. An SDK integration test covers the full flow so future releases do not regress it.

Merging or superseding #2261 plus adding the end-to-end test would provide a clear downstream exit condition.

Code to reproduce

from mcp.server.auth.handlers.register import RegistrationHandler
from mcp.server.auth.routes import build_metadata

# In mcp==2.1.1:
# - build_metadata() omits "none" from token_endpoint_auth_methods_supported
# - RegistrationHandler.handle defaults an omitted token_endpoint_auth_method
#   to "client_secret_post"

SDK version

2.1.1

Area

Auth

Related

Activity

  1. vinitsonawane45 commented on Sep 8, 2026

    @vinitsonawane45

    Hi @NgoTuong12345,

    I'd like to work on this issue.

    I understand the intended scope as the v2 end-to-end public-client PKCE contract:

    • advertise token_endpoint_auth_method="none" in authorization-server metadata;
    • ensure DCR preserves an explicit "none" and clarify the behavior when the method is omitted;
    • verify that the authorization-code/token flow works for a public client using PKCE without a client secret;
    • add an integration test covering the complete metadata → DCR → authorization-code/PKCE → token-exchange flow.

    I also saw the related #2261 work, but I understand that #3472 is intended to establish and test the complete v2 contract rather than simply porting that change.

    Before I start implementing, could you confirm that this is the intended scope and that you're okay with me taking this issue?

    I will keep the change focused on the agreed scope and add the necessary integration tests.

  2. added
    v2Affects the v2 line (2.x on main)
    v1Affects the v1.x maintenance line
    on Sep 10, 2026
  3. added
    enhancementRequest for a new feature that's not currently supported
    on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequest for a new feature that's not currently supportedv1Affects the v1.x maintenance linev2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions