diff --git a/src/ModelContextProtocol.Core/Authentication/ClientOAuthOptions.cs b/src/ModelContextProtocol.Core/Authentication/ClientOAuthOptions.cs
index df1c44c1f..16df4816c 100644
--- a/src/ModelContextProtocol.Core/Authentication/ClientOAuthOptions.cs
+++ b/src/ModelContextProtocol.Core/Authentication/ClientOAuthOptions.cs
@@ -113,6 +113,20 @@ public sealed class ClientOAuthOptions
UrlFormat = ModelContextProtocol.Obsoletions.AuthorizationRedirectDelegate_Url)]
public AuthorizationRedirectDelegate? AuthorizationRedirectDelegate { get; set; }
+ ///
+ /// Gets or sets the token endpoint authentication method selector function.
+ ///
+ ///
+ ///
+ /// This function is used to select which token endpoint authentication method to use when multiple methods are available.
+ /// If not specified, the first available method will be selected.
+ ///
+ ///
+ /// The function receives a list of supported authentication methods from the authorization server metadata and should return the selected method, or null if no suitable method is found.
+ ///
+ ///
+ public Func?, string?>? TokenEndpointAuthMethodSelector { get; set; }
+
///
/// Gets or sets the authorization server selector function.
///
diff --git a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs
index 785e3cc2e..07e13552e 100644
--- a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs
+++ b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs
@@ -30,6 +30,7 @@ internal sealed partial class ClientOAuthProvider : McpHttpClient
private readonly string? _configuredScopes;
private readonly ScopeSelectorDelegate? _scopeSelector;
private readonly IDictionary _additionalAuthorizationParameters;
+ private readonly Func?, string?> _tokenEndpointAuthMethodSelector;
private readonly Func, Uri?> _authServerSelector;
private readonly Func> _authorizationCallbackHandler;
private readonly bool _validateAuthorizationResponseState;
@@ -106,6 +107,9 @@ public ClientOAuthProvider(
_additionalAuthorizationParameters = options.AdditionalAuthorizationParameters;
_clientMetadataDocumentUri = options.ClientMetadataDocumentUri;
+ // Set up token endpoint authentication method selector (use default if not provided)
+ _tokenEndpointAuthMethodSelector = options.TokenEndpointAuthMethodSelector ?? DefaultTokenEndpointAuthMethodSelector;
+
// Set up authorization server selection strategy
_authServerSelector = options.AuthServerSelector ?? DefaultAuthServerSelector;
@@ -154,6 +158,13 @@ public ClientOAuthProvider(
_tokenCache = options.TokenCache ?? new InMemoryTokenCache();
}
+ ///
+ /// Default token endpoint authentication method selector that selects the first supported method from the authorization server metadata.
+ ///
+ /// The list of supported token endpoint authentication methods.
+ /// The selected token endpoint authentication method, or null if none are available.
+ private static string? DefaultTokenEndpointAuthMethodSelector(IReadOnlyList? tokenEndpointAuthMethodsSupported) => tokenEndpointAuthMethodsSupported?.FirstOrDefault();
+
///
/// Default authorization server selection strategy that selects the first available server.
///
@@ -475,7 +486,7 @@ private async Task GetAccessTokenCoreAsync(HttpResponseMessage response,
_clientCredentialsAuthorizationServer = selectedAuthServer.OriginalString;
// Determine the token endpoint auth method from server metadata if not already set by DCR.
- _tokenEndpointAuthMethod ??= authServerMetadata.TokenEndpointAuthMethodsSupported?.FirstOrDefault();
+ _tokenEndpointAuthMethod ??= _tokenEndpointAuthMethodSelector(authServerMetadata.TokenEndpointAuthMethodsSupported);
// Store auth server metadata for future refresh operations
_authServerMetadata = authServerMetadata;