Apply the request body limit to the SSE and OAuth endpoints
#3095 added RequestBodyLimitMiddleware and applied it to the Streamable HTTP endpoint. This does the same for the other two places that accept request bodies, so every HTTP entry point shares the one 4 MiB default.
Motivation and Context
SseServerTransporttakesmax_request_body_size(default 4 MiB, same validation asStreamableHTTPSessionManager), andMCPServer.sse_app()/run(transport="sse")pass it through, mirroringstreamable_http_app(). The message endpoint now answers 405 to anything that isn't a POST instead of treating it as one.- The
create_auth_routesendpoints (/token,/revoke,/register, POST/authorize) use the default limit. On the CORS-enabled routes it sits inside the CORS wrapper, so a 413 still carries CORS headers and preflights are untouched. These endpoints use the 4 MiB default rather than a configurable value; their payloads are a few kilobytes. - The middleware itself no longer special-cases POST: the limit applies to a request body whatever method carries it, since some of these routes also accept
OPTIONS/HEADand their handlers read the body either way. RequestBodyLimitMiddlewareandDEFAULT_MAX_REQUEST_BODY_SIZEmove tomcp.server.transport_security, next to the other shared HTTP request checks, now that three modules use them. Both remain importable frommcp.server.streamable_http_manager.
Nothing changes for requests under the limit.
How Has This Been Tested?
New tests in tests/server/test_sse_security.py, tests/server/auth/test_error_handling.py, tests/server/test_transport_security.py and tests/server/mcpserver/test_server.py: over-limit bodies (declared and streamed, across methods) get 413, bodies under the limit still reach session lookup / form parsing, CORS preflights are still answered and a 413 on a CORS route keeps its CORS headers, non-POST to the message endpoint gets 405, and sse_app() applies the configured value. Full suite, pyright and ruff pass locally.
Breaking Changes
None. The new keyword is optional and defaults to the limit streamable_http_app() already uses; the observable differences are a 413 for request bodies over 4 MiB on these endpoints and a 405 for non-POST requests to the SSE message endpoint.
Types of changes
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing functionality to change)
- Documentation update
Checklist
- I am assigned to the linked issue (or it is labeled
help wanted, or I'm a maintainer) - I have disclosed any AI assistance and can explain the change in my own words
- I have read the MCP Documentation
- My code follows the repository's style guidelines
- New and existing tests pass locally
- I have added appropriate error handling
- I have added or updated documentation as needed
Additional context
docs/run/index.md describes max_request_body_size as the largest accepted request body; no new documentation for the SSE transport.