SSE client transport: tolerate return of RPC responses in POST requests. (#445)
* SSE client transport: handle return of RPC responses in POST requests. * Remove accidental change. * Address feedback * Remove unused namespace.
This commit is contained in:
parent
ee9b04b7e5
commit
77f9e64e04
1 changed files with 30 additions and 14 deletions
|
|
@ -58,6 +58,22 @@ public partial class SseIntegrationTests(ITestOutputHelper outputHelper) : Kestr
|
|||
Assert.True(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConnectAndReceiveMessage_ServerReturningJsonInPostRequest()
|
||||
{
|
||||
await using var app = Builder.Build();
|
||||
MapAbsoluteEndpointUriMcp(app, respondInJson: true);
|
||||
|
||||
await app.StartAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
await using var mcpClient = await ConnectMcpClientAsync();
|
||||
|
||||
// Send a test message through POST endpoint
|
||||
await mcpClient.SendNotificationAsync("test/message", new Envelope { Message = "Hello, SSE!" }, serializerOptions: JsonContext.Default.Options, cancellationToken: TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.True(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConnectAndReceiveNotification_InMemoryServer()
|
||||
{
|
||||
|
|
@ -220,7 +236,7 @@ public partial class SseIntegrationTests(ITestOutputHelper outputHelper) : Kestr
|
|||
Assert.Equal("Failed to add header '' with value '' from AdditionalHeaders.", ex.Message);
|
||||
}
|
||||
|
||||
private static void MapAbsoluteEndpointUriMcp(IEndpointRouteBuilder endpoints)
|
||||
private static void MapAbsoluteEndpointUriMcp(IEndpointRouteBuilder endpoints, bool respondInJson = false)
|
||||
{
|
||||
var loggerFactory = endpoints.ServiceProvider.GetRequiredService<ILoggerFactory>();
|
||||
var optionsSnapshot = endpoints.ServiceProvider.GetRequiredService<IOptions<McpServerOptions>>();
|
||||
|
|
@ -267,7 +283,7 @@ public partial class SseIntegrationTests(ITestOutputHelper outputHelper) : Kestr
|
|||
await Results.BadRequest("Session not started.").ExecuteAsync(context);
|
||||
return;
|
||||
}
|
||||
var message = (JsonRpcMessage?)await context.Request.ReadFromJsonAsync(McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(JsonRpcMessage)), context.RequestAborted);
|
||||
var message = await context.Request.ReadFromJsonAsync<JsonRpcMessage>(McpJsonUtilities.DefaultOptions, context.RequestAborted);
|
||||
if (message is null)
|
||||
{
|
||||
await Results.BadRequest("No message in request body.").ExecuteAsync(context);
|
||||
|
|
@ -276,7 +292,15 @@ public partial class SseIntegrationTests(ITestOutputHelper outputHelper) : Kestr
|
|||
|
||||
await session.OnMessageReceivedAsync(message, context.RequestAborted);
|
||||
context.Response.StatusCode = StatusCodes.Status202Accepted;
|
||||
await context.Response.WriteAsync("Accepted");
|
||||
|
||||
if (respondInJson)
|
||||
{
|
||||
await context.Response.WriteAsJsonAsync(message, McpJsonUtilities.DefaultOptions, cancellationToken: context.RequestAborted);
|
||||
}
|
||||
else
|
||||
{
|
||||
await context.Response.WriteAsync("Accepted");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue