Skip to content

Commit dbf5420

Browse files
committed
Write "event: message" to SSE response
1 parent 674cb15 commit dbf5420

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/ModelContextProtocol/Protocol/Transport/SseResponseStreamTransport.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public async Task SendMessageAsync(IJsonRpcMessage message, CancellationToken ca
7676
throw new InvalidOperationException($"Transport is not connected. Make sure to call {nameof(RunAsync)} first.");
7777
}
7878

79-
await _outgoingSseChannel.Writer.WriteAsync(new SseItem<IJsonRpcMessage?>(message), cancellationToken);
79+
// Emit redundant "event: message" lines for better compatibility with other SDKs.
80+
await _outgoingSseChannel.Writer.WriteAsync(new SseItem<IJsonRpcMessage?>(message, "message"), cancellationToken);
8081
}
8182

8283
/// <summary>

tests/ModelContextProtocol.Tests/SseServerIntegrationTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using ModelContextProtocol.Client;
22
using ModelContextProtocol.Protocol.Types;
33
using ModelContextProtocol.Tests.Utils;
4+
using System.Net;
5+
using System.Text;
46

57
namespace ModelContextProtocol.Tests;
68

@@ -30,6 +32,12 @@ private Task<IMcpClient> GetClientAsync(McpClientOptions? options = null)
3032
cancellationToken: TestContext.Current.CancellationToken);
3133
}
3234

35+
private HttpClient GetHttpClient() =>
36+
new()
37+
{
38+
BaseAddress = new(_fixture.DefaultConfig.Location!),
39+
};
40+
3341
[Fact]
3442
public async Task ConnectAndPing_Sse_TestServer()
3543
{
@@ -271,4 +279,46 @@ public async Task CallTool_Sse_EchoServer_Concurrently()
271279
Assert.Equal($"Echo: Hello MCP! {i}", textContent.Text);
272280
}
273281
}
282+
283+
[Fact]
284+
public async Task EventSourceStream_Includes_MessageEventType()
285+
{
286+
// Simulate our own MCP client handshake using a plain HttpClient so we can look for "event: message"
287+
// in the raw SSE response stream which is not exposed by the real MCP client.
288+
using var httpClient = GetHttpClient();
289+
await using var sseResponse = await httpClient.GetStreamAsync("", TestContext.Current.CancellationToken);
290+
using var streamReader = new StreamReader(sseResponse);
291+
292+
// read event stream from the server
293+
var endpointEvent = await streamReader.ReadLineAsync(TestContext.Current.CancellationToken);
294+
Assert.Equal("event: endpoint", endpointEvent);
295+
296+
var endpointData = await streamReader.ReadLineAsync(TestContext.Current.CancellationToken);
297+
Assert.NotNull(endpointData);
298+
Assert.StartsWith("data: ", endpointData);
299+
var messageEndpoint = endpointData["data: ".Length..];
300+
301+
const string initializeRequest = """
302+
{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"IntegrationTestClient","version":"1.0.0"}}}
303+
""";
304+
using (var initializeRequestBody = new StringContent(initializeRequest, Encoding.UTF8, "application/json"))
305+
{
306+
var response = await httpClient.PostAsync(messageEndpoint, initializeRequestBody, TestContext.Current.CancellationToken);
307+
Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
308+
}
309+
310+
const string initializeNotification = """
311+
{"jsonrpc":"2.0","method":"notifications/initialized"}
312+
""";
313+
using (var initializeNotificationBody = new StringContent(initializeNotification, Encoding.UTF8, "application/json"))
314+
{
315+
var response = await httpClient.PostAsync(messageEndpoint, initializeNotificationBody, TestContext.Current.CancellationToken);
316+
Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
317+
}
318+
319+
// read event stream from the server
320+
Assert.Equal("", await streamReader.ReadLineAsync(TestContext.Current.CancellationToken));
321+
var messageEvent = await streamReader.ReadLineAsync(TestContext.Current.CancellationToken);
322+
Assert.Equal("event: message", messageEvent);
323+
}
274324
}

0 commit comments

Comments
 (0)