These sections show the server-initiated flow, which the handshake-era protocol uses. On
2026-07-28 the server asks by returning a request instead — see input-required rounds. One elicitation_handler serves both, so the examples below pin mode="legacy" only to exercise the pushed form.Handler Template
How It Works
When a server needs user input, it sends an elicitation request with a message prompt. Form elicitation requests include a JSON schema describing the expected response structure, and FastMCP automatically converts that schema into a Python dataclass type. URL elicitation requests and empty-object schemas useresponse_type=None.
The handler receives four parameters:
Handler Parameters
str
The prompt message to display to the user
type | None
A Python dataclass type that FastMCP created from a form request’s JSON schema. Use this to construct your response with proper typing. For URL requests or empty-object schemas, this will be
None.ElicitRequestParams
The original MCP elicitation parameters. Form requests carry the raw JSON schema on
params.requested_schema; URL requests carry params.url instead and have no schema.RequestContext
Request context containing metadata about the elicitation request
Response Actions
You can return data directly, which implicitly accepts the elicitation:ElicitResult for explicit control over the action:
accept: User provided valid input. Include the data in thecontentfield.decline: User chose not to provide the requested information. Omitcontent.cancel: User cancelled the entire operation. Omitcontent.
Example
A file management tool might ask which directory to create:Input-required rounds
On protocol version2026-07-28 and later, a server can ask for input before it returns a final result. Nothing is held open: the tool returns a description of what it needs, which completes that round as an ordinary response, and the client answers by issuing a new call_tool, get_prompt, or read_resource request carrying the answer. fastmcp.Client drives that loop for you — it fulfils each round’s requests using the callbacks you already configured (your elicitation_handler, sampling_handler, and roots) and repeats until the call reaches a terminal result. No extra wiring is needed beyond the handlers described above.
The input_required_max_rounds parameter caps how many rounds the client will answer before giving up, guarding against a server that never terminates. It defaults to 10.

