Repository navigation
fix(mcp): upgrade to MCP SDK 2.3.0 and raise the per-event SSE size cap - #47034
Conversation
MCP SDK 2.x reads Streamable HTTP responses through httpx2's SSE parser, which rejects any single event over 1 MiB, so a large tools/call result failed with 'SSE stream ended without a response'. mcp 2.3.0 exposes max_sse_event_size, and MCPClient now passes a 64 MiB default, configurable with LITELLM_MCP_MAX_SSE_EVENT_SIZE_BYTES Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Merging this PR will not alter performance
|
|
@greptileai @litereview code-review Please review commit 828c770 for SDK compatibility, SSE limit handling, and meaningful regression coverage before merge |
|
bugbot run Please review commit 828c770 for SDK compatibility, SSE size enforcement, and regression coverage before merge |
|
@litereview code-review Please verify the current SDK upgrade, SSE regression test, and compatibility evidence for commit 828c770 |
|
@greptileai Please review the current SDK upgrade, SSE regression test, and compatibility evidence for commit 828c770 before merge |
Review already requestedcode-review is already reviewing |
|
|
@greptileai @litereview code-review Please review 916ebf8, including invalid SSE limits, supported positive overrides, regression coverage, and the updated live evidence |
|
bugbot run Please review 916ebf8 for invalid SSE limit handling, supported overrides, regression coverage, and compatibility with existing MCP transports |
|
@litereview code-review Please review commit 916ebf8 for invalid SSE limits, transport compatibility, regression tests, and current live verification evidence |
Review already requestedcode-review is already reviewing |
[Medium impact] Both previous findings are addressed, with no remaining review findings blocking merge SummaryBoth previous findings are addressed. No new issues found
Reviews (3) · Last reviewed commit: "chore(mcp): remove redundant dependency ..." · Reviewed by Greptile |
|
@greptileai Please review 86108ee and confirm the configured-limit finding is resolved by the real proxy regression and hardcoded-limit mutation evidence |
|
@litereview code-review Please review 86108ee, including configured SSE limit rejection and recovery, mutation evidence, and refreshed live verification results |
|
bugbot run Please review 86108ee, including configured SSE limit rejection and recovery, mutation evidence, and refreshed live verification results |
|
@greptileai Please review fb3c00b and confirm both findings resolved. The latest commit only removes the flagged dependency comment |
|
@litereview code-review Please review final commit fb3c00b, covering validated limits, configured-limit transport regression, mutation evidence, and the dependency comment removal |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fb3c00b. Configure here.

TLDR
Problem this solves:
How it solves it:
User Flow
Before, a large tool result fails even though the upstream answered
dump(size)http://localhost:4000/mcp-rest/tools/callwith{"server_id":"big","name":"dump","arguments":{"size":3145728}}isError: trueandMCPError: SSE stream ended without a responseAfter, the caller receives the complete tool result
http://localhost:4000/mcp-rest/tools/callisError: falseand exactly 3,145,728 charactersAffected release
Regression in v1.103.0 following the MCP SDK 2.x migration in #41718
Linear ticket
Resolves LIT-9750
Implementation and validation
MCP 2.3.0 exposes
max_sse_event_size, but its default remains 1 MiB. The gateway passes 64 MiB by default and supportsLITELLM_MCP_MAX_SSE_EVENT_SIZE_BYTES. Positive platform-sized integers are preserved. Unset, blank, nonnumeric, nonpositive and oversized integer values use the default, with the existing parser logging invalid valuesThe proxy and MCP extras require
mcp>=2.3.0,<3andhttpx2>=2.10.0,<3. The uv override handles the admin MCP development dependency's older exact MCP pin. No unrelated dependency versions changeAffected constants and MCP client tests pass, 555 total, on the identical production code at
916ebf815bed27d17a2193b84f67a48a1be11db2. The follow-up86108ee8a9489c7d10de5226bc98fcb5ab76c23dadds only an integration test. Final commitfb3c00bdc5574d3ee48c807979b5252c194f1389removes the flagged dependency comment without changing code or locked dependencies. The final nine-case regression also passes separately. Against the preceding PR tip, the same regression fails for zero, negative and oversized limits, with the six supported controls passingCanonical
make checkanduv lock --checkpass against merge baseaa32e4cc8861eb6134391949373ebae6049311ff. Local coverage covers the changed executable line and all 16 lines and six branches in the transport factory. The completed current-tip Codecov report is available, with 100% patch coverage (2/2 lines) and 59.28% repository-wide coverage. The patch number is separate from the local executable-line and branch measurements. Eight unrelated Pydantic ReadOnly warnings come from unchanged definitionsThe configured-limit integration test starts an owned real proxy with a 4096-byte limit, discovers its tools, accepts a 512-character result, rejects an 8192-character result, and accepts the next 512-character result. It passes locally. Replacing the transport argument with a hardcoded 64 MiB makes it fail at the rejection assertion. This addresses Greptile’s configured-limit coverage finding. The integration suite runs on main in CircleCI, so this new case was executed locally before merge
Screenshots / Proof of Fix
Use source installations with each revision's locked dependencies. Start an SDK
MCPServerexposingdump(size)asreturn "x" * sizeathttp://127.0.0.1:18901/mcp. Register it asbigwithtransport: http. Start the source proxy on port 4100 with a local master key in$KEY. This server includes the text in both content and structuredContent, so the SSE event is approximately twice the requested sizeBefore (aa32e4c)
Large result
dumptoolisError: true,MCPError: SSE stream ended without a responseAfter (fb3c00b)
Large result
dumptoolFalse 3145728 TrueInvalid-limit repair and supported controls
Independent verification repeated the merge-base and final-commit cases on separate source builds with their locked MCP versions (2.2.0 on base, 2.3.0 on final). Both integration regressions fail on base and pass on final. The following fresh local replay compares preceding PR tip
828c770857b294c2a64c99fef0b3853fd08db202with final commitfb3c00bdc5574d3ee48c807979b5252c194f1389, using MCP 2.3.0 and httpx2 2.13.0 on both buildsLITELLM_MCP_MAX_SSE_EVENT_SIZE_BYTES=0, then-1. Run the same discovery and call commands for sizes 500000 and 3145728. Before, discovery and calls return HTTP 500 for both SSE and JSON-response MCP servers. After, discovery returnsdumpand every call returns HTTP 200 with the exact requested textServer-sent event exceeded the 200000 byte limit, then returns the exact third result. JSON-response calls all succeedinvalid. Both builds return exact results using the default limitAll 64 HTTP observations matched the expected outcomes. These are real source proxies and SDK MCP servers, with no mocked gateway calls. All local verification processes were stopped
Final verification
Reviewed commit
fb3c00bdc5574d3ee48c807979b5252c194f1389Greptile gives 5/5 and confirms both findings resolved. Bugbot reports no issues. Veria reports no security issues. LiteReview gives 5/5 with no correctness findings, 618 tests passing, and a passing configured-limit integration test that fails when the transport argument is removed. All review threads are resolved
Independent source-build verification compared merge base
aa32e4cc8861eb6134391949373ebae6049311ff, prior PR tip828c770857b294c2a64c99fef0b3853fd08db202, and the final commit above. It repeated the curl flows above and ran both integration nodes through the repository harnessThe baseline integration runs applied only the final test diff. Original zero/negative proxy logs did not drain before shutdown, so warning text was recaptured with separate startup-only proxies on the same final source. Response observations were retained from the original processes. Task-owned verifier processes and environments were removed
Pre-Submission checklist
Type
Bug Fix
Test
Caveats
Medium
Low
Final Attestation