Feature Request: Allow users to disable the built-in `apply_patch` tool (and interception)

Resolved 💬 2 comments Opened Dec 17, 2025 by RealXuChe Closed Feb 23, 2026

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 an apply_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:

  1. The apply_patch tool is not exposed to the model (regardless of model family defaults).
  2. apply_patch interception is disabled (so apply_patch-shaped commands sent via other tools are treated as ordinary commands and not intercepted/applied).
  3. 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.
  4. 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_tool should override any other settings that would otherwise expose apply_patch.

Acceptance criteria

  • Users can completely disable the built-in apply_patch pathway.
  • With apply_patch_tool = false, apply_patch does not appear in the tools list sent to the model.
  • With apply_patch_tool = false, Codex does not intercept apply_patch commands issued through shell / 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_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗