From 8e45782dbd21322c73381f3a021dd2bb0f3d7108 Mon Sep 17 00:00:00 2001 From: Dayna Blackwell Date: Mon, 4 May 2026 03:14:20 -0700 Subject: [PATCH] mcp: close HTTP response body from DELETE request in streamableClientConn.Close (#929) ## Summary The DELETE request that terminates a streamable HTTP session discards the `*http.Response` without closing its body. Per the `net/http` documentation, this prevents the underlying TCP connection from being reused and leaks it. ## The bug ```go // mcp/streamable.go:2239 (before) } else if _, err := c.client.Do(req); err != nil { c.closeErr = err } ``` On the success path (no error), the response is silently discarded. The default client is `http.DefaultClient` with keep-alives enabled, so the leaked connection stays open until GC or process exit. ## The fix ```go // mcp/streamable.go:2239 (after) } else if resp, err := c.client.Do(req); err != nil { c.closeErr = err } else { resp.Body.Close() } ``` All 10 other `client.Do` call sites in this file close the response body. This one was missed. ## Test plan - [x] `go build ./...` passes - [x] `go test ./... -short` passes Fixes #928 --- mcp/streamable.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mcp/streamable.go b/mcp/streamable.go index 708b132..41acc5d 100644 --- a/mcp/streamable.go +++ b/mcp/streamable.go @@ -2236,8 +2236,10 @@ func (c *streamableClientConn) Close() error { } else { if err := c.setMCPHeaders(req); err != nil { c.closeErr = err - } else if _, err := c.client.Do(req); err != nil { + } else if resp, err := c.client.Do(req); err != nil { c.closeErr = err + } else { + resp.Body.Close() } } }