You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For url-mode elicitation under MRTR, the spec notes that a round-2 retry "may need to block until the request is fulfilled," but it does not define a bounded, non-blocking idiom for "not done yet," nor a timeout/cancel verb.
Problem
A server that brokers an out-of-band flow (OAuth consent, credential entry, payment, external approval) often should not hold the round-2 request open until the user finishes — that ties up a connection for an unbounded time and doesn't compose with stateless/HTTP deployments. The server needs a sanctioned way to answer a premature retry with "still waiting, try again."
Server Requirement #6 already permits returning an InputRequiredResult with the same requestState and no new inputRequests, which is the natural "still waiting" signal. But it is not named or recommended as the idiom, so:
implementers don't know it's the blessed pattern (vs. blocking, vs. an error),
there's no guidance on client retry/backoff bounds, so clients either hammer or give up,
there's no standard cancel verb for the user abandoning the out-of-band flow.
Request
Explicitly bless the state-only InputRequiredResult (same requestState, empty/absent inputRequests) as the canonical "still waiting" response for an in-progress out-of-band interaction.
Add client guidance on retry cadence / backoff bounds for that response (and clarify whether notifications/elicitation/complete is the preferred wake signal vs. polling).
Specify a cancel/abandon path (verb or inputResponses action) for when the user dismisses the out-of-band flow, so the server can release requestState deterministically rather than relying on TTL.
Context
Implemented the host side of MRTR url-mode and hit exactly this ambiguity: the state-only-refresh response works, but whether it's the intended idiom, how aggressively to retry, and how to signal cancellation are all left to implementer guesswork.
I think #2919 helps sharpen the lifecycle question here: "still waiting" is transport/progress state; it should not itself imply anything about the authorization/decision outcome.
For an out-of-band approval flow, I would make that distinction testable with a small set of conformance cases:
Pending retry preserves identity — a state-only InputRequiredResult keeps the same requestState and does not synthesize a new tools/call.
Cancel is terminal for that continuation — after the client abandons/cancels the flow, the suspended operation cannot later resume because an approval arrives late.
Expiry is not a human answer — timeout/expiry should terminate or transition the lifecycle explicitly; it should not be encoded as a successful input response.
Completion resumes at most once — if a completion notification races with a poll/retry, the original suspended operation must not execute twice.
Pending has no execution side effect — repeated "still waiting" polls cannot reach the tool handler.
The last two seem especially important for state-changing tools: otherwise a perfectly reasonable polling/wakeup implementation can accidentally turn a lifecycle ambiguity into duplicate execution.
This also keeps the layering clean: #2919 can make namespaced request/response types extensible for things that are not approvals (e.g. host resource reads), while this issue can define the generic MRTR waiting/cancel behavior that any long-running out-of-band interaction needs.
If the intended semantics already guarantee terminal cancellation and at-most-once resume, documenting those as explicit invariants/tests would remove a lot of implementation guesswork.
Activity
hippoley commentedon Oct 3, 2026
I think #2919 helps sharpen the lifecycle question here: "still waiting" is transport/progress state; it should not itself imply anything about the authorization/decision outcome.
For an out-of-band approval flow, I would make that distinction testable with a small set of conformance cases:
InputRequiredResultkeeps the samerequestStateand does not synthesize a newtools/call.The last two seem especially important for state-changing tools: otherwise a perfectly reasonable polling/wakeup implementation can accidentally turn a lifecycle ambiguity into duplicate execution.
This also keeps the layering clean: #2919 can make namespaced request/response types extensible for things that are not approvals (e.g. host resource reads), while this issue can define the generic MRTR waiting/cancel behavior that any long-running out-of-band interaction needs.
If the intended semantics already guarantee terminal cancellation and at-most-once resume, documenting those as explicit invariants/tests would remove a lot of implementation guesswork.