Codex 配置 GitHub MCP:解决 "Environment variable is not set" 报错
TLDR
Codex 里给 GitHub MCP server 配好 bearer_token_env_var 后,仍报 Environment variable CODEX_GITHUB_PERSONAL_ACCESS_TOKEN ... is not set。根因:bearer_token_env_var 读的是 codex 自身进程 的环境变量,而把 token 塞进 ~/.codex/config.toml 的 [shell_environment_policy.set] 只注入它派生的 shell,到不了自身进程。正确做法是把环境变量 export 到 ~/.zshrc,在启动 codex 前就位。
问题
按 GitHub MCP server 官方指南配好 [mcp_servers.github],codex 启动时仍报:
⚠ MCP client for `github` failed to start: MCP startup failed: Environment variable CODEX_GITHUB_PERSONAL_ACCESS_TOKEN for MCP server 'github' is not set
根因
两个事实叠加:
| 事实 | 说明 |
|---|---|
Codex 不支持 inline bearer_token |
MCP server 配置只认 bearer_token_env_var,官方 schema 已把 inline bearer_token 字段隐藏(openai/codex #19294) |
bearer_token_env_var 读的是自身进程环境 |
它存的是「去哪个环境变量取 token」的名字,codex 连接时从自身进程读,不是从它派生的 bash 读 |
打个比方(仅为帮助理解):bearer_token_env_var 是一块「钥匙放在 X 口袋里」的告示牌,codex 只会翻自己的口袋(自身进程环境)。而 [shell_environment_policy.set] 是把钥匙塞进它派生的子进程口袋——塞错了地方。
于是三种做法的结果一目了然:
| 做法 | 结果 | 原因 |
|---|---|---|
token 写进 [shell_environment_policy.set] |
❌ 无效 | 只注入派生 shell,不是自身进程 |
config 里写 inline bearer_token |
❌ 不支持 | schema 无此字段 |
export 到 shell 启动文件 |
✅ 有效 | 启动 codex 前就在自身进程环境 |
修复
1. ~/.codex/config.toml 只留环境变量名:
[mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
bearer_token_env_var = "CODEX_GITHUB_PERSONAL_ACCESS_TOKEN"
2. ~/.zshrc 里 export 该变量。 token 从 dotenv 动态读取,避免明文重复(单一数据源,轮换 token 只改 .env 一处):
# Codex GitHub MCP: expose GITHUB_TOKEN from ~/.hermes/.env as the env var codex reads
if [[ -f "$HOME/.hermes/.env" ]]; then
_codex_gh_token="$(grep -E '^GITHUB_TOKEN=' "$HOME/.hermes/.env" | tail -n 1 | cut -d= -f2-)"
if [[ -n "$_codex_gh_token" ]]; then
export CODEX_GITHUB_PERSONAL_ACCESS_TOKEN="$_codex_gh_token"
fi
unset _codex_gh_token
fi
这里的 GitHub PAT 真实值是
ghp_***一类,上例只演示读取方式,不贴真实值。token 也可直接export CODEX_GITHUB_PERSONAL_ACCESS_TOKEN="ghp_***",但那样会跟.env各存一份,轮换时容易漏改。
3. 重开终端(或 source ~/.zshrc)→ 重启 codex → 报错消失。
命令速查
| 目的 | 命令 |
|---|---|
| 确认变量已注入 | echo $CODEX_GITHUB_PERSONAL_ACCESS_TOKEN |
| 确认 config 里的 MCP 段 | grep -A3 'mcp_servers.github' ~/.codex/config.toml |
| 验证 dotenv 提取逻辑 | grep -E '^GITHUB_TOKEN=' ~/.hermes/.env | tail -1 | cut -d= -f2- |
| 重启后看 MCP 是否就绪 | codex 启动时无 ⚠ MCP startup incomplete 即可 |