Support server-initiated requests (elicitation/sampling) over the streamable proxy
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 2.2k
- Forks
- 300
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 184
Description
Part of #5743. Follow-up surfaced by #5744 (PR #5934).
Gap
The thv run streamable HTTP proxy multiplexes N downstream client sessions onto one shared backend MCP connection (a single stdio pipe to the container). #5934 added correct, per-session routing for every server→client message that carries an attribution key the proxy can track:
*/list_changed→ all sessions (global)notifications/progress→ the originating request's stream (correlated by the client-chosen, proxy-rewrittenprogressToken)notifications/resources/updated→ only sessions subscribed to that URI
But server-INITIATED requests — elicitation/create and sampling/createMessage — arrive from the backend with a server-generated JSON-RPC id and no downstream-session attribution. Over a shared backend the proxy cannot know which client should answer, so #5934 securely refuses them (-32601 back to the backend so it unblocks) rather than mis-delivering. This is recorded as the sole accepted entry in test/conformance/expected-failures.yaml (tools-call-elicitation).
notifications/message (logging) is dropped for the same reason (unattributable content over a shared backend); its upstream level is still reconciled to the max verbosity across sessions.
Why a heuristic is not acceptable
Inferring the target from "only one tool-call is in flight" is racy (TOCTOU with concurrent sessions) and a wrong guess is a cross-session leak: one client could read or answer another client's elicitation/sampling prompt (content injection / prompt exfiltration). Forwarding must be attributable, not guessed.
Options (both require other work to land first)
- Per-session backend connections (the vMCP model). Give each downstream session its own connection to the backend so a server-initiated request is unambiguously attributable and the SDK correlates ids both ways — this is exactly why vMCP already forwards elicitation/sampling (#5875). For the streamable
thv runproxy this is a transport re-architecture (backend lifecycle per session, resource cost, teardown), not a small change. Covers the 2025-11-25 (Legacy) revision. - 2026-07-28 (Modern) / MRTR. The Modern revision removes server-initiated requests entirely (client pulls via MRTR), so the correlation problem disappears. Gated on the go-sdk v1.7 / Modern work (#5754, #5757). This is the cleaner long-term answer.
Acceptance
- Elicitation/sampling round-trip correctly through the streamable proxy without any cross-session delivery, under whichever model is chosen.
- Remove
tools-call-elicitationfromtest/conformance/expected-failures.yaml(it should then pass); wire per-session logging delivery at the same time (notifications/message).
Related
- #5744 / PR #5934 (the routing this builds on; baseline entry)
- #5759 (MRTR-based elicitation/sampling passthrough in vMCP — vMCP-specific; this issue is the shared-backend streamable-proxy counterpart)
- #5754, #5757 (go-sdk v1.7 / Modern-revision vocabulary)
Generated with Claude Code
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading PR #5934 and the streamable proxy routing it introduced, then inspect test/conformance/expected-failures.yaml and the tools-call-elicitation case. Compare the per-session vMCP work in #5759 with the Modern/MRTR dependencies in #5754 and #5757 before choosing an architecture. Done means elicitation and sampling round-trip without cross-session delivery, logging is delivered per session, and tools-call-elicitation is removed from the expected failures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, security, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100