Plugin MCP commands do not expand PLUGIN_ROOT

Open 💬 0 comments Opened Jul 28, 2026 by danielkov

What issue are you seeing?

Codex expands ${PLUGIN_ROOT} in plugin hook command paths, but plugin-provided stdio MCP configurations leave the same placeholder literal in command and args. This makes it difficult for a plugin to ship and invoke its own MCP executable without relying on installation-specific absolute paths or wrapper setup.

For example, this plugin MCP declaration is loaded with ${PLUGIN_ROOT} still present in the executable path:

{
  "mcpServers": {
    "demo": {
      "command": "${PLUGIN_ROOT}/bin/demo-mcp",
      "args": ["--config", "${PLUGIN_ROOT}/config.json"]
    }
  }
}

What steps can reproduce the bug?

  1. Create a plugin containing the stdio MCP declaration above.
  2. Install and enable the plugin.
  3. Start or inspect the contributed MCP server.
  4. Observe that Codex attempts to use the literal ${PLUGIN_ROOT}/bin/demo-mcp command rather than a path rooted in the installed plugin directory.

The missing normalization is in codex-rs/codex-mcp/src/plugin_config.rs; relative plugin MCP cwd values are already rooted correctly, while command and args are not expanded.

What is the expected behavior?

For plugin-provided stdio MCP configurations, Codex should replace the narrow, trusted ${PLUGIN_ROOT} placeholder in command and string args with the plugin root. This should work for both host-local and executor-owned plugins, using the executor path convention where applicable. It should not perform general environment-variable or shell expansion.

This matches the existing literal placeholder substitution used for plugin hooks.

Additional information

I prepared and tested an implementation on a fork because this repository currently restricts pull-request creation to collaborators:

The change adds regression coverage for local and executor-owned plugin roots. Verification completed with:

  • just fmt
  • CARGO_NET_GIT_FETCH_WITH_CLI=true just test -p codex-mcp — 132 tests passed

A collaborator is welcome to cherry-pick 46240d2e4b or use the comparison above to open the upstream PR.

View original on GitHub ↗