What is ElicitResult?
ElicitResult is the response envelope returned by the MCP client after a server calls the elicitation primitive. It represents the complete outcome of surfacing a structured data-collection dialog to the end user — not just the data itself, but the user's intent expressed through one of three discrete actions: accept, decline, or cancel. This three-way model is intentional: it distinguishes a user who actively refuses a request (decline) from one who simply closes the dialog without engaging (cancel), giving servers the ability to handle ambiguous dismissal differently from an explicit opt-out.\n\nIn the MCP message flow, ElicitResult travels from client to server as the response to a sampling/elicit request. The server initiates elicitation when it needs information from the human in the loop that cannot be inferred from context — credentials, a confirmation, a free-text description. The client renders appropriate UI, collects input, and wraps the outcome in this type before returning control. The content field is only populated on the accept path and only when the elicitation was in form mode; its shape is guaranteed to conform to the requestedSchema the server provided in the original request.\n\nElicitResult was introduced alongside the broader elicitation capability in the 2025-03-26 revision of the MCP specification. It pairs with ElicitRequest as a strict request/response pair. Servers must always branch on action before reading content — reading content without checking for accept first is a common source of null-reference errors because content is omitted entirely (not set to null) on decline and cancel responses.
When to use
Always — every elicitation/create reply.
When NOT to use
Don't treat absent content as accept — check the action.
Notes
Check action before touching content
The content field is absent on decline and cancel — it is not present as null, it is simply not serialized. Any server-side code that accesses result.content without first asserting result.action === 'accept' will throw or produce undefined behavior. Always guard with an explicit equality check before destructuring the content object.
Decline vs cancel carry different semantics
decline signals the user saw the request and consciously chose not to provide the data. cancel signals dismissal — closing the dialog, pressing Escape, or a timeout. Servers should use this distinction to decide whether to retry: cancels may warrant a single retry with context, while declines should be treated as a hard stop to avoid pestering the user.
content must match requestedSchema exactly
The MCP spec requires the client to validate content against the requestedSchema before constructing ElicitResult. In practice, SDK implementations vary: some clients validate strictly and reject malformed submissions, others pass through whatever the user typed. Servers should run their own validation against requestedSchema on receipt rather than trusting the client to have enforced the schema.
No partial-accept path exists
ElicitResult has no concept of a partial response — the user either submits all required fields (accept) or does not (decline/cancel). If a server needs optional sub-fields, those must be modeled as optional properties inside requestedSchema and collected in a single round-trip. Chaining multiple elicitation requests is the only way to collect data incrementally.
Security: treat content as untrusted input
Because content originates from user input rendered by the client, it must be treated as untrusted data on the server side regardless of schema conformance. Apply the same sanitization and authorization checks you would apply to any user-supplied payload — especially if content values are used to construct file paths, queries, or shell commands.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| action | 'accept' | 'decline' | 'cancel' | yes | User's choice. |
| content | object? | no | Submitted data (form mode + accept). |
Examples
User accepted
{ "action": "accept", "content": { "confirm": true } }
User cancelled
{ "action": "cancel" }
Common mistakes
❌ Reading content without checking action
✅ If action !== 'accept', content is undefined.