MCP Elicitation Boundary

Why this page exists. MCP now lets servers ask users for information through clients. That is powerful, but it creates a new enterprise boundary: a server must not collect secrets through form prompts, send a user to a phishing URL, or confuse external OAuth with MCP authorization.

The product bet

SecurityRecipes is positioned as the secure context layer for agentic AI. Secure context is not only retrieval and tool policy; it also includes the moment an MCP server asks a human for data.

The new MCP elicitation surface makes AI easier for users because a server can ask for missing information inside a workflow. The enterprise version needs a default-deny policy:

  • clients advertise elicitation modes in capabilities metadata on every parent request, and servers only ask for modes declared on that request;
  • servers return elicitation inside InputRequiredResult.inputRequests, never as a standalone server-initiated JSON-RPC request;
  • clients correlate each response by its inputRequests map key, echo opaque requestState exactly, and retry the original operation with a new JSON-RPC ID;
  • servers treat requestState as attacker-controlled, verify its integrity, bind it to the principal and original request, enforce a short expiry, and add single-use enforcement where replay would have side effects;
  • low-risk form prompts can collect display names, preferences, and approval rationale;
  • passwords, API keys, payment credentials, access tokens, private keys, seed phrases, and session cookies are never allowed through form mode;
  • sensitive third-party authorization and credential setup uses URL mode;
  • URL mode requires HTTPS, explicit consent, full URL display, domain review, no prefetch, no pre-authenticated URLs, and no sensitive data embedded in the URL;
  • external OAuth via URL mode is separate from MCP authorization and must not become token passthrough;
  • every request creates receipt evidence tied to workflow, agent, run, server, user, session, and correlation ID.

Workflow at a glance

MCP Elicitation Boundary workflow

Control multi-round-trip MCP input requests, state-bound retries, user consent, and whether sensitive values can enter the exchange.

mcp-governance
  1. Signal

    Receive required input

    Capture the supported parent request, per-request client capabilities, InputRequiredResult, inputRequests key, opaque requestState, server/tool, purpose, UI mode, destination, and identity.

  2. Scope

    Classify requested data

    Identify public, internal, personal, regulated, credential, token, private key, payment, approval, or prohibited fields.

  3. Decision

    Validate consent and retry context

    Check server trust, purpose, minimization, URL/form safety, approval, state integrity and expiry, replay controls, principal binding, and original-request binding.

  4. Action

    Render or block safely

    Correlate inputResponses, echo opaque state unchanged, retry with a new JSON-RPC ID, or hold, deny, and kill unsafe or credential-harvesting requests.

  5. Proof

    Write the elicitation receipt

    Record the parent and retry requests, input key, state-validation outcome, displayed purpose, allowed fields, user decision, destination, policy, and correlation ID.

Decision gate

Is the request necessary, transparent, from a trusted server, and free of prohibited secrets or deceptive collection?

Proceed

Present only the approved fields and preserve informed user control.

Hold or stop

Hold, deny, or kill hidden, overbroad, credential-seeking, or untrusted elicitation.

Evidence to retain

  • request/data classification
  • server/consent policy decision
  • state-bound elicitation receipt

Expected outputs

  • safe elicitation form/URL
  • denial record
  • security incident signal

What was added

  • Source profile: data/assurance/mcp-elicitation-boundary-profile.json
  • Generator: scripts/generate_mcp_elicitation_boundary_pack.py
  • Evidence pack: data/evidence/mcp-elicitation-boundary-pack.json
  • Runtime evaluator: scripts/evaluate_mcp_elicitation_boundary_decision.py
  • MCP tools: recipes_mcp_elicitation_boundary_pack, paired with recipes_playbook_plan using playbook id mcp-elicitation-boundary.

Regenerate and validate the pack:

python3 scripts/generate_mcp_elicitation_boundary_pack.py
python3 scripts/generate_mcp_elicitation_boundary_pack.py --check

Evaluate a safe URL-mode OAuth request:

python3 scripts/evaluate_mcp_elicitation_boundary_decision.py \
  --workflow-id mcp-connector-intake-scanner \
  --agent-id sr-agent::mcp-connector-intake::codex \
  --run-id run-123 \
  --connector-id github \
  --namespace github.oauth \
  --server-id mcp-server::github \
  --elicitation-profile-id profile-third-party-oauth-url \
  --input-request-id github_oauth \
  --request-state opaque-aead-state \
  --mode url \
  --url https://github.com/login/oauth/authorize \
  --url-domain github.com \
  --user-id user-123 \
  --session-id session-123 \
  --correlation-id corr-123 \
  --authorization-pack-hash auth-pack-sha256 \
  --client-supports-mode \
  --server-identity-displayed \
  --user-can-decline \
  --user-consent-recorded \
  --request-state-echoed-exactly \
  --request-state-integrity-validated \
  --retry-request-bound \
  --https-url \
  --url-allowlisted \
  --expect-decision allow_elicitation_with_receipt

Evaluate a blocked secret-form request:

python3 scripts/evaluate_mcp_elicitation_boundary_decision.py \
  --workflow-id mcp-gateway-policy \
  --agent-id sr-agent::gateway::codex \
  --run-id run-124 \
  --server-id mcp-server::unknown \
  --elicitation-profile-id profile-credential-form-prohibited \
  --input-request-id api_key_form \
  --request-state opaque-aead-state \
  --mode form \
  --data-class api_key \
  --schema-field api_key \
  --session-id session-124 \
  --correlation-id corr-124 \
  --client-supports-mode \
  --server-identity-displayed \
  --user-can-decline \
  --user-can-review \
  --expect-decision deny_sensitive_form_elicitation

Decision model

Decision Meaning
allow_elicitation_with_receipt The request satisfies mode, data-class, URL, consent, identity, and receipt controls.
hold_for_elicitation_evidence The request is missing profile, client capability, identity, consent, review, completion, or workflow evidence.
deny_sensitive_form_elicitation Form mode is asking for a secret, token, payment credential, private key, seed phrase, or secret-like field.
deny_untrusted_elicitation_url URL mode failed HTTPS, allowlist, phishing, open-redirect, prefetch, pre-authenticated URL, or sensitive-URL checks.
deny_token_or_secret_transit Credentials or tokens would transit the MCP client, LLM context, or intermediate MCP server.
kill_session_on_elicitation_abuse A runtime kill signal fired or a URL was opened without explicit consent.

What the pack proves

The generated pack joins:

  • the MCP authorization conformance pack,
  • the context egress boundary pack,
  • the MCP tool-risk contract,
  • the agentic run receipt pack,
  • the workflow control plane,
  • and the MCP gateway policy pack.

That gives reviewers a single answer for a subtle production question: when an MCP server asks a user for more information, is the request safe, auditable, and separate from tool authorization?

For MCP 2026-07-28, the answer also covers the breaking multi-round-trip transport change: supported parent request, per-request client capability, unique input-request correlation, exact opaque-state echo, a distinct retry request ID, state integrity and replay protection, and binding to the authenticated principal and original operation. Rechecked August 23, 2026: 2026-07-28 is still current and stateless. There is no negotiation handshake. Servers MUST implement server/discover. --session-id and kill_session here are local run identifiers and host-session kill switches, not Mcp-Session-Id. Streamable HTTP revisions through 2025-11-25 could assign that header; 2026-07-28 ignores it and does not mint session IDs.

Industry alignment

This feature follows current primary guidance:

Trusted-source path

The open pack is the reference model. The reviewed production opportunity is hosted elicitation safety for MCP:

  • customer-specific URL allowlists and domain reputation checks,
  • consent receipt storage and replay,
  • connector setup flows for external OAuth and API-key rotation,
  • phishing and open-redirect telemetry,
  • separation checks between external authorization and MCP authorization,
  • trust-center exports proving which MCP servers can ask users for what.

That is a concrete path from open knowledge to a production MCP safety layer a model provider, developer platform, security platform, or AI gateway vendor can acquire.

MCP examples

Inspect the overall pack:

recipes_mcp_elicitation_boundary_pack()

Review URL-mode profiles:

recipes_mcp_elicitation_boundary_pack(mode="url")

Plan one runtime request:

recipes_playbook_plan(
  playbook_id="mcp-elicitation-boundary",
  finding="GitHub OAuth URL elicitation request needs consent and domain validation."
)

See also