MCP form vs URL elicitation: how to request user data safely
A practical choice between form and URL elicitation in MCP: capability negotiation, sensitive data, third-party OAuth, completion, phishing controls, testing, and rollout.
Article contents
- 01Short answer: forms collect non-secret fields; URLs isolate sensitive interactions
- 02Capability negotiation determines the available UX before the first request
- 03Form mode needs a minimal schema, preview, and validation on both sides
- 04URL mode separates consent to navigate from completion of the external flow
- 05Third-party authorization must not be confused with MCP client authorization
- 06The test matrix validates privacy, association, and recovery
- 07Rollout starts with a read-only form and one allowlisted URL flow
Short answer: forms collect non-secret fields; URLs isolate sensitive interactions
Use form mode for a small set of non-secret structured answers that the user can review and submit in the MCP client: environment name, report format, date range, or parameter confirmation. URL mode is appropriate when the interaction involves a password, API key, access token, payment credentials, or third-party authorization. Those values are entered outside the client and are not returned in ElicitResult content.
Elicitation is not permission for the model to act and does not replace authorization. It only gives the server a controlled way to request user participation during an originating request. After the response, the server rechecks identity, scope, business policy, and current object state. If the authoritative system already knows the value, or the question is unnecessary for execution, do not elicit it: every extra prompt adds friction and phishing surface.
- Non-secret primitive fields → form mode.
- Credentials, payment, or external OAuth → URL mode.
- Approval for a consequential action → a separate policy/approval gate, not an arbitrary form field.
- Client did not advertise the required mode → controlled fallback or refusal.
- Authoritative value already exists → read it from the system of record.
Capability negotiation determines the available UX before the first request
The client advertises elicitation capability during initialization and the supported form and/or URL modes. An empty elicitation object is compatible with form-only behavior; the server must not interpret it as URL support. Store the session capability manifest together with the negotiated protocol and implementation versions, then check the required mode before elicitation/create. An application name or a button seen in one client does not prove compatibility in another deployment.
Server-to-client elicitation must be associated with an originating client request such as tools/call or resources/read. Do not build an independent channel for unsolicited prompts. The router determines the requirement before any side effect starts: form-supported, URL-supported, no-elicitation fallback, or blocked. If a workflow cannot obtain a credential safely without URL mode, the correct fallback is an out-of-band setup link or a clear refusal, not asking for the secret in a text field.
Form mode needs a minimal schema, preview, and validation on both sides
A form request contains a human-readable message and restricted JSON Schema: a flat object with primitive properties. The restriction is useful because it keeps elicitation as a short interaction rather than a hidden application-form platform. Names, descriptions, defaults, enum labels, and required fields should explain the consequence of the answer. Do not put clickable URLs into form fields and do not request secrets even if the schema can technically accept a string.
The client lets the user review, edit, accept, decline, or cancel the response and validates content against the schema. The server repeats schema and domain validation: range, tenant membership, object existence, current version, and allowed transitions. Accept means the user submitted values; it does not automatically approve a later high-risk action. Decline ends the request without a hidden default, while cancel must not be interpreted as a negative business decision.
- Collect only the fields needed for the current request.
- Separate schema validity from business authorization.
- Do not log full content without a retention purpose and data classification.
- After decline or cancel, do not repeat the prompt in an endless agent loop.
The test matrix validates privacy, association, and recovery
Contract tests cover initialization with form-only, URL-only, both modes, and no elicitation; omitted mode as form; unsupported mode; accept, decline, and cancel; schema rejection; unknown or duplicate completion IDs; and request association. URL cases verify that the client does not prefetch the address, shows the host, requires consent, and does not return external content in the protocol result. Form cases block password, token, API key, and payment fixtures regardless of their field names.
Security tests try to change elicitationId, tenant, provider, redirect, state, and browser subject; replay a callback; use an expired URL; substitute a Punycode host; or recover a secret from logs or traces. Recovery tests lose the accept response, completion notification, and originating retry. Assertions require idempotent resume: a repeated tool request first reconciles elicitation state and the downstream connection instead of creating a second OAuth grant or payment.
- Hard gate → secret in a form, automatic navigation, identity mismatch, or credential leakage.
- Protocol gate → request without association or a mode without capability.
- Recovery gate → lost notification must not create a duplicate external effect.
- UX gate → server, purpose, domain, and decline/cancel are clear before consent.
Rollout starts with a read-only form and one allowlisted URL flow
Start with form mode for a reversible read-only workflow containing two or three non-secret fields. Measure completion, decline/cancel, validation failures, repeated prompts, and time-to-resume without recording raw values in general telemetry. Then add one URL flow to an allowlisted HTTPS origin with a pinned redirect policy, verified identity binding, expiry, replay protection, vault storage, audit evidence, and a kill switch.
Promote the canary only after contract, privacy, phishing, recovery, and accessibility gates pass. Rollback blocks new elicitation requests, preserves reconciliation for in-flight records, revokes unfinished state handles, and restores a documented manual setup path. Retest after a change to the MCP revision, SDK/client, capability manifest, browser container, identity provider, downstream OAuth configuration, or data classification. The verdict always applies to a specific client-server-flow combination, never to the universal safety of URL mode.
Practical examples
Form for read-only export parameters
A tool is missing the report format and period. The server asks for an enum format and date range, the client shows a preview, and the server revalidates range and tenant. Decline ends the export without a side effect; the form collects no credentials.
URL for connecting a CRM
The server creates a short-lived elicitation record and displays an allowlisted HTTPS URL. The browser user completes third-party OAuth, the callback verifies subject and state, and the token goes directly into the server vault. The client receives a completion signal but never sees the credential.
FAQ
Can form elicitation request an API key?
No. The specification forbids form mode for passwords, API keys, access tokens, and payment credentials. Use URL mode with a secure out-of-band flow.
Does accept in URL mode mean OAuth has completed?
No. It only means consent to navigate to the URL. A server-side flow confirms completion; a completion notification may inform the client, but retry and reconciliation are still required.
Does URL elicitation replace MCP authorization?
No. MCP authorization controls client-to-server access. URL elicitation can obtain a third-party grant for the server without changing the client bearer token.
What if the client supports only form mode?
Do not send a URL request. Offer a safe manual setup path outside the workflow, another compatible client, or terminate with a clear error; never collect the secret in a form as fallback.
Related materials
A practical production architecture for human oversight: involve a person at a specific risk point with enough context for real, not ceremonial, control. Covers contracts, authority boundaries, failure modes, evaluation, and controlled rollout.
MCP Tasks vs synchronous tool calls: how to handle long-running operationsA practical choice between standard MCP tools/call and experimental MCP Tasks for long-running operations: capability negotiation, states, polling, cancellation, security, testing, and rollout.