Feature Request: Allow users to disable the built-in `apply_patch` tool (and interception)
What feature would you like to see?
Summary
Codex CLI currently has a built-in editing pathway (apply_patch) that can be effectively “always on” in practice:
- The tool may be exposed to the model based on model-family defaults, even when the user tries to disable editing.
- Even if the tool spec is not exposed, Codex can still intercept
apply_patch-shaped commands sent via other tools (e.g.shell/unified_exec) and execute them anyway.
This makes it impossible for users to fully opt out of the built-in apply_patch pathway (for example, to force the model to use editing tools provided by their own MCP server).
This issue proposes adding a user-respecting configuration switch that fully disables the built-in apply_patch tool and the apply_patch command interception logic.
Motivation / Use cases
- Some users run custom MCP servers that provide their own editing tools (audit logging, policy enforcement, different patch formats, remote editing, etc.).
- In those setups, users may want to force all edits through their MCP tools and prevent Codex’s built-in editing tool from being used.
- Today, users can sometimes control which format of apply_patch is used (freeform vs JSON) but cannot reliably disable the entire built-in editing pathway.
Current behavior (technical)
Tool exposure ignores the user intent in some cases
Tool availability is built from a ToolsConfig.
ToolsConfig::new()chooses anapply_patch_tool_type.- If the selected model family has an explicit
apply_patch_tool_type, that can override user configuration (e.g. user chooses freeform mode, but the model family forces JSON; or user wants to remove it entirely, but the model family still injects it).
Interception can bypass tool exposure
Even if the apply_patch tool is not present in the tool list, Codex can still detect and intercept an apply_patch-like command issued via other tools.
This means the model can still “edit files” by sending a shell command that looks like:
apply_patch <patch>
…and Codex will apply it.
Proposed behavior
Introduce a user-configurable feature flag (default enabled to preserve existing behavior):
[features]
apply_patch_tool = false
When apply_patch_tool = false:
- The
apply_patchtool is not exposed to the model (regardless of model family defaults). apply_patchinterception is disabled (soapply_patch-shaped commands sent via other tools are treated as ordinary commands and not intercepted/applied).- If the model somehow calls the tool anyway, Codex rejects the call cleanly (for example:
unsupported call: apply_patch) and does not apply any patch. - Codex should also avoid injecting
apply_patch-specific instruction text (the “special apply_patch instructions” appended for some models) when the tool is intentionally disabled.
Compatibility
- Default behavior remains unchanged (
apply_patch_tool = true). - Existing “freeform apply_patch” configuration (freeform vs JSON) should remain unchanged when
apply_patch_tool = true. - Disabling
apply_patch_toolshould override any other settings that would otherwise exposeapply_patch.
Acceptance criteria
- Users can completely disable the built-in
apply_patchpathway. - With
apply_patch_tool = false,apply_patchdoes not appear in the tools list sent to the model. - With
apply_patch_tool = false, Codex does not interceptapply_patchcommands issued throughshell/unified_exec. - No behavior changes when the feature is left at default.
- Documentation (
docs/config.md) includes the new flag and its behavior.
Additional information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗