Approvals
Depending on a user's Codex settings, command execution and file changes may require approval. The app-server sends a server-initiated JSON-RPC request to the client, and the client responds with a decision payload.
Command execution decisions:
accept,acceptForSession,decline,cancel, or\{ "acceptWithExecpolicyAmendment": \{ "execpolicy_amendment": ["cmd", "..."] \} \}.File change decisions:
accept,acceptForSession,decline,cancel.Requests include
threadIdandturnId- use them to scope UI state to the active conversation.The server resumes or declines the work and ends the item with
item/completed.
Command execution approvals
Order of messages:
item/startedshows the pendingcommandExecutionitem withcommand,cwd, and other fields.item/commandExecution/requestApprovalincludesitemId,threadId,turnId, optionalreason, optionalcommand, optionalcwd, optionalcommandActions, optionalproposedExecpolicyAmendment, optionalnetworkApprovalContext, and optionalavailableDecisions. Wheninitialize.params.capabilities.experimentalApi = true, the payload can also include experimentaladditionalPermissionsdescribing requested per-command sandbox access. Any filesystem paths insideadditionalPermissionsare absolute on the wire.- Client responds with one of the command execution approval decisions above.
serverRequest/resolvedconfirms that the pending request has been answered or cleared.item/completedreturns the finalcommandExecutionitem withstatus: completed | failed | declined.
When networkApprovalContext is present, the prompt is for managed network access (not a general shell-command approval). The current v2 schema exposes the target host and protocol; clients should render a network-specific prompt and not rely on command being a user-meaningful shell command preview.
Codex groups concurrent network approval prompts by destination (host, protocol, and port). The app-server may therefore send one prompt that unblocks multiple queued requests to the same destination, while different ports on the same host are treated separately.
File change approvals
Order of messages:
item/startedemits afileChangeitem with proposedchangesandstatus: "inProgress".item/fileChange/requestApprovalincludesitemId,threadId,turnId, optionalreason, and optionalgrantRoot.- Client responds with one of the file change approval decisions above.
serverRequest/resolvedconfirms that the pending request has been answered or cleared.item/completedreturns the finalfileChangeitem withstatus: completed | failed | declined.
tool/requestUserInput
When the client responds to item/tool/requestUserInput, app-server emits serverRequest/resolved with \{ threadId, requestId \}. If the pending request is cleared by turn start, turn completion, or turn interruption before the client answers, the server emits the same notification for that cleanup.
Request params include autoResolutionMs as an integer millisecond timeout or null. When present, host clients can resolve the prompt automatically after that interval if the user doesn't answer.
Permission requests
The built-in request_permissions tool sends item/permissions/requestApproval with the threadId, turnId, itemId, environmentId, cwd, optional reason, and requested network or filesystem permissions. Respond with permissions containing only the granted subset. Set scope to "session" to persist the grant for later turns in the same session; omit it or use "turn" for a turn-scoped grant. Permissions that weren't requested are ignored.
MCP server elicitation requests
An MCP server can interrupt a turn with mcpServer/elicitation/request. The request includes threadId, an optional turnId, serverName, and one of these request shapes:
mode: "form"ormode: "openai/form", withmessageandrequestedSchema.mode: "url", withmessage,url, andelicitationId.
Respond with action: "accept" and the requested content, or with action: "decline" or "cancel" and content: null. App-server then emits serverRequest/resolved. To receive the openai/form variant, opt in with initialize.params.capabilities.mcpServerOpenaiFormElicitation.
Dynamic tool calls (experimental)
dynamicTools on thread/start and the corresponding item/tool/call request or response flow are experimental APIs.
Dynamic tool names and namespace names must follow Responses API naming constraints. Avoid reserved namespace names used by built-in Codex tools.
When a dynamic tool is invoked during a turn, app-server emits:
item/startedwithitem.type = "dynamicToolCall",status = "inProgress", plustoolandarguments.item/tool/callas a server request to the client.- The client response payload with returned content items.
item/completedwithitem.type = "dynamicToolCall", the finalstatus, and any returnedcontentItemsorsuccessvalue.
MCP tool-call approvals (apps)
App (connector) tool calls can also require approval. When an app tool call has side effects, the server may elicit approval with tool/requestUserInput and options such as Accept, Decline, and Cancel. Destructive tool annotations always trigger approval even when the tool also advertises less-privileged hints. If the user declines or cancels, the related mcpToolCall item completes with an error instead of running the tool.