Fail fast on server-to-client requests in JSON-response mode instead of hanging (#3195)
This commit is contained in:
parent
27f5cc7a46
commit
528e366558
2 changed files with 259 additions and 93 deletions
|
|
@ -65,7 +65,7 @@ Each transport has its own keyword arguments, all on `run()`:
|
|||
|
||||
* `host` / `port`: where to listen. Defaults `127.0.0.1` and `8000`.
|
||||
* `streamable_http_path`: where the MCP endpoint lives. Default `/mcp`.
|
||||
* `json_response=True`: answer with plain JSON instead of an SSE stream.
|
||||
* `json_response=True`: answer each POST with a single JSON body instead of an SSE stream. That body has room for the response and nothing else, so a tool that calls back into the client mid-request (`ctx.elicit()`, sampling) raises `NoBackChannelError` on this leg, and notifications tied to the in-flight call (progress from `ctx.report_progress()`, per-call log messages) are dropped; the standalone `GET` stream still carries unrelated ones.
|
||||
* `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
|
||||
|
|
|
|||
|
|
@ -72,6 +72,13 @@ Two things about it matter more than what it does.
|
|||
|
||||
**It costs both server-to-client channels on that leg.** A session that lives for one `POST` has no stream for the server to push a request down and no standalone stream for it to push notifications down. Every server-initiated request raises `NoBackChannelError`: `ctx.elicit()`, the retired sampling and roots calls (**[Deprecated features](../deprecated.md)**), and, yes, `Resolve` asking a *legacy* client its question. Notifications don't even get an error; they are silently dropped.
|
||||
|
||||
!!! note
|
||||
`json_response=True` is not that knob, but it takes half the same cost on *every* legacy
|
||||
session: a `POST` answered with one JSON body has no stream for the request-scoped channel,
|
||||
so a mid-request `ctx.elicit()` raises the same `NoBackChannelError` and notifications tied to
|
||||
the request are dropped. The session's standalone stream is untouched: unrelated notifications
|
||||
still arrive.
|
||||
|
||||
!!! check
|
||||
Do the wrong thing. `reserve` is the exact tool that just served both clients. Deploy it with
|
||||
`stateless_http=True`, connect the same two clients over HTTP, and call it from each.
|
||||
|
|
|
|||
Loading…
Reference in a new issue