Add server-level approval defaults for custom MCP servers (#17843)

## Summary
- Add `default_tools_approval_mode` support for custom MCP server
configs, matching the existing `codex_apps` behavior
- Apply approval precedence as per-tool override, then server default,
then `auto`
- Update config serialization, CLI display, schema generation, docs, and
tests

## Testing
- `cargo check -p codex-config`
- `cargo check -p codex-core`
- `just write-config-schema`
- `just fmt`
- `cargo test -p codex-config`
- Targeted `codex-core` tests for config parsing, config writes, and MCP
approval precedence
- `just fix -p codex-config -p codex-core`
This commit is contained in:
Matthew Zeng authored and GitHub committed 2026-04-16 18:18:07 +00:00
1 parent 206dd13c32
commit 71174574ad
27 files changed
+231 -12

No files matched your search

+8
View File
@@ -582,6 +582,7 @@ fn blocking_replace_mcp_servers_round_trips() {
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: Some(vec!["one".to_string(), "two".to_string()]),
disabled_tools: None,
scopes: None,
@@ -610,6 +611,7 @@ fn blocking_replace_mcp_servers_round_trips() {
disabled_reason: None,
startup_timeout_sec: Some(std::time::Duration::from_secs(5)),
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: None,
disabled_tools: Some(vec!["forbidden".to_string()]),
scopes: None,
@@ -675,6 +677,7 @@ fn blocking_replace_mcp_servers_serializes_tool_approval_overrides() {
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: Some(AppToolApproval::Prompt),
enabled_tools: None,
disabled_tools: None,
scopes: None,
@@ -699,6 +702,7 @@ fn blocking_replace_mcp_servers_serializes_tool_approval_overrides() {
let expected = "\
[mcp_servers.docs]
command = \"docs-server\"
default_tools_approval_mode = \"prompt\"
[mcp_servers.docs.tools.search]
approval_mode = \"approve\"
@@ -737,6 +741,7 @@ foo = { command = "cmd" }
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: None,
disabled_tools: None,
scopes: None,
@@ -790,6 +795,7 @@ foo = { command = "cmd" } # keep me
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: None,
disabled_tools: None,
scopes: None,
@@ -842,6 +848,7 @@ foo = { command = "cmd", args = ["--flag"] } # keep me
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: None,
disabled_tools: None,
scopes: None,
@@ -895,6 +902,7 @@ foo = { command = "cmd" }
disabled_reason: None,
startup_timeout_sec: None,
tool_timeout_sec: None,
default_tools_approval_mode: None,
enabled_tools: None,
disabled_tools: None,
scopes: None,