Plugin MCPs are disabled when plugin requirements contain no MCP allowlist
Summary
Plugin-provided MCP servers are all marked enabled = false when requirements.plugins is present but none of its entries declares mcp_servers.
A plugin requirement unrelated to MCP policy should not implicitly become an empty MCP allowlist. This can make plugin installation and codex mcp login succeed while new TUI, codex exec, and Desktop sessions receive none of the plugin MCP tools.
Root cause
In filter_plugin_mcp_servers_by_requirements() (codex-rs/core/src/config/mod.rs), the function returns early only when requirements.plugins is absent. When the plugins map exists but every PluginRequirementsToml::mcp_servers is None, allowed evaluates to false for every plugin MCP. Each server is disabled with McpServerDisabledReason::Requirements, so the connection manager never creates its client.
This is distinct from an explicit empty allowlist (mcp_servers = {}), which should continue to deny all plugin MCPs.
Minimal regression case
Construct requirements containing a plugin entry with mcp_servers: None, then pass an otherwise valid plugin MCP through filter_plugin_mcp_servers_by_requirements().
Expected: the MCP remains enabled because no MCP allowlist was declared.
Actual: the MCP is disabled with McpServerDisabledReason::Requirements.
Suggested fix
Skip MCP filtering unless at least one plugin requirement actually declares mcp_servers:
if !requirements
.value
.values()
.any(|plugin| plugin.mcp_servers.is_some())
{
return;
}
This preserves populated and explicitly empty allowlists while preventing unrelated plugin requirements from disabling every plugin MCP.
User-visible symptom
- Plugin inventory reports the plugin and MCP as installed/enabled.
codex mcp logincan complete successfully.- A fresh runtime does not connect to or expose the plugin MCP tools.
- Desktop may display
Auth unsupported, although the server was disabled by requirements before authentication.
Validation performed
Against Codex CLI 0.144.5 source:
- A focused regression test fails before the guard and passes after it.
- Existing explicit allowlist tests continue to pass.
codex-clibuilds successfully.- In an isolated smoke test, the unpatched binary materializes the plugin MCP as disabled; the patched binary enables it and completes
tools/list.
It would also help if the UI surfaced disabled_reason = Requirements instead of presenting this state as an authentication limitation.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗