Under approval_policy="never", MCP URL elicitations are auto-declined while form elicitations surface (openai/standard-form-input has no URL equivalent)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What variant of Codex are you using?
Codex CLI / codex app-server, 0.154.0 (headless, driven by an external controller).
Summary
With approval_policy = "never" and sandbox = "danger-full-access", a controller that advertises the openai/standard-form-input extension at initialize does get downstream MCP form elicitations surfaced as mcpServer/elicitation/request (via enable_full_access_form_input() → should_surface_form_in_full_access). But URL-mode elicitations from the same server are silently auto-declined — there is no full_access_url_input counterpart. So a server that chains form → URL (e.g. collect a parameter, then OAuth-authorize) gets the form answered and the URL dropped, and the tool call fails/times out.
Root cause
In codex-rs/codex-mcp/src/elicitation.rs, the make_sender closure:
should_surface_form_in_full_accessmatches onlyFormElicitationParams/OpenAiElicitationForm; every other variant (incl.UrlElicitationParams) isfalse.- So URL elicitations fall into
if !should_surface_form_in_full_access { if elicitation_is_rejected_by_policy(approval_policy) { return Decline } }. elicitation_is_rejected_by_policyreturnstrueforAskForApproval::Never.can_auto_accept_elicitationonly auto-accepts empty-schema forms, so URLs aren't accepted either — they're declined.
Result under never: approval-only forms → auto-accepted; data forms (with standard-form-input) → surfaced; URL/OAuth → declined. Switching to on-request/untrusted surfaces the URL, but that also re-enables command-approval prompting, which defeats the point of never for autonomous runs.
Expected
A way to surface URL elicitations under never for hosts that can render them — symmetric to openai/standard-form-input for forms — without flipping the whole approval axis back to asking.
Proposed fix
Mirror the form bypass for URLs: add full_access_url_input_enabled + enable_full_access_url_input() on ElicitationRequestRouter, arm it from an opt-in client extension at initialize (same ThreadSource::User + root-agent guard as OPENAI_STANDARD_FORM_INPUT_EXTENSION_ID in core/src/thread_manager.rs), and add should_surface_url_in_full_access matching UrlElicitationParams, folded into the same guard so it bypasses elicitation_is_rejected_by_policy.
Repro
Point codex app-server (approval_policy=never, sandbox=danger-full-access, advertising openai/standard-form-input) at an MCP server that returns a URL-mode elicitation on tools/call; observe an auto-decline with no mcpServer/elicitation/request emitted. A form-mode elicitation from the same server surfaces normally.
Related
- #29344 (URL-mode elicitation capability gating — advertising side)
- #42139, #19554 (
neversemantics: "run without asking" actually declines approval-gated actions)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codex-rs/codex-mcp/src/elicitation.rs, tracing make_sender, should_surface_form_in_full_access, and the policy checks for UrlElicitationParams. Then inspect core/src/thread_manager.rs for OPENAI_STANDARD_FORM_INPUT_EXTENSION_ID, ThreadSource::User, and the root-agent guard. Done means an opt-in URL extension surfaces URL elicitations under approval_policy="never" without restoring command-approval prompting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, cli
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100