fix(codex): bridge MCP tool approval elicitations#68807
Conversation
Greptile SummaryThis PR introduces a targeted bridge for Confidence Score: 5/5Safe to merge — the bridge is narrowly gated, fails closed on all unrecognized shapes, and does not change existing approval or non-approval code paths. All findings are P2 or lower (a duplicate test helper call and a documented heuristic risk). The fix is logically sound, the routing order in run-attempt.ts is correct, payload clamping is verified by tests, and the non-approval fallback remains unchanged. No files require special attention. The heuristic approval-field detection in
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ffb19e4db4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 701ecb9e44
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!isPersistField(property) || outcome !== "approved-session") { | ||
| return undefined; |
There was a problem hiding this comment.
Map allow-once onto required persist fields
readPersistFieldValue only returns a value for approved-session, and readFallbackFieldValue explicitly suppresses defaults for persist-like fields on approved-once. When an MCP approval schema makes persist required (for example with options like never/session/always), an allow-once decision leaves persist unset, so buildAcceptedContent returns undefined and the bridge declines the request even though the user approved it once.
Useful? React with 👍 / 👎.
|
Thanks @kesslerio — the useful narrowed version of this is now on main in What landed:
One local adjustment from the PR: the bridge now requires the request Main CI is green on Closing this PR as superseded by the landed main commit. |
Summary
user rejected MCP tool callfailures./approveflows already existed.mcpServer/elicitation/requesthandling now bridges_meta.codex_approval_kind = "mcp_tool_call"throughplugin.approval.request/plugin.approval.waitDecision, clamps approval payload lengths to gateway schema limits, and adds focused regression coverage.item/tool/requestUserInput, non-approval elicitations, connector auth, and GitHub permission behavior all remain unchanged and fail closed outside this targeted MCP approval path.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
extensions/codex/src/app-server/run-attempt.tsonly bridged native approval request families anditem/tool/call, so MCP tool approvals arriving onmcpServer/elicitation/requestfell through toclient.ts's default{ action: "decline" }fallback._meta.codex_approval_kind = "mcp_tool_call", and no regression test proving the native Codex bridge had to intercept that request family before fallback.Regression Test Plan (if applicable)
extensions/codex/src/app-server/elicitation-bridge.test.tsextensions/codex/src/app-server/run-attempt.test.tsextensions/codex/src/app-server/client.test.ts_meta.codex_approval_kind = "mcp_tool_call"routes through plugin approval request/wait, unsupported generic prompts still fail closed, and long approval payloads are clamped before gateway validation.User-visible / Behavior Changes
item/tool/requestUserInputand non-approval elicitation flows still fail closed exactly as before.Diagram (if applicable)
Security Impact (required)
Yes, explain risk + mitigation: this changes how an existing MCP tool approval request is routed, not what the tool can access. The bridge is gated to_meta.codex_approval_kind = "mcp_tool_call", leaves unsupported flows fail-closed, and clamps payloads to existing gateway validation limits.Repro + Verification
Environment
codex/gpt-5.4Steps
Expected
Actual
user rejected MCP tool call.Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
item/tool/requestUserInputstill fails closedReview Conversations
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
Compatibility / Migration
Risks and Mitigations
_meta.codex_approval_kind = "mcp_tool_call", only accepts form-mode object schemas, and fails closed when required fields cannot be satisfied.plugin.approval.request, with regression coverage.AI Assistance
Tests
pnpm exec vitest run extensions/codex/src/app-server/approval-bridge.test.ts extensions/codex/src/app-server/elicitation-bridge.test.ts extensions/codex/src/app-server/run-attempt.test.ts extensions/codex/src/app-server/client.test.ts