From 90b8156229541d38b45d9641d5864df5c67dec61 Mon Sep 17 00:00:00 2001 From: Yaroslav Shevchuk Date: Mon, 26 Oct 2026 08:08:15 +0000 Subject: [PATCH] fix default maxEventSize --- mcp/streamable.go | 6 +++++- mcp/streamable_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/mcp/streamable.go b/mcp/streamable.go index e4fe035b..01ab3105 100644 --- a/mcp/streamable.go +++ b/mcp/streamable.go @@ -2288,6 +2288,10 @@ func (t *StreamableClientTransport) Connect(ctx context.Context) (Connection, er } else if maxRetries < 0 { maxRetries = 0 } + maxEventSize := t.MaxEventSize + if maxEventSize == 0 { + maxEventSize = DefaultMaxEventSize + } // Create a new cancellable context that will manage the connection's lifecycle. // This is crucial for cleanly shutting down the background SSE listener by // cancelling its blocking network operations, which prevents hangs on exit. @@ -2318,7 +2322,7 @@ func (t *StreamableClientTransport) Connect(ctx context.Context) (Connection, er failed: make(chan struct{}), disableStandaloneSSE: t.DisableStandaloneSSE, oauthHandler: t.OAuthHandler, - maxEventSize: t.MaxEventSize, + maxEventSize: maxEventSize, } return conn, nil } diff --git a/mcp/streamable_test.go b/mcp/streamable_test.go index 19f475e1..bdbb07d1 100644 --- a/mcp/streamable_test.go +++ b/mcp/streamable_test.go @@ -3012,6 +3012,36 @@ func TestProcessStreamMaxEventSize(t *testing.T) { } } +// TestStreamableClientDefaultMaxEventSize verifies that a zero +// StreamableClientTransport.MaxEventSize applies DefaultMaxEventSize rather +// than disabling the cap. +func TestStreamableClientDefaultMaxEventSize(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Mcp-Session-Id", "session") + io.WriteString(w, "event: message\ndata: ") + chunk := strings.Repeat("A", 1<<20) + for range 2 * DefaultMaxEventSize / len(chunk) { + if _, err := io.WriteString(w, chunk); err != nil { + return + } + } + })) + defer srv.Close() + + client := NewClient(testImpl, nil) + transport := &StreamableClientTransport{Endpoint: srv.URL, DisableStandaloneSSE: true} + _, err := client.Connect(t.Context(), transport, nil) + want := fmt.Sprintf("SSE event exceeded %d bytes", DefaultMaxEventSize) + if err == nil || !strings.Contains(err.Error(), want) { + t.Fatalf("Connect() error = %v, want an error containing %q", err, want) + } +} + // TestScanEventsPingFiltering is a unit test for the low-level event scanning // with ping events to verify scanEvents properly parses all event types. func TestScanEventsPingFiltering(t *testing.T) {