Skip to content

Document MCP env_vars for secret-manager session tokens like BW_SESSION #19023

Open

Description

@verickwayne

Summary

Codex MCP subprocesses did not inherit the shell's secret-manager session environment by default. In this case an MCP server that resolved AGENTMAIL_API_KEY through Bitwarden appeared configured/enabled, but the model could not reliably discover/call the server's tools until I explicitly passed BW_SESSION through env_vars.

This is probably working as designed from a strict environment-isolation perspective, but the failure mode was hard to diagnose: codex mcp list / codex mcp get showed the server as enabled, and the same wrapper worked from the shell. A clearer warning or docs note would help MCP servers that resolve credentials from CLI secret managers.

Environment

  • Codex CLI: 0.122.0
  • macOS: 15.6.1
  • Node used by the MCP scripts: v25.8.2
  • MCP transport: stdio
  • Secret manager: Bitwarden CLI (bw)

Repro Shape

  1. Configure a stdio MCP server whose wrapper resolves its API key from either AGENTMAIL_API_KEY or Bitwarden CLI:
[mcp_servers.AgentMail]
command = "/path/to/agentmail-mcp.sh"
args = []
startup_timeout_sec = 20
default_tools_enabled = true
default_tools_approval_mode = "approve"
enabled_tools = ["list_inboxes"]
  1. In the interactive shell, Bitwarden is unlocked and the wrapper works:
bw status
/path/to/agentmail-mcp.sh   # raw MCP initialize/tools/list works
  1. In Codex, the server appears enabled, but native model calls to the server/tool are unavailable or fail because the MCP subprocess sees Bitwarden as locked.

A diagnostic MCP resource inside the subprocess showed the important difference:

{
  "hasAgentMailApiKeyEnv": false,
  "home": "/Users/...",
  "pathHasHomebrew": true,
  "bitwardenStatusExit": 0,
  "bitwardenStatusStdout": "{...\"status\":\"locked\"}"
}
  1. Passing the session variables through fixes it:
[mcp_servers.AgentMail]
command = "/path/to/agentmail-mcp.sh"
args = []
startup_timeout_sec = 20
default_tools_enabled = true
default_tools_approval_mode = "approve"
env_vars = ["AGENTMAIL_API_KEY", "BW_SESSION"]
enabled_tools = ["list_inboxes"]

[mcp_servers.AgentMail.env]
HOME = "/Users/..."
PATH = "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

After that, native Codex MCP calls to the tool succeed.

Expected

Either:

  • Docs explicitly call out that secret-manager session variables like BW_SESSION must be passed through with env_vars; or
  • codex mcp get/list / startup diagnostics make it easier to see that a configured MCP server's runtime environment differs from the launching shell in a way that can lock secret-manager access.

Actual

The server looked enabled from codex mcp list, but the actionable cause was only visible after building a custom diagnostic MCP resource.

Notes

No raw credentials were stored in config.toml; env_vars was sufficient and is the right fix once discovered.

Activity

  1. added
    documentationImprovements or additions to documentation
    CLIIssues related to the Codex CLI
    mcpIssues related to the use of model context protocol (MCP) servers
    configIssues involving config.toml, config keys, config merging, or config updates
    on Apr 22, 2026
  2. removed
    CLIIssues related to the Codex CLI
    configIssues involving config.toml, config keys, config merging, or config updates
    on Apr 22, 2026
  3. chanwooyang1 commented on Apr 24, 2026

    @chanwooyang1

    Thanks for the detailed repro and workaround. I looked through the current repo docs, and this seems like a focused MCP documentation improvement rather than a CLI/config behavior change.

    The missing piece appears to be explaining how env_vars differs from [mcp_servers.<name>.env]:

    • env_vars = [...] forwards selected variables from the launching environment into the stdio MCP subprocess.
    • [mcp_servers.<name>.env] sets explicit literal values in config.toml.

    That distinction is important for secret-manager session variables such as BW_SESSION, where users usually should not write the secret/session value directly into config.toml.

    A narrow docs update could add an example like:

    [mcp_servers.AgentMail]
    command = "/path/to/agentmail-mcp.sh"
    env_vars = ["AGENTMAIL_API_KEY", "BW_SESSION"]
    
    [mcp_servers.AgentMail.env]
    PATH = "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

    This would make it clearer that MCP subprocesses may not see secret-manager session state unless the relevant environment variables are explicitly passed through.

    If this scope looks right to maintainers, I’d be happy to prepare a narrow docs PR if invited, following the repo’s invitation-only contribution policy.

  4. Herrtian commented on May 22, 2026

    @Herrtian

    I prepared a focused docs/schema branch for the env vs env_vars distinction:

    https://github.com/Herrtian/codex/tree/docs/mcp-env-vars-secret-manager

    The branch keeps the change small and only updates the config comments plus generated schema:

    • env is described as literal environment values set for a stdio MCP server.
    • env_vars is described as names forwarded from the launching shell.
    • the schema text calls out secret-manager session variables such as BW_SESSION, where forwarding is usually preferable to writing the value into config.

    Validation I ran:

    git diff --check -- codex-rs/config/src/mcp_types.rs codex-rs/core/config.schema.json
    cargo run -p codex-core --bin codex-write-config-schema
    cargo test -p codex-core config_schema_matches_fixture -- --nocapture

    PR creation appears to be limited by the repo's invitation-only contribution policy, so I'm leaving the branch here rather than opening an unsolicited PR. If this matches the intended docs direction, could a maintainer invite a PR or pick up the branch internally?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationmcpIssues related to the use of model context protocol (MCP) servers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions