MRTR (SEP-2322) gives tools/call two new inputs: request_state, the opaque continuation the
client echoes back, and input_responses, the client's answers to the previous round's
inputRequests. Both live on CallToolRequestParams.
A handler written with #[tool] cannot see either. ToolCallContext::new takes the params apart
and forwards only the arguments, so the macro-generated body has no access to the two fields that
make a multi-round call multi-round.
The consequence is that every MRTR server in Rust must hand-write ServerHandler::call_tool,
giving up the macro's routing, schema derivation, and argument extraction for the whole server —
not just for the tool that needs MRTR.
Why this is worth fixing
MRTR is not a niche extension. SEP-2322 routes all server-initiated interaction through it:
elicitation/create, sampling/createMessage, and roots/list no longer exist as
server-to-client requests. Any tool that needs to ask the user anything is an MRTR tool. The
ergonomic path in the SDK currently excludes the entire category.
Suggested fix
Extractors, in the style the SDK already uses for Extension:
#[tool(description = "book a trip")]
async fn book_trip(
&self,
Parameters(args): Parameters<BookTrip>,
RequestState(state): RequestState, // Option<String>
InputResponses(answers): InputResponses, // Option<BTreeMap<String, Value>>
) -> Result<CallToolResponse, ErrorData> { … }
That would need ToolCallContext to carry the two fields through rather than drop them, and a
return type of CallToolResponse rather than CallToolResult so a handler can answer
InputRequired.
A smaller first step that would unblock people: keep the fields on ToolCallContext and expose
them through an accessor, so a macro-based handler can reach them even if the extractor sugar
comes later.
MRTR (SEP-2322) gives
tools/calltwo new inputs:request_state, the opaque continuation theclient echoes back, and
input_responses, the client's answers to the previous round'sinputRequests. Both live onCallToolRequestParams.A handler written with
#[tool]cannot see either.ToolCallContext::newtakes the params apartand forwards only the arguments, so the macro-generated body has no access to the two fields that
make a multi-round call multi-round.
The consequence is that every MRTR server in Rust must hand-write
ServerHandler::call_tool,giving up the macro's routing, schema derivation, and argument extraction for the whole server —
not just for the tool that needs MRTR.
Why this is worth fixing
MRTR is not a niche extension. SEP-2322 routes all server-initiated interaction through it:
elicitation/create,sampling/createMessage, androots/listno longer exist asserver-to-client requests. Any tool that needs to ask the user anything is an MRTR tool. The
ergonomic path in the SDK currently excludes the entire category.
Suggested fix
Extractors, in the style the SDK already uses for
Extension:That would need
ToolCallContextto carry the two fields through rather than drop them, and areturn type of
CallToolResponserather thanCallToolResultso a handler can answerInputRequired.A smaller first step that would unblock people: keep the fields on
ToolCallContextand exposethem through an accessor, so a macro-based handler can reach them even if the extractor sugar
comes later.