SKIP TO CONTENT
AI AGENTS6 minAgents in Production / Ep. 11 · Stage 11-2

MCP Without Sessions: How a Server Asks the User Mid-Call

Your tool needs the user’s answer mid-call, and the retry may land on another server instance. How does it pick up where it stopped?

XIN
Pixel-art night scene of a row of identical server cabinets with no luggage beside them. Each glowing envelope arriving on a conveyor carries its own small backpack, and a teal lockbox key hangs from one envelope.

IN 30 SECONDS

Multi Round-Trip Requests (MRTR) is the 2026-07-28 way for an MCP server to ask the user something mid-call: it returns input_required, and the client retries with the answers. Its half-done work can travel in a sealed requestState, checked on every retry.

KEY TAKEAWAYS · 3

  • MRTR replaces the elicitation and sampling requests a server used to send: the server returns input_required, and the client retries.
  • requestState passes through the client, so the spec says to treat it as attacker-controlled and to protect it, for example with HMAC or AEAD, when it affects authorization or business logic.
  • Binding it to the principal, a short expiry and the request bounds replay. Single use needs a server-side check.
On this page

Asking the user mid-call, step by step

IN SHORT With MRTR, the server can hand its half-done work back to the client in an optional requestState, so the retry can land on any instance.

Anything marked as a proposal is my opinion, not the standard. Checks on the caller assume an HTTP server that authenticates each call. The spec makes authorization optional.

WORDS TO KNOW

Elicitation
The server asking the user for input in the middle of a tool call.
requestState
An optional, opaque token the server returns when it needs input. The client sends it back unchanged when it retries.
Principal
The user or service a request acts for, shown by its access token.

Elicitation The server asking the user for input in the middle of a tool call. See the glossary used to be a request the server sent on an open stream. So the same process had to be alive when the answer came back. Sampling, where the server asks a model through the client, worked the same way.

The Multi Round-Trip Requests pattern (MRTR) replaces both. Its stated goal is to work

“without requiring a shared storage layer across server instances or requiring stateful load balancing.”

MCP specification 2026-07-28, MRTR

ONE CALL, TWO INSTANCES

Sequence diagram: 4 participants: AI app, Load balancer, Instance A, Instance BSequence diagram: 4 participants: AI app, Load balancer, Instance A, Instance B. Step 1: AI app to Load balancer, Call a tool (id 1). Step 2: Load balancer to Instance A, Send to any healthy instance. Step 3: Instance A to AI app, Need input: a question and sealed state. Step 4: AI app to itself, Ask the user, collect the answers. Step 5: AI app to Load balancer, Retry (id 2): answers and the same state. Step 6: Load balancer to Instance B, Lands on another instance. Step 7: Instance B to itself, Check the seal, caller, expiry and request. Step 8: Instance B to AI app, Done: the result. Step 9: Load balancer to Instance B, A retry with edited state.AI APP > LOAD BALANCERCall a tool (id 1)LOAD BALANCER > INSTANCE ASend to any healthy instanceINSTANCE A > AI APPNeed input: a question andsealed stateA keeps nothingAI APP > AI APPAsk the user, collect theanswersAI APP > LOAD BALANCERRetry (id 2): answers and thesame stateLOAD BALANCER > INSTANCE BLands on another instanceINSTANCE B > INSTANCE BCheck the seal, caller, expiryand requestINSTANCE B > AI APPDone: the resultLOAD BALANCER > INSTANCE BA retry with edited state

Step 1. First call. The app calls a tool with id 1. The load balancer picks instance A.

Pick a step to see it move
  1. First call The app calls a tool with id 1. The load balancer picks instance A.
  2. Ask for input A answers input_required, with a question and a sealed requestState. Then it forgets the call.
  3. Ask the user The app asks the user and collects the answers, called inputResponses.
  4. Retry The app sends the same call with a new id (2), the answers and the exact requestState. It lands on B.
  5. Verify, then answer B checks the seal, the caller, the expiry and the original call, then returns the result with resultType complete.
  6. Edited: refused A retry whose requestState was edited fails the seal check. B rejects it and runs nothing.
The retry lands on another instance, which resumes from what the request carries. The last step shows a refusal.

The retry gets a new id, so the id can’t link it to the first call. The fingerprint of the original call, sealed inside the state, does that job.

Sampling is also Deprecated in 2026-07-28, along with Roots and Logging, with a window of at least 12 months. They still work, but new implementations shouldn’t add them.

Why the server checks the sealed state

IN SHORT Because requestState passes through the client, servers “MUST treat requestState as an attacker-controlled input.”

WHAT THE SERVER CHECKS ON A RETRY
Flow diagram: 5 stepsFlow diagram: 5 steps. Seal intact?, then Same caller?. Same caller?, then Not expired?. Not expired?, then Same request?. Same request?, then Resume the call.1Seal intact?Nobody edited it on the way2Same caller?The sealed caller matches theaccess token3Not expired?The short expiry hasn’tpassed4Same request?The sealed fingerprintmatches the call beingretried5Resume the call
The three bindings are what the spec recommends. The order is my proposal. Any failed check rejects the state.

If the state “influences authorization, resource access, or business logic”, the server must protect it from tampering, for example with HMAC or AEAD.

IN PLAIN WORDS

HMAC is a keyed seal that reveals tampering. AEAD is encryption that also detects it.

ADAM says: A seal isn’t a secret: with HMAC alone, the client may still read what’s inside. If the client must not read it, use AEAD.

To limit replay (the same state sent again), the spec says servers should seal three things inside it: the authenticated Principal The user or service a request acts for, shown by its access token. See the glossary, a short expiry, and an id for the original request.

ITEM GET

Treat it as hostile input

requestState comes back through the client, so the server verifies it before trusting any of it.

Those bindings bound replay, but they don’t make the state single-use. A one-time use needs a check on the server side.

SealedState (my sketch, not in the spec)
substring

The principal, from the access token

expnumber

The expiry. Keep it short

reqstring

Method, tool name and a digest of the original arguments

dataunknown

Whatever the server needs to resume

The tool name matters: every tool shares the method tools/call. Hash a canonical JSON encoding of the arguments, so key order can’t change the digest.

Sources: MRTR, changelog, both read on 7 October 2026.

FAQ

HMAC gives integrity, not secrecy: if the payload is only base64-encoded, the client can decode it. If the state holds anything the client shouldn’t read, use AEAD. My advice either way: rotate the key on a schedule with an overlap window, since every instance must check what another one sealed.

STAGE CLEAR

What you now know

  • How MRTR lets any instance finish a call that needed the user’s input.
  • Why the server verifies the returned state before trusting any of it.

Check yourself

Tap or click a question to see the answer.

The same user’s client sends one valid requestState twice, unchanged, before it expires. Does the seal stop the second retry?

Not by itself. The seal proves nobody edited it, and the expiry limits the window. Stopping a second use needs the server to record that the state was used.

Next stage:Where does work that must outlive one call go, and how does a server avoid writing it twice?5 min
Adam Boudjemaa
Adam Boudjemaa

Former CTO of Integra. Named author (1 of 5) of ERC-3643, first author of ERC-6960, co-author of ERC-7410, and co-author of ERC-8203, which is still a draft. Building production AI and regulated Web3 systems.

Have a project to ship or a role to fill?

Discuss your project or role
Follow the engineering notes

Get new articles on production AI and smart contracts by email.