Good catch Mihai_LeanZero . I went back through the MRTR spec, and it doesn't give you a built-in idempotency key for this.
The spec does give you replay protection around requestState: bind it to the authenticated principal, give it a short TTL, and tie it to the originating request. But it explicitly says that still doesn't guarantee single use. If you need exactly-once behavior, the server has to enforce that itself.
There's another edge case too: the client isn't required to retry after input_required. So if the first pass already reserves something or calls a paid API, you can end up with either a duplicate on retry or an orphan if the retry never happens.
I'd keep the first pass side-effect free where possible. If that's not possible, create a short-lived reservation/idempotency ID, carry it through requestState, and have the retry reconcile against that reservation instead of performing the action again.
And yeah, idempotentHint doesn't solve this. It's useful metadata, but it's still only a hint, not an enforcement mechanism.
The MRTR mechanic is the part I'd want a strong opinion on before wiring anything real behind it. If the server already did something before returning input_required -- reserved a slot, hit a paid API, written a provisional record -- then retrying the whole request with a new ID after the client gathers input means the server has to treat "reconstitute from requestState" as authoritative for what already happened, not just for what's still needed. That's fine when the tool is stateless up to the input gate, but it looks like a real footgun for anything where the first pass causes a side effect before it can know it needs input. Does the spec say anything about idempotency keys for that case, or is it left entirely to the tool author?