Skip to content

Commit d297272

Browse files
authored
mcp: relax SSE connection response handling in non-strict mode (#611)
Some MCP servers do not support SSE, but when receiving a request, they return 400 Bad Request or 404 Not Found instead of the standard 405 Method Not Allowed. The TypeScript and Python SDK ignore this error, while the Go SDK terminates the session. This patch addresses the issue in the non-strict mode. Fixes #610 --------- Signed-off-by: Xie Zhihao <[email protected]>
1 parent 32d84d8 commit d297272

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

mcp/streamable.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,13 +1377,14 @@ func (c *streamableClientConn) connectStandaloneSSE() {
13771377
resp.Body.Close()
13781378
return
13791379
}
1380-
if resp.StatusCode == http.StatusNotFound && !c.strict {
1381-
// modelcontextprotocol/gosdk#393: some servers return NotFound instead
1382-
// of MethodNotAllowed for the standalone SSE stream.
1380+
if resp.StatusCode >= 400 && resp.StatusCode < 500 && !c.strict {
1381+
// modelcontextprotocol/go-sdk#393,#610: some servers return NotFound or
1382+
// other status codes instead of MethodNotAllowed for the standalone SSE
1383+
// stream.
13831384
//
13841385
// Treat this like MethodNotAllowed in non-strict mode.
13851386
if c.logger != nil {
1386-
c.logger.Warn("got 404 instead of 405 for standalone SSE stream")
1387+
c.logger.Warn(fmt.Sprintf("got %d instead of 405 for standalone SSE stream", resp.StatusCode))
13871388
}
13881389
resp.Body.Close()
13891390
return

mcp/streamable_client_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,11 @@ func TestStreamableClientGETHandling(t *testing.T) {
239239
}{
240240
{http.StatusOK, ""},
241241
{http.StatusMethodNotAllowed, ""},
242-
{http.StatusBadRequest, "standalone SSE"},
242+
// The client error status code is not treated as an error in non-strict
243+
// mode.
244+
{http.StatusNotFound, ""},
245+
{http.StatusBadRequest, ""},
246+
{http.StatusInternalServerError, "standalone SSE"},
243247
}
244248

245249
for _, test := range tests {
@@ -305,7 +309,11 @@ func TestStreamableClientStrictness(t *testing.T) {
305309
{"strict initialized", true, http.StatusOK, http.StatusMethodNotAllowed, true},
306310
{"unstrict initialized", false, http.StatusOK, http.StatusMethodNotAllowed, false},
307311
{"strict GET", true, http.StatusAccepted, http.StatusNotFound, true},
308-
{"unstrict GET", false, http.StatusOK, http.StatusNotFound, false},
312+
// The client error status code is not treated as an error in non-strict
313+
// mode.
314+
{"unstrict GET on StatusNotFound", false, http.StatusOK, http.StatusNotFound, false},
315+
{"unstrict GET on StatusBadRequest", false, http.StatusOK, http.StatusBadRequest, false},
316+
{"GET on InternlServerError", false, http.StatusOK, http.StatusInternalServerError, true},
309317
}
310318
for _, test := range tests {
311319
t.Run(test.label, func(t *testing.T) {

0 commit comments

Comments
 (0)