When should an MCP tool elicit input mid-call rather than declare the argument up front?
answer
- Two sources for a value, very different costs
- Free by default, expensive by exception
- Consent cannot be model-supplied
- Ambiguity that did not exist before the call
- Some clients have no human at all
basics
~20 sElicit only for values that are genuinely the user's to give — consent for a risky action, or a choice the server discovers mid-call. Anything the model can supply from context belongs in the tool's input schema, which costs no round trip and no interruption.
solid answer
~50 sThe default is to declare the argument in the tool's `inputSchema`: the model fills it from context, the call completes in one round trip, and the tool works in clients that never show a human anything. Elicitation is the exception, and it earns its cost in three cases — the value is a **decision** only the user may make (confirming something destructive, authorising data exposure), the value only becomes knowable **during** the call (the server discovers the user has three matching accounts and cannot guess which), or the value must not pass through the model at all. The costs are real: an extra round trip, work the server must be able to resume from, an interruption the user may decline or dismiss, and total unusability in a client that does not declare the elicitation capability. When you do ask, ask once — batch every field you need into a single form rather than three sequential prompts.
go deeper
Know that most arguments belong in the tool's input schema and that elicitation is for asking the person something, not for collecting anything the model could provide.
Explain the concrete costs — an extra round trip, work the server must resume, a capability the client may not have — and name the cases that justify them.
Show how you design for the answer never arriving: reserve nothing you cannot abandon, never half-apply a change before asking, and keep the tool usable in a headless client.
Own elicitation as an interrupt budget across the fleet: measure decline and dismissal rates as product signals, forbid consent flags the model can set itself, and require every tool to degrade legibly where no human is present.
## Two places an argument can come from Every MCP tool declares an `inputSchema`, which is unrestricted JSON Schema and is filled by the model from the conversation before the call is made. Separately, a server handling a `tools/call` may raise an elicitation and ask the human directly. Choosing between them is a design decision made once per tool and lived with by everyone who uses it. The defaults are not symmetric. `inputSchema` is nearly free: no extra round trip, no interruption, no capability requirement, and the model already has the conversation that usually contains the answer. Elicitation costs something every single time it fires. So the burden of proof sits on elicitation. ## What elicitation actually costs **A round trip and a resumption.** In revision 2026-07-28 there are no server-initiated requests: the server returns an interim result, releases the request, and can only continue if the client chooses to re-issue it. That means the work has to be structured so it can be picked up again from whatever the server stashed — not a callback that suspends mid-function. **A human in the loop.** Somebody must be present, paying attention, and willing. They may decline, they may dismiss it, they may never come back. Every one of those outcomes has to leave your tool in a defensible state. **A capability that may not exist.** The client declares `elicitation` per request. A client that does not declare it cannot be asked, and in 2026-07-28 you cannot fall back on a remembered declaration from a previous request — the protocol is stateless and capabilities arrive with each one. A tool that always elicits is simply unusable in a batch runner, a CI agent, or any headless client. **Attention, which is finite.** Prompt fatigue is real. A server that interrupts on every third call trains users to click accept without reading, which destroys the value of the prompts that actually matter. ## When elicitation is right **Consent for consequence.** Deleting a production table, sending a message on the user's behalf, spending money. Here the *point* is that a human decides, and a model-supplied `confirm: true` field in the input schema is theatre — the model can set it to true. The decision has to come from the person. **Information that appears mid-call.** The server queries and finds the user has three accounts named similarly, or two branches match the description. Nothing in the conversation before the call could have disambiguated it, because the ambiguity did not exist yet. This is the cleanest case for elicitation. **Values that must not touch the model.** Anything the model should not see or repeat. Note that outright secrets are further constrained: form-mode elicitation must not request sensitive information at all, and URL mode is the route for those. ## When it is wrong **Anything the conversation already contains.** If the user just said which repository they meant, do not ask them again. Declare it as a parameter and let the model fill it. **Compensating for a vague schema.** A tool whose parameters are under-described will be called with bad arguments, and eliciting the missing ones papers over the real fix — better descriptions, tighter enums, sensible defaults. **Multi-step wizards.** Three sequential elicitations is three round trips and three chances for the user to walk away. If you need five fields, ask for five fields in one flat form. **Configuration.** Directories, endpoints, credentials for the server's own upstream — these belong in how the server is configured or authorized, not in a question asked of whoever happens to be using it today. ## Designing for the answer never arriving Because declining is expressed by simply not coming back, "no answer" is a normal outcome rather than an error path. Whatever you reserved before asking must be safe to abandon, whatever you stashed to resume with must expire on its own, and nothing must be half-applied while you wait. A tool that mutates state and *then* asks for confirmation has the order backwards. ## The organisational view Across a fleet of servers, treat elicitation like any other interrupt budget. Track how often each ask fires, how often it is declined and how often it is dismissed — a high dismissal rate means the ask is confusing or badly timed, and a high decline rate means users understand it and do not want the operation. Both are product signals. And keep a rule that a tool must remain useful, or fail cleanly and legibly, in a client with no elicitation capability at all; otherwise your server quietly excludes every headless integration. ## Version note This assumes revision 2026-07-28: no server-initiated requests, per-request capability declaration, and a stateless protocol in which the server cannot rely on anything the client said on an earlier request.
- A tool takes a confirm boolean in its input schema. Why is that not the same as eliciting confirmation?Because the model fills the input schema. A `confirm: true` parameter is set by the same component that decided to make the call, so it confirms nothing — it is the caller agreeing with itself. Elicitation puts the decision in front of the person who bears the consequence, which is the entire point when the action is destructive or spends money.
- How should a tool behave in a client that does not declare the elicitation capability?Either complete without asking, or fail cleanly with a result saying which capability is missing and what the user can do about it. What it must not do is proceed on an assumption it would otherwise have confirmed. Capabilities arrive on every request in revision 2026-07-28, so this is a per-call check, not something established once at connection time.
- Your server needs five values from the user. Why prefer one elicitation over five?Each ask is a full round trip, a fresh interruption, and another chance for the user to dismiss it and abandon the operation halfway. A single flat form carries all five fields at once, the user sees the whole cost of the request before answering, and the server resumes exactly once. Sequential asks are only justified when a later question genuinely depends on an earlier answer.
saying these in an interview costs you the question
- Elicits values the conversation already contained
- Adds a model-filled confirm flag and calls it consent
- Uses sequential elicitations as a multi-step wizard
- Assumes a human is always present to answer
- Mutates state before asking for confirmation