Use case
A plugin ships a stdio MCP server that serves per-project data (in our case: a per-project knowledge index — the server must know which project the session is working in to serve the right one). Hooks can do this today: every hook payload carries cwd with the session working directory. Plugin MCP servers cannot.
Current behavior (codex-cli 0.146.0)
- A plugin-registered stdio MCP server with
"cwd": "." is spawned in the plugin's materialized cache directory (~/.codex/plugins/cache/<marketplace>/<plugin>/<version>/), so process.cwd() carries no project information.
- No substitution token or injected environment variable exposes the workspace/session root to plugin MCP server configs (nothing analogous to hook payload
cwd; env_vars only whitelists variables from the codex process environment, which requires a manual per-shell export).
- The MCP client does not declare the
roots capability, so roots/list is unavailable as an in-protocol signal (codex-rs/codex-mcp/src/rmcp_client.rs constructs client capabilities without roots as of rust-v0.146.0).
The net effect: a plugin MCP server cannot be project-aware without asking users to export an environment variable in every shell before launching codex.
Ask
Any one of these would close the gap:
- A substitution token for plugin MCP server
env/args values that resolves to the session workspace root (the equivalent of the cwd field hooks already receive), or
- An injected environment variable carrying the workspace root in the MCP server child process, or
- Declaring the
roots capability and answering roots/list with the workspace folder.
Option 1 or 2 seems most consistent with the existing hook contract, and with the MCP spec's 2026-07-28 direction (Roots is deprecated there in favor of server configuration).
Environment
- codex-cli 0.146.0, macOS
- Plugin installed via
codex plugin add from a marketplace repo
Use case
A plugin ships a stdio MCP server that serves per-project data (in our case: a per-project knowledge index — the server must know which project the session is working in to serve the right one). Hooks can do this today: every hook payload carries
cwdwith the session working directory. Plugin MCP servers cannot.Current behavior (codex-cli 0.146.0)
"cwd": "."is spawned in the plugin's materialized cache directory (~/.codex/plugins/cache/<marketplace>/<plugin>/<version>/), soprocess.cwd()carries no project information.cwd;env_varsonly whitelists variables from the codex process environment, which requires a manual per-shell export).rootscapability, soroots/listis unavailable as an in-protocol signal (codex-rs/codex-mcp/src/rmcp_client.rsconstructs client capabilities withoutrootsas ofrust-v0.146.0).The net effect: a plugin MCP server cannot be project-aware without asking users to export an environment variable in every shell before launching codex.
Ask
Any one of these would close the gap:
env/argsvalues that resolves to the session workspace root (the equivalent of thecwdfield hooks already receive), orrootscapability and answeringroots/listwith the workspace folder.Option 1 or 2 seems most consistent with the existing hook contract, and with the MCP spec's 2026-07-28 direction (Roots is deprecated there in favor of server configuration).
Environment
codex plugin addfrom a marketplace repo