From 6b363267f0337d31a522275586e39b2e58b51f57 Mon Sep 17 00:00:00 2001 From: Liu Shuang Date: Thu, 25 Dec 2025 10:02:08 +0800 Subject: [PATCH 1/3] fix: enhance SSE stream validation by checking Content-Type header --- mcp/streamable.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcp/streamable.go b/mcp/streamable.go index b4b2fa31..0a8de31a 100644 --- a/mcp/streamable.go +++ b/mcp/streamable.go @@ -1550,7 +1550,7 @@ func (c *streamableClientConn) connectStandaloneSSE() { // SSE stream at this endpoint." // // [§2.2.3]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#listening-for-messages-from-the-server - if resp.StatusCode == http.StatusMethodNotAllowed { + if resp.StatusCode == http.StatusMethodNotAllowed || resp.Header.Get("Content-Type") != "text/event-stream" { // The server doesn't support the standalone SSE stream. resp.Body.Close() return From a9eec70ed9684b195bc043c968c1b7964d896ea7 Mon Sep 17 00:00:00 2001 From: Liu Shuang Date: Tue, 30 Dec 2025 10:22:06 +0800 Subject: [PATCH 2/3] update TestStreamableClientGETHandling to include Content-Type validation --- mcp/streamable_client_test.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/mcp/streamable_client_test.go b/mcp/streamable_client_test.go index e2923325..12284237 100644 --- a/mcp/streamable_client_test.go +++ b/mcp/streamable_client_test.go @@ -17,6 +17,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2" "github.com/modelcontextprotocol/go-sdk/jsonrpc" ) @@ -258,14 +259,16 @@ func TestStreamableClientGETHandling(t *testing.T) { tests := []struct { status int wantErrorContaining string + contentType string }{ - {http.StatusOK, ""}, - {http.StatusMethodNotAllowed, ""}, - // The client error status code is not treated as an error in non-strict - // mode. - {http.StatusNotFound, ""}, - {http.StatusBadRequest, ""}, - {http.StatusInternalServerError, "standalone SSE"}, + {http.StatusOK, "", "text/event-stream"}, + {http.StatusMethodNotAllowed, "", "text/event-stream"}, + //// The client error status code is not treated as an error in non-strict + //// mode. + {http.StatusNotFound, "", "text/event-stream"}, + {http.StatusBadRequest, "", "text/event-stream"}, + {http.StatusInternalServerError, "standalone SSE", "text/event-stream"}, + {http.StatusOK, "", "text/html; charset=utf-8"}, } for _, test := range tests { @@ -286,7 +289,7 @@ func TestStreamableClientGETHandling(t *testing.T) { }, {"GET", "123", "", ""}: { header: header{ - "Content-Type": "text/event-stream", + "Content-Type": test.contentType, }, status: test.status, wantProtocolVersion: latestProtocolVersion, From 88dad3a09b8486df4ebbc1c5263fbe51f6f3d34c Mon Sep 17 00:00:00 2001 From: Liu Shuang Date: Wed, 31 Dec 2025 10:32:22 +0800 Subject: [PATCH 3/3] fix: improve standalone SSE stream validation by checking Content-Type header --- mcp/streamable.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mcp/streamable.go b/mcp/streamable.go index 0a8de31a..52269afb 100644 --- a/mcp/streamable.go +++ b/mcp/streamable.go @@ -1550,11 +1550,19 @@ func (c *streamableClientConn) connectStandaloneSSE() { // SSE stream at this endpoint." // // [§2.2.3]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#listening-for-messages-from-the-server - if resp.StatusCode == http.StatusMethodNotAllowed || resp.Header.Get("Content-Type") != "text/event-stream" { + if resp.StatusCode == http.StatusMethodNotAllowed { // The server doesn't support the standalone SSE stream. resp.Body.Close() return } + if resp.Header.Get("Content-Type") != "text/event-stream" { + // modelcontextprotocol/go-sdk#736: some servers return 200 OK or redirect with + // non-SSE content type instead of text/event-stream for the standalone + // SSE stream. + c.logger.Warn(fmt.Sprintf("got Content-Type %s instead of text/event-stream for standalone SSE stream", resp.Header.Get("Content-Type"))) + resp.Body.Close() + return + } if resp.StatusCode >= 400 && resp.StatusCode < 500 && !c.strict { // modelcontextprotocol/go-sdk#393,#610: some servers return NotFound or // other status codes instead of MethodNotAllowed for the standalone SSE