Make "Stateless" mode sessionless (#760)

- This removes the requirement to configure data protection which is the motivating reason for this change
- This means that McpServer.ClientInfo will always be null in stateless mode
This commit is contained in:
Stephen Halter 2025-10-02 15:57:01 -07:00 • committed by GitHub
commit 47b9582fd7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 72 deletions

View file

@ -54,8 +54,10 @@ public abstract class HttpServerIntegrationTests : LoggedTest, IClassFixture<Sse
Assert.NotNull(client.ServerInfo);
Assert.NotNull(client.NegotiatedProtocolVersion);
if (ClientTransportOptions.Endpoint.AbsolutePath.EndsWith("/sse"))
if (ClientTransportOptions.Endpoint.AbsolutePath.EndsWith("/sse") ||
ClientTransportOptions.Endpoint.AbsolutePath.EndsWith("/stateless"))
{
// In SSE and in Streamable HTTP's stateless mode, no protocol-defined session IDs are used.:w
Assert.Null(client.SessionId);
}
else

View file

@ -158,7 +158,7 @@ public class MapMcpStreamableHttpTests(ITestOutputHelper outputHelper) : MapMcpT
{
return async context =>
{
if (!StringValues.IsNullOrEmpty(context.Request.Headers["mcp-session-id"]))
if (!StringValues.IsNullOrEmpty(context.Request.Headers["mcp-protocol-version"]))
{
protocolVersionHeaderValues.Add(context.Request.Headers["mcp-protocol-version"]);
}
@ -179,8 +179,11 @@ public class MapMcpStreamableHttpTests(ITestOutputHelper outputHelper) : MapMcpT
Assert.Equal("2025-03-26", mcpClient.NegotiatedProtocolVersion);
await mcpClient.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken);
await mcpClient.DisposeAsync();
// The header should be included in the GET request, the initialized notification, the tools/list call, and the delete request.
Assert.NotEmpty(protocolVersionHeaderValues);
// The DELETE request won't be sent for Stateless mode due to the lack of an Mcp-Session-Id.
Assert.Equal(Stateless ? 3 : 4, protocolVersionHeaderValues.Count);
Assert.All(protocolVersionHeaderValues, v => Assert.Equal("2025-03-26", v));
}
}

View file

@ -85,6 +85,8 @@ public abstract class MapMcpTests(ITestOutputHelper testOutputHelper) : KestrelI
[Fact]
public async Task Messages_FromNewUser_AreRejected()
{
Assert.SkipWhen(Stateless, "User validation across requests is not applicable in stateless mode.");
Builder.Services.AddMcpServer().WithHttpTransport(ConfigureStateless).WithTools<EchoHttpContextUserTools>();
// Add an authentication scheme that will send a 403 Forbidden response.