[mcp] Fix plugin MCP approval policy. (#19537)

Plugin MCP servers are loaded from plugin manifests rather than
top-level `[mcp_servers]`, so their tool approval preferences need to be
stored and applied through the owning plugin config. Without this,
choosing "Always allow" for a plugin MCP tool could write a preference
that was not reliably used on later tool calls.

## Summary
- Add plugin-scoped MCP policy config under
`plugins.<plugin>.mcp_servers`, including server enablement, tool
allow/deny lists, server defaults, and per-tool approval modes.
- Overlay plugin MCP policy onto manifest-provided server configs when
plugins are loaded.
- Route persistent "Always allow" writes for plugin MCP tools back to
the owning `plugins.<plugin>.mcp_servers.<server>.tools.<tool>` config
entry.
- Reload user config after persisting an approval and make the plugin
load cache config-aware so stale plugin MCP policy is not reused after
`config.toml` changes.
- Regenerate the config schema and add coverage for plugin MCP policy
loading, approval lookup, persistence, and stale-cache prevention.

## Testing
- `cargo test -p codex-config`
- `cargo test -p codex-core-plugins`
- `cargo test -p codex-core --lib plugin_mcp`
This commit is contained in:
Matthew Zeng authored and GitHub committed 2026-04-29 15:40:03 -07:00
1 parent 4241df4d79
commit e20391e567
15 files changed
+919 -28

No files matched your search

+48
View File
@@ -1760,6 +1760,54 @@
"enabled": {
"default": true,
"type": "boolean"
},
"mcp_servers": {
"additionalProperties": {
"$ref": "#/definitions/PluginMcpServerConfig"
},
"description": "Per-MCP-server policy overlays for MCP servers contributed by this plugin.",
"type": "object"
}
},
"type": "object"
},
"PluginMcpServerConfig": {
"additionalProperties": false,
"description": "Policy settings for a plugin-provided MCP server.\n\nThis intentionally excludes transport settings: plugin manifests own how the MCP server is launched, while user config owns enablement and tool policy.",
"properties": {
"default_tools_approval_mode": {
"allOf": [
{
"$ref": "#/definitions/AppToolApproval"
}
],
"description": "Approval mode for tools in this server unless a tool override exists."
},
"disabled_tools": {
"description": "Explicit deny-list of tools. These tools are removed after applying `enabled_tools`.",
"items": {
"type": "string"
},
"type": "array"
},
"enabled": {
"default": true,
"description": "When `false`, Codex skips initializing this plugin MCP server.",
"type": "boolean"
},
"enabled_tools": {
"description": "Explicit allow-list of tools exposed from this server.",
"items": {
"type": "string"
},
"type": "array"
},
"tools": {
"additionalProperties": {
"$ref": "#/definitions/McpServerToolConfig"
},
"description": "Per-tool approval settings keyed by tool name.",
"type": "object"
}
},
"type": "object"