Skip to content

Conversation

@chipgpt
Copy link
Contributor

@chipgpt chipgpt commented Oct 10, 2025

Updates the OAuth authorization flow to prefer to use the token_endpoint_auth_method result from the Dynamic Client Registration endpoint, if provided.

#951

Motivation and Context

When using dynamic client registration, the registration endpoint may return the token_endpoint_auth_method value to be used when exchanging tokens for access tokens. The current oauth implementation ignores this field and only uses the methods from the oauth authorization server metadata.

How Has This Been Tested?

This has not been tested in a real application.

Breaking Changes

No breaking changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Previous PR #982 is no longer showing changes after rebase for some reason and was automatically closed, reopening new PR

@chipgpt chipgpt requested review from a team as code owners October 10, 2025 17:35
* server.
*/
clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
clientInformation(): OAuthClientInformationFull | undefined | Promise<OAuthClientInformationFull | undefined>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this type signature change worries me a bit. The OAuthClientInformation is the response from the DCR endpoint, listed here:
https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1

All the fields are optional except for redirect_uris (which is what I think is what required a bunch of changes in tests).

this means this change will be backwards incompatible for implementations of the provider that directly return the DCR response rather than the full metadata.

saveClientInformation takes the full information type, so this might be a non issue.

to land this, we'll either want to:

  • check around for implementations to see if they commonly return the reduced type, to see the estimated impact of the breaking change
  • OR: make this backwards compatible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I can make it backwards compatible. My only argument for changing the type is that it seems like the current type is wrong. As you pointed out, saveClientInformation() takes the OAuthClientInformationFull type and is the only way clientInformation() is set.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this a bit more and chatted w/ @ochafik & @felixweinberger .

There's 2 flows to consider:

  • DCR Request + Response
  • Saving and restoring client information

For the DCR Request + Response, requiring redirect_uri's in both cases is correct. We require sending one, and the DCR response is required to send back any data related to the client:

Additionally, the authorization server MUST return all registered
metadata about this client, including any fields provisioned by the
authorization server itself.

However, saveClientInformation and clientInformation are used in non-DCR flows as well. In static registration situations, providing the redirect URI's isn't required and are often not available. Similarly, with the upcoming Client ID Metadata Document flow, the list of redirect URI's will not be on the client necessarily.

So what that means is:

  • OAuthClientInformationFull could more properly be named OAuthDCRResponseMetadata (or something similar). Although renaming here isn't strictly necessary.
  • HaveOAuthClientInformationFull be an optional type for both saveClientInformation and clientInformation
  • Also allow OAuthClientInformation as a type in both cases

That will loosen the type to accommodate both DCR and non-DCR cases, and also allow us to get the supported token_endpoint_auth_method in the DCR response if it's available.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcarleton understood. will follow up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcarleton I have redone the PR.

export type OAuthClientInformationMixed = OAuthClientInformation | OAuthClientInformationFull;

@felixweinberger felixweinberger added needs more work auth Issues and PRs related to Authentication / OAuth labels Oct 17, 2025
addClientAuthentication(headers, params, authorizationServerUrl, metadata);
} else {
// Determine and apply client authentication method
const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [];
Copy link

@frankie567 frankie567 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a less intrusive solution would be the following:

const supportedMethods = clientInformation.token_endpoint_auth_method ? [clientInformation.token_endpoint_auth_method] : (metadata?.token_endpoint_auth_methods_supported ?? [])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed this is less intrusive, but it has a slightly different behavior. If the metadata has "token_endpoint_auth_methods_supported": ["none"] and the client registration endpoint returns "token_endpoint_auth_method": "client_secret_post", this code would bypass the metadata's "supported" value. Is that allowed?

https://www.rfc-editor.org/rfc/rfc8414.html

token_endpoint_auth_methods_supported
OPTIONAL. JSON array containing a list of client authentication methods supported by this token endpoint. Client authentication method values are used in the "token_endpoint_auth_method" parameter defined in Section 2 of [RFC7591]. If omitted, the default is "client_secret_basic" -- the HTTP Basic Authentication Scheme specified in Section 2.3.1 of OAuth 2.0 [RFC6749].

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess that's unlikely, but still possible 😊

@chipgpt chipgpt force-pushed the fix/dcr-use-token-auth-method branch from 110b067 to 9bda5df Compare October 28, 2025 01:46
Copy link
Member

@pcarleton pcarleton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, LGTM! Thanks for the patience

@pcarleton pcarleton merged commit 874aa27 into modelcontextprotocol:main Oct 28, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Issues and PRs related to Authentication / OAuth needs more work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants