Part 4 of 6 · 6 min read
Sampling, and why it is being retired
Covers: Sampling, and why it is being retired; Who is the control; A checklist.
Sampling, and why it is being retired
A sampling request carries messages, optional modelPreferences (name hints plus cost, speed and intelligence priorities), a systemPrompt (which the client may modify or ignore), maxTokens (required, and the client must respect it), and optionally temperature, stopSequences and metadata (which the client may ignore), tools and toolChoice. The reply carries role, content, model and a stopReason (end of turn, stop sequence, max tokens, or tool use). The specification says there should always be a human in the loop who can deny, review and edit the request and review the response.
The host's side is where the controls live, and the example host shows each of them with a greedy server that asks for 100,000 tokens, 50 times, with everyone's context:
| Control | Result in the example |
|---|---|
Client never declared sampling.context |
server's includeContext request never sent; 0 model calls |
| Cap on tokens per call | the model saw at most 30 instead of 100,000 |
| Limit on calls | stopped after 5 calls with "too many sampling requests" |
| Token budget | 45 tokens spent against a budget of 60 |
| Leave the shared context out | secret in the host's history leaked: false |
A host that honours includeContext |
secret leaked: true |
| Person denies the request | 0 model calls; the call is abandoned |
| Person edits the prompt | the reply reflected the edit (Lisbon became Porto) |
includeContext (the request to include other servers' context) is itself deprecated, for the reason the last two rows show: it lets a server read what it was never shown.
Tool use inside sampling
A sampling request can offer the host's model tools, and the server runs the loop: model asks for a tool, server runs it, server sends the result back, repeat. The page's rules are precise and the example checks them with a small validator: every tool_use must be matched by a tool_result with the same id, all results must be in one user message that contains only results, and there should be an iteration limit. The validator accepted the correct shape and rejected a missing result, results mixed with other text, and a tool use with no result at all. In the example's weather tool, two cities took 2 model calls and 3 client rounds. The tool also carries a round limit of its own (three), which this run did not reach.
Warning: dates
The page I read says sampling is deprecated as of 2026-07-28, with the earliest removal on or after 2027-07-28, and that servers should integrate with a model provider directly. I teach it because servers and clients written to the earlier revisions still use it, and because the controls above apply to any case where a server drives your model. Do not build a new server on it.
Who is the control?
A server that asks "are you sure?" is polite. It is not a control, because the server's author decides whether to ask, and a careless or hostile author simply does not.
In the example, the same 5000 "gift" expense was submitted by submit_expense (which asks) and submit_expense_quick (which does not). Without a host gateway, the polite tool asked 1 question and the quick one asked 0 and both submitted. Behind a host gateway that asks the person before running any tool not marked read-only, both submitted 0: the person declined, and nothing the server wrote could change that.
Use the server's own questions as a convenience (they carry exactly the details of the action) and the host's approval as the rule.
Tip: ask with the details, approve with the policy
Make the server's question specific ("Submit 250 for dinner?") so a person can answer well. Make the host's rule general ("any write needs approval") so it cannot be avoided by a server that forgets to ask.
A checklist
- Ask first, act last. Nothing irreversible before your final question; the body runs again each round.
- Seal the state. Sign it (or encrypt it), bind it to the person and the request, give it a short life, and never put a secret in a signed-only token.
- Enforce one-time actions on the server. A valid token can be replayed until it expires.
- Check capabilities before asking, and return a message for the model, not a crash, when the client cannot.
- Treat accept, decline and cancel differently, and write error text that says what happened and what to do.
- Never ask for a secret in a form. Use URL mode, and keep third-party tokens on the server.
- Bind a URL flow to the user who started it. Check the identity of the person who completes it.
- Limit your own loops. Rounds, tool iterations, tokens. The client should limit them too.
- As a host, cap tokens, count calls, review requests, and leave other servers' context out.
- Put the real approval in the host. A server's question is not a control.
- Do not build new servers on sampling or roots. Plan for their removal, and support the earlier revision only as long as you have clients that need it.
Interview angle
"How does a server ask the user something in the middle of a tool call?" A strong answer names the mechanism and its history: in the earlier revisions the server sent a request on the open connection; in the current one the call returns input_required with the questions and an opaque requestState, and the client retries the same call with the answers. Then give the consequences: the tool body runs again, so side effects go after the last question; the state passes through the client, so it must be signed, bound to the user and request, and expire, and one-time actions need a server-side record; the change makes servers stateless and balancer-friendly.
Follow-up: "What can go wrong with URL elicitation?" The wrong person opens the link; the server must check that the user who completes the flow is the user who started it. And "Is a confirmation prompt from the server a security control?" No. The server decides whether to ask. The control is a host-side approval and least privilege; this connects to the level's second question, on securing an MCP server that exposes internal data, which module 5 answers in full. A weak answer says "MCP lets servers prompt users" and stops, or describes sampling as current without saying it is deprecated.
Check yourself
A tool asks the person "Delete the project? yes/no" halfway through, after it has already archived the files. What is wrong with the order? (The tool body runs again on retry, so everything before the last question must be harmless to repeat. Ask first, act after the last answer.)
For the curious Why requestState is untrusted
The client carries the state between rounds, so the person, or anything on the client, can change it. Seal it, bind it to the person and request, expire it, and keep a server-side record for one-time actions. Sampling is described as being retired, so this module treats it as legacy and shows the controls a host should keep if it still supports it.
What you will use daily at work
| Practice | What it looks like |
|---|---|
| Ask before acting | Collect all answers, then do the irreversible step once. |
| Form mode for plain questions | Dates, choices, confirmations. |
| URL mode for secrets | Passwords and API keys go through the provider page, never a form. |
Draft: confirm which of these request types your client supports.