Skip to content

[codex] Add managed MCP server matchers - #29648

Merged
felixxia-oai merged 8 commits into
mainfrom
mcp-server-matchers
Jun 25, 2026
Merged

[codex] Add managed MCP server matchers#29648
felixxia-oai merged 8 commits into
mainfrom
mcp-server-matchers

Conversation

@felixxia-oai

@felixxia-oai felixxia-oai commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR extends the existing managed mcp_servers identity requirement so that one name-qualified rule can use either:

  • the released exact command or URL identity;
  • an exact stdio executable with an exact-length, ordered argument matcher list; or
  • a direct MCP URL matcher.

Matcher-based rules stay under the released identity key and use the same McpServerRequirement abstraction and mcp_servers.<server_name> namespace.

Behavior

Policy activation and name qualification are unchanged:

  • If mcp_servers is absent, ordinary configured MCP servers remain unrestricted.
  • If mcp_servers is present, a server needs a matching same-name requirement.
  • mcp_servers = {} continues to deny every configured MCP server.
  • Existing exact identity requirements keep their released semantics.

Plugin-bundled MCP servers use the same requirement shapes under plugins.<plugin_name>.mcp_servers.<server_name>. Top-level non-empty rules continue to govern only ordinary configured servers; plugin rules remain explicitly plugin-scoped. The existing globally empty mcp_servers = {} plugin kill switch is preserved.

Requirements layers continue to use the existing regular TOML merge behavior. Atomic replacement of named MCP requirements is intentionally out of scope here and is tracked independently in #30118.

Requirement contract

The released exact identity contract remains valid:

[mcp_servers.docs.identity]
command = "codex-mcp"

[mcp_servers.remote.identity]
url = "https://example.com/mcp"

Command identities continue to check only command; they do not inspect arguments, cwd, env, or env_vars.

A command matcher uses an exact executable plus an exact-length, ordered argument list. Each argument position supports exact, prefix, or full-value regex matching:

[mcp_servers.internal_mcp_proxy.identity]
command = { executable = "company-cli", args = [
  { match = "exact", value = "mcp" },
  { match = "exact", value = "proxy" },
  { match = "exact", value = "--server" },
  { match = "regex", expression = '^https://[A-Za-z0-9-]+\.mcp\.internal\.example\.com(?::443)?(?:/.*)?$' },
] }

Direct streamable HTTP MCP definitions can use the same value matcher types through identity.url:

[mcp_servers.internal_http.identity]
url = {
  match = "regex",
  expression = '^https://[A-Za-z0-9-]+\.mcp\.internal\.example\.com(?:/.*)?$',
}

Plugin-bundled MCP matchers use the same contract inside the plugin-qualified allowlist:

[plugins."sample@test".mcp_servers.internal_mcp_proxy.identity]
command = { executable = "company-cli", args = [
  { match = "exact", value = "mcp" },
  { match = "exact", value = "proxy" },
] }

Regexes are validated while managed requirements are loaded, and regex matching must cover the complete value. Command matchers constrain only the executable and arguments.

Why

Enterprise administrators need to allow MCP servers by executable and positional-argument shape, including fixed arguments plus constrained values such as internal MCP URLs passed to a proxy.

Validation

  • just fmt
  • git diff --check
  • just test -p codex-config (198 passed)
  • just test -p codex-core mcp_servers_by_matchers --lib (2 passed)

@felixxia-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 251056df68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/config/src/mcp_requirements.rs Outdated
Comment thread codex-rs/core/src/config/mod.rs Outdated
Comment thread codex-rs/config/src/mcp_requirements.rs
@felixxia-oai
felixxia-oai force-pushed the mcp-server-matchers branch 3 times, most recently from c70065c to 4b838e8 Compare June 23, 2026 20:13
@felixxia-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 4b838e8079

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@felixxia-oai
felixxia-oai marked this pull request as ready for review June 23, 2026 20:55
@felixxia-oai
felixxia-oai requested a review from a team as a code owner June 23, 2026 20:55
@felixxia-oai
felixxia-oai enabled auto-merge (squash) June 23, 2026 20:55
let mut merged_toml = TomlValue::Table(toml::map::Map::new());
for layer in &layers {
merge_toml_values(&mut merged_toml, &layer.regular_toml);
replace_mcp_server_requirements(&mut merged_toml, &layer.regular_toml);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we reuse/extend the existing identity shape for matcher-based requirements (e.g. identity.command = { match = ..., value = ... }) so all MCP requirement variants stay under the same key and we don’t need this extra MCP-specific replacement pass?

@felixxia-oai felixxia-oai Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The replacement behavior is not only needed because matchers currently sit outside identity. There is already a latent edge case with the existing identity contract:

# Lower layer
[mcp_servers.proxy.identity]
command = "old-command"

# Higher layer
[mcp_servers.proxy.identity]
url = "https://example.com/mcp"

The generic recursive merge produces:

[mcp_servers.proxy.identity]
command = "old-command"
url = "https://example.com/mcp"

McpServerIdentity is an untagged enum. Serde tries the command variant first, and unknown fields are tolerated, so this silently deserializes as the lower command identity and ignores the higher-priority URL.

Therefore, even if matcher forms were nested under identity, each same-name MCP requirement would still need to be replaced atomically across layers. I’ve moved that generic atomic-override mechanism into merge.rs and added documentation and coverage.

@felixxia-oai
felixxia-oai force-pushed the mcp-server-matchers branch from 4b838e8 to ef28c60 Compare June 24, 2026 12:39
@felixxia-oai
felixxia-oai disabled auto-merge June 24, 2026 13:01
Comment thread codex-rs/config/src/mcp_requirements.rs Outdated
Comment thread codex-rs/config/src/config_requirements.rs Outdated
Comment thread codex-rs/config/src/merge.rs Outdated
Comment thread codex-rs/config/src/requirements_layers/stack.rs Outdated
Comment thread codex-rs/config/src/mcp_requirements.rs Outdated
Comment thread codex-rs/config/src/merge.rs Outdated
@felixxia-oai
felixxia-oai force-pushed the mcp-server-matchers branch from d5a13af to 39cb801 Compare June 24, 2026 19:09
@felixxia-oai
felixxia-oai force-pushed the mcp-server-matchers branch from 39cb801 to f42f626 Compare June 24, 2026 19:34
@felixxia-oai
felixxia-oai merged commit db541f4 into main Jun 25, 2026
31 checks passed
@felixxia-oai
felixxia-oai deleted the mcp-server-matchers branch June 25, 2026 21:15
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants