Support environment variable expansion

Open 💬 5 comments Opened Aug 25, 2025 by Epokhe

What feature would you like to see?

From CC docs: https://docs.anthropic.com/en/docs/claude-code/mcp#environment-variable-expansion-in-mcp-json

I think codex doesn't support this yet, at least the same ${ENV_VAR} syntax didn't work for me. Currently I have to put secrets directly into ~/.codex/config.toml, I think?

Are you interested in implementing this feature?

No

Additional information

_No response_

View original on GitHub ↗

5 Comments

masda70 · 12 months ago

I tried different syntaxes as well and couldn't manage to make environment variable interpolation work, so I believe Codex CLI does not yet support this feature indeed.

This kind of feature would be great when you need to share and sync Codex CLI config across multiple, possibly ephemeral, dev environments (e.g., devcontainers, Gihub Codespaces) while letting each machine manage its own secrets or instance specific params.

kossnocorp · 11 months ago

Env var expansion will help a lot with stuff like this:

[shell_environment_policy]
set = { GIT_CONFIG_GLOBAL = "${HOME}/.config/git/agent.config" } # Use agent git config

GIT_CONFIG_GLOBAL needs to be absolute, so ~/ won't work.

I have this in my dotfiles that automatically pulled in Dev Containers, so having project-specific config is not an option.

I currently have an Ansible playbook that solves this (that also merges local config), sharing it in case anyone needs a workaround:

---
- name: Apply project Codex configurations
  hosts: localhost
  gather_facts: no
  vars:
    start_marker: "#@project"
    end_marker: "#@project-end"

  tasks:
    - name: Read project config
      slurp:
        src: "{{ project_config }}"
      register: project_content

    - name: Merge project config into global config
      blockinfile:
        path: "{{ global_config }}"
        marker_begin: "{{ start_marker }}"
        marker_end: "{{ end_marker }}"
        block: "{{ project_content['content'] | b64decode }}"
        create: yes
        backup: yes

    - name: Read merged config
      slurp:
        src: "{{ global_config }}"
      register: merged_content

    - name: Expand ${HOME} in merged config
      copy:
        dest: "{{ global_config | expanduser }}"
        content: >-
          {{ merged_content['content'] | b64decode | regex_replace('\$\{HOME\}', lookup('env','HOME')) }}
        backup: yes
        mode: "0644"

I use such a script to run it:

#!/usr/bin/env bash

# This script merges global and local Codex config and expands necessary
# environment variables (as they aren't supported yet: https://github.com/openai/codex/issues/2680).

set -eo pipefail
root_dir="$(dirname "$0")/.."

echo -e "⚡️ Setting up Codex\n"

# Merge local Codex config to global config, as it doesn't support relative
# paths yet: https://github.com/openai/codex/issues/3706

echo -e "🌀 Merging project Codex config to ~/.codex/config.toml"

codex_config_path_chunk=".codex/config.toml"
local_codex_config_tmpl_path=$(realpath "$root_dir/$codex_config_path_chunk")
global_codex_config_path="$HOME/$codex_config_path_chunk"

ansible-playbook "$root_dir/scripts/setup-codex/playbook.yaml" \
  -i localhost, --connection=local \
  --extra-vars "global_config=$global_codex_config_path project_config=$local_codex_config_tmpl_path"

echo -e "\n💚 Codex setup complete!"
LimLLL · 8 months ago

can't believe codex still doesn't support the env expansion......

jeroenwienk · 6 months ago

Really need this as well there is now way to have a shared config now.

michaelfrog · 1 month ago

What is the best workaround today? assuming i have dynamic url for remote MCP that i want to plant in plugin ?