Add Streamable HTTP request body limits (#3095)
This commit is contained in:
parent
2713b53b12
commit
03aaebd3aa
2 changed files with 280 additions and 19 deletions
|
|
@ -622,6 +622,7 @@ Transport-specific parameters have been moved from the `MCPServer` constructor t
|
|||
- `sse_path`, `message_path` - SSE transport paths
|
||||
- `streamable_http_path` - StreamableHTTP endpoint path
|
||||
- `json_response`, `stateless_http` - StreamableHTTP behavior
|
||||
- `max_request_body_size` - StreamableHTTP request-body limit
|
||||
- `event_store`, `retry_interval` - StreamableHTTP event handling
|
||||
- `transport_security` - DNS rebinding protection
|
||||
|
||||
|
|
@ -675,6 +676,21 @@ app = Starlette(routes=[Mount("/", app=mcp.streamable_http_app(json_response=Tru
|
|||
|
||||
If you were mutating these via `mcp.settings` after construction (e.g., `mcp.settings.port = 9000`), pass them to `run()` / `sse_app()` / `streamable_http_app()` instead — these fields no longer exist on `Settings`. The `debug` and `log_level` parameters remain on the constructor.
|
||||
|
||||
### Streamable HTTP request bodies are limited to 4 MiB
|
||||
|
||||
V2 applies a 4 MiB default limit to Streamable HTTP POST bodies and returns HTTP 413 before parsing
|
||||
the JSON or creating a session when that limit is exceeded.
|
||||
|
||||
Most servers need no migration. If your application intentionally accepts larger MCP messages,
|
||||
set an explicit byte limit on `run()` or `streamable_http_app()`:
|
||||
|
||||
```python
|
||||
mcp.run(transport="streamable-http", max_request_body_size=8 * 1024 * 1024)
|
||||
```
|
||||
|
||||
The limit must be positive and applies to both legacy session-based requests and V2's modern
|
||||
single-exchange requests. Keep the smallest value your application actually needs.
|
||||
|
||||
### Streamable HTTP: lifespan now entered once at manager startup
|
||||
|
||||
When serving streamable HTTP (stateful or `stateless_http=True`), the server's `lifespan` context manager is now entered once when `StreamableHTTPSessionManager.run()` starts, and the resulting state is shared across all sessions and requests. Previously each session (stateful) or each request (stateless) entered and exited `lifespan` independently.
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ Each transport has its own keyword arguments, all on `run()`:
|
|||
* `streamable_http_path`: where the MCP endpoint lives. Default `/mcp`.
|
||||
* `json_response=True`: answer with plain JSON instead of an SSE stream.
|
||||
* `stateless_http=True`: a fresh transport per request, no session tracking.
|
||||
* `max_request_body_size`: largest accepted POST body in bytes. Defaults to 4 MiB; larger requests
|
||||
receive HTTP 413 before parsing or session creation. Raise it only when legitimate MCP messages
|
||||
exceed that size.
|
||||
* `event_store`, `retry_interval`, `transport_security`: resumability and DNS-rebinding protection. They can wait, until you deploy somewhere other than localhost; **[Deploy & scale](deploy.md)** covers `transport_security`.
|
||||
|
||||
!!! warning
|
||||
|
|
|
|||
Loading…
Reference in a new issue