Why a server cannot simply prompt

Everything about elicitation follows from one fact: an MCP server has no user interface. It may be a subprocess speaking over stdio or a remote service answering HTTP from a datacenter; whatever it writes goes to a log or a JSON-RPC frame, not to a screen. Nor does it have any trust relationship with the human — the person authorized a host application, which chose to connect to this server. The human’s attention belongs to the host.

Without a way to ask, a server hitting a missing value has three bad options. It can fail, turning a recoverable gap into an error the model must interpret. It can guess, which is how tools delete the wrong record. Or it can demand the value up front as configuration, forcing it to hold information it has no business storing. Elicitation exists because all three are worse than asking.

Advertisement

The inversion, and where it is not sampling

MCP’s usual direction of travel is client-to-server: the host’s client calls tools/call, the server answers. Elicitation reverses it: mid-request, the server issues a request to the client and waits, suspending the original call inside its own handler. MCP has two such inversions and they are easy to confuse: sampling asks the host to run a model completion on the server’s behalf, while elicitation asks the host to obtain input from the human. That is the whole boundary; the rest of this article stays on the human side.

The request carries two things: a message explaining what is needed and why, and a schema describing the shape of an acceptable answer. The message is what the user reads; the schema is what the host renders and what the server may assume about whatever comes back.

Advertisement

The schema is a constraint, not a hint

The schema reads like documentation but works like a fence. Current revisions deliberately restrict elicitation schemas to a flat object of primitive fields — strings, numbers, booleans and enumerated choices, with titles and descriptions for display — rather than the full generality of JSON Schema. No nesting, no arrays of objects, no arbitrary composition.

That restriction is doing real work. It guarantees a host can mechanically render any valid request as an ordinary form: a checkbox for a boolean, a dropdown for an enumeration, a labelled field for a string — without interpreting a schema language it did not expect. And a server cannot smuggle a data-extraction interrogation into what the user reads as a simple question. The schema also validates: what the user submits is checked against it before it reaches the server, which therefore receives typed values rather than free text to parse.

The host as mediator

The host is not a pass-through; it is where every guarantee lives. It attributes the request — the user must see which named server is asking, not a floating dialog that could have come from the application itself. It renders the request in its own chrome, so a server cannot forge the look of a system prompt or a login screen. And it enforces policy: a host may cap how often a server asks, suppress a muted server, or reject a request without ever showing it, answering on the user’s behalf.

This is the trust posture the protocol takes everywhere — the server proposes, the host disposes — and it is why elicitation can be offered to servers of unknown provenance at all. A server can request; it cannot compel, cannot see what it was not given, and cannot tell a human’s refusal from a policy’s.

MCP elicitation — servers requesting input from usersstructured prompts mid-operation, safelyServer needs inputmissing parameter, confirmationElicitation requestschema + promptClient mediatespresents to userUser respondsstructured inputSchema validationtyped responsesUser controlapprove, decline, cancelTrust boundaryserver can't forcevs samplinginput vs generationUse casesconfig, confirmation, disambiguationSecurityno sensitive-data coercionOps — schema design + UX + consent flowsvalidatecontrolboundcompareapplysecuredesignoperateoperate
Elicitation: a server requests structured input via a schema; the host mediates, presenting it to the user who controls whether and how to respond.

Three outcomes: accept, decline, cancel

A server that treats elicitation as a function returning a value has already misunderstood it. There are three outcomes, kept distinct on purpose.

OutcomeWhat the user didWhat it means
AcceptFilled the form and submittedYou get schema-valid content; proceed
DeclineExplicitly refused this requestA deliberate “no” — do not re-ask
CancelDismissed without decidingNo answer at all — intent unknown

The difference between the last two is the one teams collapse and then regret. Decline is information: the user considered the question and said no, so a well-behaved server records that and stops asking. Cancel is the absence of information — the dialog dismissed, the window closed, the user gone. Treating cancel as “no” silently converts an interruption into a decision; treating decline as cancel produces a server that asks the same question forever. And accept only promises the fields were supplied and valid, not that the values are right.

Handling all three in the tool that asked

The elicitation sits inside a suspended tool call, so each outcome must become a tool result. The common anti-pattern is letting anything other than accept raise, so a user politely declining produces a stack trace and a protocol-level failure. That is wrong on both counts: a declined confirmation is a successful execution of a tool whose correct behaviour was to do nothing.

Return it as a normal tool result whose content says so — “deployment not performed; the user declined confirmation” — not as an error. The model reads that sentence and can explain it, instead of retrying a call it thinks crashed. Reserve the error channel for elicitation that actually broke, and never loop to re-ask on decline; a server that pesters until the user gives in is the coercion this design exists to prevent.

What must never be elicited

There is a hard line, and it is credentials. Passwords, API keys, one-time codes, card numbers: a server must never ask for them through elicitation, and a host should treat a request fishing for them as hostile. The reason is precisely the mechanism’s strength: elicitation renders inside the interface the user already trusts, so a request for a password arrives wearing the host’s clothes — a confused-deputy setup, borrowing the host’s credibility to make a third party’s phishing prompt look official.

Legitimate secrets have their own path: an authorization flow the user completes with the identity provider directly, or configuration the host holds and the server never sees. A mid-tool prompt improves on neither. So: servers should elicit only choices, confirmations and non-secret values; hosts should scan messages and field metadata for credential-shaped asks, warn loudly, and offer a one-click way to cut that server off.