From afbfb7cbda4369b997ad5a5fe7b0d2d1acafc3e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 15:25:31 +0000 Subject: [PATCH 1/3] Initial plan From ff40ebc4f8d904bfb5936dc5d84d43f33139d647 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 15:36:55 +0000 Subject: [PATCH 2/3] Add test for AdditionalHeaders in Streamable HTTP transport Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../MapMcpStreamableHttpTests.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs b/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs index 8f04cbe8b..962170996 100644 --- a/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs +++ b/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; using ModelContextProtocol.Client; @@ -355,4 +356,60 @@ public async Task EnablePollingAsync_ThrowsInvalidOperationException_WhenNoEvent Assert.NotNull(capturedException); Assert.Contains("event stream store", capturedException.Message, StringComparison.OrdinalIgnoreCase); } + + [Fact] + public async Task AdditionalHeaders_AreSent_InPostAndDeleteRequests() + { + Assert.SkipWhen(Stateless, "DELETE requests are not sent in stateless mode due to lack of session ID."); + + bool wasPostRequest = false; + bool wasDeleteRequest = false; + + Builder.Services.AddMcpServer().WithHttpTransport(ConfigureStateless).WithTools(); + + await using var app = Builder.Build(); + + app.Use(next => + { + return async context => + { + Assert.Equal("Bearer testToken", context.Request.Headers["Authorization"]); + if (context.Request.Method == HttpMethods.Post) + { + wasPostRequest = true; + } + else if (context.Request.Method == HttpMethods.Delete) + { + wasDeleteRequest = true; + } + await next(context); + }; + }); + + app.MapMcp(); + + await app.StartAsync(TestContext.Current.CancellationToken); + + var transportOptions = new HttpClientTransportOptions + { + Endpoint = new("http://localhost:5000/"), + Name = "In-memory Streamable HTTP Client", + TransportMode = HttpTransportMode.StreamableHttp, + AdditionalHeaders = new Dictionary + { + ["Authorization"] = "Bearer testToken" + }, + }; + + await using var mcpClient = await ConnectAsync(transportOptions: transportOptions); + + // Do a tool call to ensure there's more than just the initialize request + await mcpClient.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken); + + // Dispose the client to trigger the DELETE request + await mcpClient.DisposeAsync(); + + Assert.True(wasPostRequest, "POST request was not made"); + Assert.True(wasDeleteRequest, "DELETE request was not made"); + } } From c71eb844a634363d05d13f5ff7161443acd83185 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 15:42:23 +0000 Subject: [PATCH 3/3] Align header name with existing SSE test for consistency Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../MapMcpStreamableHttpTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs b/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs index 962170996..2098e79c9 100644 --- a/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs +++ b/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs @@ -373,7 +373,7 @@ public async Task AdditionalHeaders_AreSent_InPostAndDeleteRequests() { return async context => { - Assert.Equal("Bearer testToken", context.Request.Headers["Authorization"]); + Assert.Equal("Bearer testToken", context.Request.Headers["Authorize"]); if (context.Request.Method == HttpMethods.Post) { wasPostRequest = true; @@ -397,7 +397,7 @@ public async Task AdditionalHeaders_AreSent_InPostAndDeleteRequests() TransportMode = HttpTransportMode.StreamableHttp, AdditionalHeaders = new Dictionary { - ["Authorization"] = "Bearer testToken" + ["Authorize"] = "Bearer testToken" }, };