From ed408c2ffb2b0ff8623113dc136364949ce243d6 Mon Sep 17 00:00:00 2001 From: Benjamin Bartels Date: Tue, 27 Jan 2026 21:24:39 +0000 Subject: [PATCH 1/6] Support https+http scheme for .NET Aspire service discovery --- .../Client/HttpClientTransportOptions.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs index 73eaae700..999493052 100644 --- a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs +++ b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs @@ -25,7 +25,9 @@ public required Uri Endpoint { throw new ArgumentException("Endpoint must be an absolute URI.", nameof(value)); } - if (value.Scheme != Uri.UriSchemeHttp && value.Scheme != Uri.UriSchemeHttps) + if (value.Scheme != Uri.UriSchemeHttp && + value.Scheme != Uri.UriSchemeHttps && + value.Scheme != $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}") { throw new ArgumentException("Endpoint must use HTTP or HTTPS scheme.", nameof(value)); } From e8ae0ac401a30dabe6a3e6dedd142bb1be53bdd2 Mon Sep 17 00:00:00 2001 From: Benjamin Bartels Date: Tue, 27 Jan 2026 21:30:41 +0000 Subject: [PATCH 2/6] Update HttpClientTransportOptions.cs --- .../Client/HttpClientTransportOptions.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs index 999493052..7b5cf42c5 100644 --- a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs +++ b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs @@ -25,9 +25,7 @@ public required Uri Endpoint { throw new ArgumentException("Endpoint must be an absolute URI.", nameof(value)); } - if (value.Scheme != Uri.UriSchemeHttp && - value.Scheme != Uri.UriSchemeHttps && - value.Scheme != $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}") + if (value.Scheme is not (Uri.UriSchemeHttp or Uri.UriSchemeHttps or $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}")) { throw new ArgumentException("Endpoint must use HTTP or HTTPS scheme.", nameof(value)); } From e11e98f5fa84bf500dd4a7dcb371033486cc25d6 Mon Sep 17 00:00:00 2001 From: Benjamin Bartels Date: Tue, 27 Jan 2026 21:34:41 +0000 Subject: [PATCH 3/6] Refactor authorization endpoint scheme check --- .../Authentication/ClientOAuthProvider.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs index 75126556b..4a23d46cb 100644 --- a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs +++ b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs @@ -342,8 +342,7 @@ private async Task GetAuthServerMetadataAsync(Uri a ThrowFailedToHandleUnauthorizedResponse($"No authorization_endpoint was provided via '{wellKnownEndpoint}'."); } - if (metadata.AuthorizationEndpoint.Scheme != Uri.UriSchemeHttp && - metadata.AuthorizationEndpoint.Scheme != Uri.UriSchemeHttps) + if (metadata.AuthorizationEndpoint.Scheme is not (Uri.UriSchemeHttp or Uri.UriSchemeHttps or $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}")) { ThrowFailedToHandleUnauthorizedResponse($"AuthorizationEndpoint must use HTTP or HTTPS. '{metadata.AuthorizationEndpoint}' does not meet this requirement."); } From 66798162346a45a8da7525656484e17d6468cf4a Mon Sep 17 00:00:00 2001 From: bbartels Date: Wed, 28 Jan 2026 00:08:13 +0000 Subject: [PATCH 4/6] Addresses PR feedback --- .../Authentication/ClientOAuthProvider.cs | 9 +++++++-- .../Client/HttpClientTransportOptions.cs | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs index 4a23d46cb..312814784 100644 --- a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs +++ b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs @@ -24,6 +24,7 @@ internal sealed partial class ClientOAuthProvider : McpHttpClient /// private const string BearerScheme = "Bearer"; private const string ProtectedResourceMetadataWellKnownPath = "/.well-known/oauth-protected-resource"; + private static readonly string HttpsPlusHttpScheme = $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}"; private readonly Uri _serverUrl; private readonly Uri _redirectUri; @@ -342,9 +343,13 @@ private async Task GetAuthServerMetadataAsync(Uri a ThrowFailedToHandleUnauthorizedResponse($"No authorization_endpoint was provided via '{wellKnownEndpoint}'."); } - if (metadata.AuthorizationEndpoint.Scheme is not (Uri.UriSchemeHttp or Uri.UriSchemeHttps or $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}")) + string authorizationEndpointScheme = metadata.AuthorizationEndpoint.Scheme; + + if (authorizationEndpointScheme != Uri.UriSchemeHttp && + authorizationEndpointScheme != Uri.UriSchemeHttps && + authorizationEndpointScheme != HttpsPlusHttpScheme) { - ThrowFailedToHandleUnauthorizedResponse($"AuthorizationEndpoint must use HTTP or HTTPS. '{metadata.AuthorizationEndpoint}' does not meet this requirement."); + ThrowFailedToHandleUnauthorizedResponse($"AuthorizationEndpoint must use HTTP, HTTPS, or HTTPS+HTTP. '{metadata.AuthorizationEndpoint}' does not meet this requirement."); } metadata.ResponseTypesSupported ??= ["code"]; diff --git a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs index 7b5cf42c5..2168310a5 100644 --- a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs +++ b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs @@ -7,6 +7,8 @@ namespace ModelContextProtocol.Client; /// public sealed class HttpClientTransportOptions { + private static readonly string HttpsPlusHttpScheme = $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}"; + /// /// Gets or sets the base address of the server for SSE connections. /// @@ -25,9 +27,13 @@ public required Uri Endpoint { throw new ArgumentException("Endpoint must be an absolute URI.", nameof(value)); } - if (value.Scheme is not (Uri.UriSchemeHttp or Uri.UriSchemeHttps or $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}")) + string scheme = value.Scheme; + + if (scheme != Uri.UriSchemeHttp && + scheme != Uri.UriSchemeHttps && + scheme != HttpsPlusHttpScheme) { - throw new ArgumentException("Endpoint must use HTTP or HTTPS scheme.", nameof(value)); + throw new ArgumentException("Endpoint must use HTTP, HTTPS, or HTTPS+HTTP scheme.", nameof(value)); } field = value; From c81d4debd95288abbaf00d45aa0223775373095a Mon Sep 17 00:00:00 2001 From: Benjamin Bartels Date: Sun, 8 Feb 2026 11:41:44 +0000 Subject: [PATCH 5/6] Refactor authorization endpoint scheme validation --- .../Authentication/ClientOAuthProvider.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs index 312814784..75126556b 100644 --- a/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs +++ b/src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs @@ -24,7 +24,6 @@ internal sealed partial class ClientOAuthProvider : McpHttpClient /// private const string BearerScheme = "Bearer"; private const string ProtectedResourceMetadataWellKnownPath = "/.well-known/oauth-protected-resource"; - private static readonly string HttpsPlusHttpScheme = $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}"; private readonly Uri _serverUrl; private readonly Uri _redirectUri; @@ -343,13 +342,10 @@ private async Task GetAuthServerMetadataAsync(Uri a ThrowFailedToHandleUnauthorizedResponse($"No authorization_endpoint was provided via '{wellKnownEndpoint}'."); } - string authorizationEndpointScheme = metadata.AuthorizationEndpoint.Scheme; - - if (authorizationEndpointScheme != Uri.UriSchemeHttp && - authorizationEndpointScheme != Uri.UriSchemeHttps && - authorizationEndpointScheme != HttpsPlusHttpScheme) + if (metadata.AuthorizationEndpoint.Scheme != Uri.UriSchemeHttp && + metadata.AuthorizationEndpoint.Scheme != Uri.UriSchemeHttps) { - ThrowFailedToHandleUnauthorizedResponse($"AuthorizationEndpoint must use HTTP, HTTPS, or HTTPS+HTTP. '{metadata.AuthorizationEndpoint}' does not meet this requirement."); + ThrowFailedToHandleUnauthorizedResponse($"AuthorizationEndpoint must use HTTP or HTTPS. '{metadata.AuthorizationEndpoint}' does not meet this requirement."); } metadata.ResponseTypesSupported ??= ["code"]; From 41a5f530a48c1bffd72de74208b6bfcc134f2953 Mon Sep 17 00:00:00 2001 From: Benjamin Bartels Date: Sun, 8 Feb 2026 11:42:43 +0000 Subject: [PATCH 6/6] Refactor HttpClientTransportOptions by removing scheme checks Removed the HttpsPlusHttpScheme variable and related validation checks for the endpoint scheme. --- .../Client/HttpClientTransportOptions.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs index 2168310a5..95cddddaa 100644 --- a/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs +++ b/src/ModelContextProtocol.Core/Client/HttpClientTransportOptions.cs @@ -7,8 +7,6 @@ namespace ModelContextProtocol.Client; /// public sealed class HttpClientTransportOptions { - private static readonly string HttpsPlusHttpScheme = $"{Uri.UriSchemeHttps}+{Uri.UriSchemeHttp}"; - /// /// Gets or sets the base address of the server for SSE connections. /// @@ -27,14 +25,6 @@ public required Uri Endpoint { throw new ArgumentException("Endpoint must be an absolute URI.", nameof(value)); } - string scheme = value.Scheme; - - if (scheme != Uri.UriSchemeHttp && - scheme != Uri.UriSchemeHttps && - scheme != HttpsPlusHttpScheme) - { - throw new ArgumentException("Endpoint must use HTTP, HTTPS, or HTTPS+HTTP scheme.", nameof(value)); - } field = value; }