Summary
In affected versions, an MCP server built with this SDK read the whole body of every HTTP request into memory before checking its size. One large request grew the process's memory by two to three times the size of the body, so a client that could reach the server over HTTP could exhaust its memory and take it offline, repeatedly. No credentials are needed against the OAuth endpoints, or against a server that does not require authentication (the default).
Am I affected?
Yes, if clients you do not fully trust can reach your server over HTTP and it runs:
- 1.x before 1.29.1, or
- 2.0.0 or 2.0.1.
The limit arrived in two steps:
- 1.29.0 and 2.0.0 added a 4 MiB limit to the Streamable HTTP endpoint only.
- 1.29.1 and 2.1.0 extended it to the SSE transport's message endpoint and the OAuth authorization server routes (
/token, /register, /revoke, /authorize).
Not affected:
- servers that only use the stdio transport
- MCP clients
- deployments behind a reverse proxy or gateway that already caps request body size
Fix
Upgrade to mcp 1.29.1 (1.x) or 2.1.0 (2.x) or later. There is no fixed 2.0.x release.
Every HTTP endpoint the SDK provides then reads the body through one shared limit (default 4 MiB) and answers 413 as soon as a request declares or streams more than that, before any parsing.
If your clients send single messages larger than 4 MiB, raise the limit with max_request_body_size=:
- 1.x:
FastMCP(..., max_request_body_size=...)
- 2.x:
MCPServer.run(), streamable_http_app(), sse_app()
- or
StreamableHTTPSessionManager / SseServerTransport when you construct them yourself
Code that drives StreamableHTTPServerTransport directly, without the session manager, does not get the limit and should bound request bodies itself. If you cannot upgrade yet, cap request body size in a reverse proxy or ASGI middleware in front of the server.
Summary
In affected versions, an MCP server built with this SDK read the whole body of every HTTP request into memory before checking its size. One large request grew the process's memory by two to three times the size of the body, so a client that could reach the server over HTTP could exhaust its memory and take it offline, repeatedly. No credentials are needed against the OAuth endpoints, or against a server that does not require authentication (the default).
Am I affected?
Yes, if clients you do not fully trust can reach your server over HTTP and it runs:
The limit arrived in two steps:
/token,/register,/revoke,/authorize).Not affected:
Fix
Upgrade to
mcp1.29.1 (1.x) or 2.1.0 (2.x) or later. There is no fixed 2.0.x release.Every HTTP endpoint the SDK provides then reads the body through one shared limit (default 4 MiB) and answers
413as soon as a request declares or streams more than that, before any parsing.If your clients send single messages larger than 4 MiB, raise the limit with
max_request_body_size=:FastMCP(..., max_request_body_size=...)MCPServer.run(),streamable_http_app(),sse_app()StreamableHTTPSessionManager/SseServerTransportwhen you construct them yourselfCode that drives
StreamableHTTPServerTransportdirectly, without the session manager, does not get the limit and should bound request bodies itself. If you cannot upgrade yet, cap request body size in a reverse proxy or ASGI middleware in front of the server.