Injecting env vars via settings.json's env key — verified live

Skip shell exports — settings.json alone can distribute env vars, verified on this Mac.

Why not just export in your shell profile

Shell exports aren't guaranteed to reach every Bash command, hook, and MCP server Claude Code launches. `settings.json`'s `env` key is written into the process environment by Claude Code itself, more reliably.

How to write it

A top-level `env` object in `.claude/settings.json`. Values must be plain strings — no dynamic evaluation (per official docs, fetched 2026-07-29).

{
  "env": {
    "APP_STAGE": "staging",
    "FEATURE_FLAG_NEW_UI": "true"
  }
}

Verified live: does Bash really see it?

With the above env set, asking Claude to echo both variables returned the real, correct values:

$ claude -p "echo APP_STAGE=$APP_STAGE FEATURE_FLAG_NEW_UI=$FEATURE_FLAG_NEW_UI" \
  --allowedTools "Bash(echo*)"

APP_STAGE=staging FEATURE_FLAG_NEW_UI=true

How far it reaches

Per the docs, it covers Bash commands, hook scripts, and MCP servers Claude Code launches.

Precedence vs your shell

If the same variable is set in both your shell and settings.json's env block, the settings file value wins per the docs.

Don't put secrets here

settings.json is meant to be committed and shared — keep API keys and tokens out of it; use a key manager or a gitignored .env instead.

FAQ

What does settings.json's env key affect?
Verified live — every Bash command Claude Code runs sees it as an environment variable.
Can values be dynamic?
No — per the docs, values must be plain strings only.
Shell export vs settings.json env — which wins?
Per the docs, the settings.json value wins.
Do hooks and MCP servers see it too?
Yes — Bash commands, hooks, and MCP servers Claude Code launches all see it.
Can I put secrets here?
Not recommended — settings.json is meant to be shared/committed; use a key manager instead.