elicitation
Elicitation is how an MCP server asks the user for more information through the client while it handles a request. Form mode collects simple structured data the client can see. URL mode sends the user to a web page, and is the one a server must use for secrets. The user can accept, decline or cancel.
What is MCP elicitation?
A tool sometimes needs something only the user knows: which account to use, a date, a confirmation. Elicitation lets the server ask partway through a request. The client shows the question, the user answers, and the work carries on [1].
A server can only ask a client that supports it. The client says so by declaring the elicitation capability, with form, url or both inside it. An empty elicitation object means form mode only.
Form mode or URL mode?
| Form mode | URL mode | |
|---|---|---|
| Use it for | Names, choices, dates, confirmations | API keys, payments, signing in to a third party |
| What the client sees | Everything the user types | Only the URL |
| Extra field | requestedSchema |
url |
Form schemas stay small on purpose. They are flat objects whose properties are strings, numbers, booleans or enums, which keeps the form simple for the person filling it in.
The line between the two modes is a hard rule. Servers "MUST NOT use form mode elicitation to request sensitive information such as passwords, API keys, access tokens, or payment credentials" [1]. Those go through URL mode, where the user types them into a page and they never pass through the client or the model.
URL mode is for what the server needs from somewhere else, such as a user's token for a third-party service. Signing the client in to your own server is MCP authorization, a separate flow.
What can the user answer?
Three things, and a server should handle each one differently [1]:
accept: the user submitted. In form mode the answers are incontent.decline: the user said no. Offer another way forward.cancel: the user closed it without choosing. Asking again later is reasonable.
In URL mode, accept means the user agreed to open the page. The work on that page may still be unfinished.
What changed in the 2026-07-28 revision?
Before it, a server sent elicitation/create to the client as its own request in the middle of a call. The 2026-07-28 revision replaced that with retries, and calls the change breaking: "The previous pattern of server-initiated requests is no longer supported" [2].
Now the server answers the original tools/call with an interim result, and the client retries once it has the answer:
{
"resultType": "input_required",
"inputRequests": {
"github_login": {
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "Please provide your GitHub username",
"requestedSchema": {
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
}
}
}
},
"requestState": "AEAD-protected blob"
}
The retry is a new request with a new id. It carries the user's answer in inputResponses under the same key, and echoes requestState back untouched. That blob passes through the client, so the server must treat it as attacker-controlled and protect its integrity when it affects authorization, resource access or business logic [2].
The same retry works on prompts/get and resources/read. The notifications/elicitation/complete message and the elicitationId field, both new in 2025-11-25, are gone [3]. The client declares its capabilities in _meta on each request instead of once in initialize.
Example
Our MCP connection test declares no client capabilities and never calls a tool, so a server has no reason or permission to elicit anything from it. A clean result from the test tells you the server answers and lists its tools. To try an elicitation flow, call the tool from a client that declares elicitation.