diff --git a/docs/servers/elicitation.mdx b/docs/servers/elicitation.mdx index 9b7b0c164..76bfea4d3 100644 --- a/docs/servers/elicitation.mdx +++ b/docs/servers/elicitation.mdx @@ -541,6 +541,59 @@ on handshake-era connections. If you need to support both eras, branch on `ctx.protocol_version`: return an `InputRequiredResult` on modern connections and fall back to [`ctx.elicit()`](#requesting-input-on-handshake-connections) on handshake-era ones. +### Prompts and resources + +`InputRequiredResult` is a **result type**, not a tools feature: any request can resolve to one. Prompts, resources, and resource templates ask for input exactly the way tools do — return an `InputRequiredResult`, read `ctx.input_responses` on the next round, and the client re-issues the same `prompts/get` or `resources/read` with the answer attached. + +This prompt gathers the context it needs before rendering: + +```python +from fastmcp import FastMCP, Context +from mcp_types import InputRequiredResult, ElicitRequest, ElicitRequestFormParams + +mcp = FastMCP("Reporting Server") + +ask_for_quarter = InputRequiredResult( + result_type="input_required", + input_requests={ + "quarter": ElicitRequest( + method="elicitation/create", + params=ElicitRequestFormParams( + message="Which quarter should the summary cover?", + requested_schema={ + "type": "object", + "properties": {"quarter": {"type": "string"}}, + "required": ["quarter"], + }, + ), + ) + }, +) + + +@mcp.prompt +async def summarize(ctx: Context) -> str | InputRequiredResult: + responses = ctx.input_responses + if responses is None: + return ask_for_quarter + quarter = responses["quarter"].content["quarter"] + return f"Summarize the {quarter} results." +``` + +Resources and resource templates work the same way, with the URI standing in for the tool name: + +```python +@mcp.resource("report://summary") +async def report(ctx: Context) -> str | InputRequiredResult: + responses = ctx.input_responses + if responses is None: + return ask_for_quarter + quarter = responses["quarter"].content["quarter"] + return f"Revenue report for {quarter}" +``` + +The same protocol requirement applies: returning an `InputRequiredResult` from a prompt or resource needs a 2026-07-28 connection, and FastMCP names the era mismatch if one arrives on an older one. Client-side, `read_resource` and `get_prompt` drive the loop the way `call_tool` does, so a configured elicitation handler answers all three without extra wiring. + ### Sampling and roots Elicitation is the most common request to carry this way, and **roots** requests work identically — the `input_requests` map holds them the same way, and each answer comes back in `ctx.input_responses` under its key (an `ElicitResult` or `ListRootsResult`). See [Client Roots](/clients/roots) for what a roots request contains. `fastmcp.Client` answers both from the handlers you already configured, so a guard tool that mixes them needs no extra client wiring. diff --git a/docs/servers/prompts.mdx b/docs/servers/prompts.mdx index 4e824dec0..ae7172522 100644 --- a/docs/servers/prompts.mdx +++ b/docs/servers/prompts.mdx @@ -438,6 +438,10 @@ Notifications are only sent when these operations occur within an active MCP req Clients can handle these notifications using a [message handler](/clients/notifications) to automatically refresh their prompt lists or update their interfaces. +## Requesting Input + +A prompt can ask the client for information before it renders. On an MCP 2026-07-28 connection, return an `InputRequiredResult` describing what you need; the client answers and re-issues the `prompts/get`, and your function runs again with the answer on `ctx.input_responses`. See [Elicitation](/servers/elicitation#prompts-and-resources) for the full pattern. + ## Server Behavior ### Duplicate Prompts diff --git a/docs/servers/resources.mdx b/docs/servers/resources.mdx index 7f45c7280..e0daf6e76 100644 --- a/docs/servers/resources.mdx +++ b/docs/servers/resources.mdx @@ -783,6 +783,10 @@ def get_data_by_id(id: str) -> dict: When `mask_error_details=True`, only error messages from `ResourceError` will include details, other exceptions will be converted to a generic message. +## Requesting Input + +A resource or resource template can ask the client for information before it produces content. On an MCP 2026-07-28 connection, return an `InputRequiredResult` describing what you need; the client answers and re-issues the `resources/read`, and your function runs again with the answer on `ctx.input_responses`. See [Elicitation](/servers/elicitation#prompts-and-resources) for the full pattern. + ## Server Behavior ### Duplicate Resources