# Claude Code Status Line - Complete Guide: all fields, config, ready-to-use scripts

> Source: <https://gist.github.com/zaherkarp/afc4a5899b808be54badd46cde51e747>
> Published: 2026-06-24 18:21:28+00:00

Claude Code Status Line - Complete Guide: all fields, config, ready-to-use scripts

A persistent, customizable bar at the bottom of Claude Code that shows real-time session data.

[What Is It?](https://gist.github.com/starred.atom#what-is-it)[Quick Start](https://gist.github.com/starred.atom#quick-start)[Want Mine?](https://gist.github.com/starred.atom#want-mine)[Available Data Fields](https://gist.github.com/starred.atom#available-data-fields)[Your Script Superpowers](https://gist.github.com/starred.atom#your-script-superpowers)[Ready-to-Use Scripts](https://gist.github.com/starred.atom#ready-to-use-scripts)[Full JSON Schema](https://gist.github.com/starred.atom#full-json-schema)[Tips and Tricks](https://gist.github.com/starred.atom#tips-and-tricks)[All Claude Code Settings](https://gist.github.com/starred.atom#all-claude-code-settings)

The status line is an **info bar pinned to the bottom of your Claude Code window**. Think of it like the status bar in VS Code or the bottom of a Google Doc — it just sits there showing you useful stuff while you work.

**What can it show?**

- Which AI model you're using
- Your project name and git branch
- How much of your conversation memory is used up (context %)
- How much the session has cost so far
- How long you've been working
- Lines of code added / removed
- …and more

**How does it work?**
You tell Claude what you want to see, and it builds the status bar for you. No coding required on your part — just describe it in plain English.

**Does it cost anything?**
Nope. It runs entirely on your machine. Zero API usage.

Just type a `/statusline`

command describing what you want:

```
/statusline show model name and context percentage with a progress bar
```

Claude generates the script, saves it, and wires up settings for you. Done.

**More examples:**

```
/statusline show repo name, git branch, context bar, and model
/statusline show cost and session duration with model name
/statusline show git branch with colored staged/modified file counts
/statusline two lines: model and branch on top, color-coded context bar with cost on bottom
```

**To remove it:**

```
/statusline clear
```

Here's the exact status line I use daily. Fully color-coded with icons and a gradient context bar.

**What it looks like:**

| Element | Example | Color |
|---|---|---|
| Repo name | `EasyClaw` |
Bold yellow |
| Branch | `🌿 (main)` |
Bold cyan |
| Context bar | `⚡ █████████░░░░░░░░░░░ 47%` |
True RGB gradient (green → yellow → red) + dynamic emoji |
| Context emoji | 🟢 → ⚡ → 🔥 → 🚨 | Changes at 20% / 70% / 90% |
| Cost | `$0.47` |
Yellow |
| Code velocity | `+156 -23` |
Green adds, red deletes |
| Model | `🤖 Opus 4.6` |
Magenta |
| Separators | `|` |
Dim gray |

**One command to get it:**

```
/statusline single line, fully color-coded with truecolor RGB gradient: repo name bold yellow, 🌿 leaf icon + git branch in bold cyan with parentheses, 20-block context bar using 24-bit RGB gradient from green(0,200,80) through yellow(220,200,0) to red(220,40,20) with dark gray(60,60,60) empty blocks, dynamic emoji that changes with usage (🟢 under 20%, ⚡ 20-69%, 🔥 70-89%, 🚨 90%+), percentage colored by usage level, session cost in yellow, code velocity showing +lines in green and -lines in red, 🤖 robot icon + model name in magenta, dim gray pipe separators between all elements
```

**Or copy the script directly:**

``` bash
#!/usr/bin/env bash
# Claude Code status line: RGB gradient, dynamic emoji, cost, code velocity

input=$(cat)

# ── Colors ──
CYAN='\033[36m'
GREEN='\033[32m'
YELLOW='\033[33m'
RED='\033[31m'
MAGENTA='\033[35m'
DIM='\033[2m'
BOLD='\033[1m'
RESET='\033[0m'

# ── Truecolor helper ──
rgb() { printf '\033[38;2;%d;%d;%dm' "$1" "$2" "$3"; }

# ── Parse JSON fields ──
model=$(echo "$input" | jq -r '.model.display_name // "Unknown"')
used=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
lines_add=$(echo "$input" | jq -r '.cost.total_lines_added // 0')
lines_del=$(echo "$input" | jq -r '.cost.total_lines_removed // 0')
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""')

# ── Git info ──
branch=""
repo=""
if [ -n "$cwd" ]; then
  branch=$(git -C "$cwd" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null)
  repo=$(basename "$(git -C "$cwd" --no-optional-locks rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null)
fi

# ── Context bar: RGB gradient, full blocks only ──
BAR_WIDTH=20

if [ -n "$used" ]; then
  used_int=$(printf '%.0f' "$used")

  # Round to nearest block
  filled=$(( (used_int * BAR_WIDTH + 50) / 100 ))

  bar=""
  for (( i=0; i<BAR_WIDTH; i++ )); do
    pos=$(( i * 100 / (BAR_WIDTH - 1) ))

    if [ "$pos" -le 50 ]; then
      r=$(( 0 + 220 * pos / 50 ))
      g=200
      b=$(( 80 - 80 * pos / 50 ))
    else
      adj=$(( pos - 50 ))
      r=220
      g=$(( 200 - 160 * adj / 50 ))
      b=$(( 0 + 20 * adj / 50 ))
    fi

    if [ "$i" -lt "$filled" ]; then
      bar="${bar}$(rgb $r $g $b)█"
    else
      bar="${bar}\033[38;2;60;60;60m░"
    fi
  done
  bar="${bar}${RESET}"

  if [ "$used_int" -ge 90 ]; then status_emoji="🚨"
  elif [ "$used_int" -ge 70 ]; then status_emoji="🔥"
  elif [ "$used_int" -ge 20 ]; then status_emoji="⚡"
  else status_emoji="🟢"; fi

  if [ "$used_int" -ge 90 ]; then pct_color="$RED"
  elif [ "$used_int" -ge 70 ]; then pct_color="$YELLOW"
  else pct_color="$GREEN"; fi

  ctx_part="${status_emoji} ${bar} ${pct_color}${used_int}%${RESET}"
else
  ctx_part="🟢 \033[38;2;60;60;60m░░░░░░░░░░░░░░░░░░░░${RESET} --%"
fi

# ── Cost ──
cost_part="${YELLOW}$(printf '$%.2f' "$cost")${RESET}"

# ── Code velocity ──
velocity="${GREEN}+${lines_add}${RESET} ${RED}-${lines_del}${RESET}"

# ── Single line ──
out=""
[ -n "$repo" ] && out="${BOLD}${YELLOW}${repo}${RESET}"
[ -n "$branch" ] && out="${out:+$out }${BOLD}${CYAN}🌿 (${branch})${RESET}"
out="${out:+$out ${DIM}|${RESET} }${ctx_part}"
out="${out} ${DIM}|${RESET} ${cost_part}"
out="${out} ${DIM}|${RESET} ${velocity}"
out="${out} ${DIM}|${RESET} ${MAGENTA}🤖 ${model}${RESET}"

printf '%b' "$out"
```

Every time your script runs, it receives JSON via `stdin`

. Here is everything you can display.

| Field | What It Shows | Example Value |
|---|---|---|
`model.id` |
Model identifier | `"claude-opus-4-6"` |
`model.display_name` |
Friendly model name | `"Opus"` |
`session_id` |
Unique session ID | `"abc123..."` |
`session_name` |
Custom name (via `/rename` ) |
`"my-feature-work"` |
`version` |
Claude Code version | `"2.1.90"` |

| Field | What It Shows | Example Value |
|---|---|---|
`cwd` |
Current working directory | `"/Users/me/project"` |
`workspace.current_dir` |
Same as `cwd` (preferred) |
`"/Users/me/project"` |
`workspace.project_dir` |
Where Claude Code was launched | `"/Users/me/project"` |
`workspace.added_dirs` |
Extra dirs added via `/add-dir` |
`[]` |
`workspace.git_worktree` |
Git worktree name (if in one) | `"feature-xyz"` |

| Field | What It Shows | Example |
|---|---|---|
`context_window.used_percentage` |
% of context used | `30` |
`context_window.remaining_percentage` |
% of context remaining | `70` |
`context_window.context_window_size` |
Max tokens (200K or 1M) | `200000` |
`context_window.total_input_tokens` |
Cumulative input tokens | `15234` |
`context_window.total_output_tokens` |
Cumulative output tokens | `4521` |
`context_window.current_usage.input_tokens` |
Input tokens in last API call | `8500` |
`context_window.current_usage.output_tokens` |
Output tokens from last call | `1200` |
`context_window.current_usage.cache_creation_input_tokens` |
Tokens written to cache | `5000` |
`context_window.current_usage.cache_read_input_tokens` |
Tokens read from cache | `2000` |
`exceeds_200k_tokens` |
Last response exceeded 200K | `false` |

| Field | What It Shows | Example Value |
|---|---|---|
`cost.total_cost_usd` |
Total session cost (USD) | `0.01234` |
`cost.total_duration_ms` |
Wall-clock time since start | `45000` |
`cost.total_api_duration_ms` |
Time waiting for API responses | `2300` |
`cost.total_lines_added` |
Lines of code added | `156` |
`cost.total_lines_removed` |
Lines of code removed | `23` |

| Field | What It Shows | Example Value |
|---|---|---|
`rate_limits.five_hour.used_percentage` |
5-hour usage % | `23.5` |
`rate_limits.five_hour.resets_at` |
Reset time (Unix epoch) | `1738425600` |
`rate_limits.seven_day.used_percentage` |
7-day usage % | `41.2` |
`rate_limits.seven_day.resets_at` |
Reset time (Unix epoch) | `1738857600` |

| Field | When It Appears | Example Value |
|---|---|---|
`vim.mode` |
When vim mode is enabled | `"NORMAL"` or `"INSERT"` |
`output_style.name` |
Current output style | `"default"` |
`agent.name` |
When using `--agent` flag |
`"security-reviewer"` |
`worktree.name` |
During `--worktree` sessions |
`"my-feature"` |
`worktree.path` |
Worktree directory path | `"/path/to/worktree"` |
`worktree.branch` |
Worktree git branch | `"worktree-my-feature"` |
`worktree.original_cwd` |
Dir before entering worktree | `"/path/to/project"` |
`worktree.original_branch` |
Branch before entering worktree | `"main"` |
`transcript_path` |
Path to conversation transcript | `"/path/to/transcript"` |

Each `echo`

/ `print`

creates a separate row:

```
echo "Line 1: Model and branch info"
echo "Line 2: Context bar and cost"
+-----------------------------------------------------------------+
|  [Opus] EasyClaw | main                                          |
|  [####......] 40% | $0.23 | 12m 5s                               |
+-----------------------------------------------------------------+
```

Use escape codes for colored output:

```
GREEN='\033[32m'
YELLOW='\033[33m'
RED='\033[31m'
CYAN='\033[36m'
RESET='\033[0m'

echo -e "${GREEN}All good${RESET} | ${RED}Warning${RESET}"
```

Use OSC 8 escape sequences (requires iTerm2, Kitty, or WezTerm):

```
printf '%b' "\e]8;;https://github.com/user/repo\aRepo Name\e]8;;\a"
```

Hold `Cmd`

(macOS) or `Ctrl`

(Windows/Linux) and click to open.

Copy any of these and pass them to `/statusline`

, or just describe what you want in plain English.

```
[Opus] [###.......] 30%
bash
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)

BAR_WIDTH=10
FILLED=$((PCT * BAR_WIDTH / 100))
EMPTY=$((BAR_WIDTH - FILLED))
BAR=""
[ "$FILLED" -gt 0 ] && printf -v FILL "%${FILLED}s" && BAR="${FILL// /▓}"
[ "$EMPTY" -gt 0 ] && printf -v PAD "%${EMPTY}s" && BAR="${BAR}${PAD// /░}"

echo "[$MODEL] $BAR $PCT%"
EasyClaw (main)  [███░░░░░░░] 30%  Claude Opus 4
bash
#!/bin/bash
input=$(cat)

model=$(echo "$input" | jq -r '.model.display_name // "Unknown Model"')

used=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
if [ -n "$used" ]; then
  used_int=$(printf '%.0f' "$used")
  filled=$(( used_int / 10 ))
  empty=$(( 10 - filled ))
  bar=""
  for i in $(seq 1 $filled); do bar="${bar}█"; done
  for i in $(seq 1 $empty);  do bar="${bar}░"; done
  ctx_part="[${bar}] ${used_int}%"
else
  ctx_part="[░░░░░░░░░░] --%"
fi

cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""')
branch=""
repo=""
if [ -n "$cwd" ]; then
  branch=$(git -C "$cwd" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null)
  repo=$(basename "$(git -C "$cwd" --no-optional-locks rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null)
fi

out=""
[ -n "$repo" ] && out="$repo"
[ -n "$branch" ] && out="${out:+$out }(${branch})"
out="${out:+$out  }${ctx_part}  ${model}"

printf '%s' "$out"
[Opus] EasyClaw | main +2 ~5
bash
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')

GREEN='\033[32m'; YELLOW='\033[33m'; RESET='\033[0m'

if git rev-parse --git-dir > /dev/null 2>&1; then
    BRANCH=$(git branch --show-current 2>/dev/null)
    STAGED=$(git diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ')
    MODIFIED=$(git diff --numstat 2>/dev/null | wc -l | tr -d ' ')

    GIT_STATUS=""
    [ "$STAGED" -gt 0 ] && GIT_STATUS="${GREEN}+${STAGED}${RESET}"
    [ "$MODIFIED" -gt 0 ] && GIT_STATUS="${GIT_STATUS}${YELLOW}~${MODIFIED}${RESET}"

    echo -e "[$MODEL] ${DIR##*/} | $BRANCH $GIT_STATUS"
else
    echo "[$MODEL] ${DIR##*/}"
fi
[Opus] $0.23 | 12m 5s
bash
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')

COST_FMT=$(printf '$%.2f' "$COST")
DURATION_SEC=$((DURATION_MS / 1000))
MINS=$((DURATION_SEC / 60))
SECS=$((DURATION_SEC % 60))

echo "[$MODEL] $COST_FMT | ${MINS}m ${SECS}s"
[Opus] EasyClaw | main
[####......] 40% | $0.23 | 12m 5s
```

Context bar changes color: green < 70% | yellow 70-89% | red 90%+

``` bash
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')

CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'

if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED"
elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW"
else BAR_COLOR="$GREEN"; fi

FILLED=$((PCT / 10)); EMPTY=$((10 - FILLED))
printf -v FILL "%${FILLED}s"; printf -v PAD "%${EMPTY}s"
BAR="${FILL// /█}${PAD// /░}"

MINS=$((DURATION_MS / 60000)); SECS=$(((DURATION_MS % 60000) / 1000))

BRANCH=""
git rev-parse --git-dir > /dev/null 2>&1 && BRANCH=" | $(git branch --show-current 2>/dev/null)"

echo -e "${CYAN}[$MODEL]${RESET} ${DIR##*/}$BRANCH"
COST_FMT=$(printf '$%.2f' "$COST")
echo -e "${BAR_COLOR}${BAR}${RESET} ${PCT}% | ${YELLOW}${COST_FMT}${RESET} | ${MINS}m ${SECS}s"
[Opus] 5h: 23% | 7d: 41%
bash
#!/bin/bash
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
FIVE_HR=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
SEVEN_DAY=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')

out="[$MODEL]"
[ -n "$FIVE_HR" ] && out="$out 5h: $(printf '%.0f' "$FIVE_HR")%"
[ -n "$SEVEN_DAY" ] && out="$out | 7d: $(printf '%.0f' "$SEVEN_DAY")%"

echo "$out"
```

This is the complete JSON your script receives on `stdin`

:

```
{
  "cwd": "/current/working/directory",
  "session_id": "abc123...",
  "session_name": "my-session",
  "transcript_path": "/path/to/transcript.jsonl",
  "model": {
    "id": "claude-opus-4-6",
    "display_name": "Opus"
  },
  "workspace": {
    "current_dir": "/current/working/directory",
    "project_dir": "/original/project/directory",
    "added_dirs": [],
    "git_worktree": "feature-xyz"
  },
  "version": "2.1.90",
  "output_style": {
    "name": "default"
  },
  "cost": {
    "total_cost_usd": 0.01234,
    "total_duration_ms": 45000,
    "total_api_duration_ms": 2300,
    "total_lines_added": 156,
    "total_lines_removed": 23
  },
  "context_window": {
    "total_input_tokens": 15234,
    "total_output_tokens": 4521,
    "context_window_size": 200000,
    "used_percentage": 8,
    "remaining_percentage": 92,
    "current_usage": {
      "input_tokens": 8500,
      "output_tokens": 1200,
      "cache_creation_input_tokens": 5000,
      "cache_read_input_tokens": 2000
    }
  },
  "exceeds_200k_tokens": false,
  "rate_limits": {
    "five_hour": {
      "used_percentage": 23.5,
      "resets_at": 1738425600
    },
    "seven_day": {
      "used_percentage": 41.2,
      "resets_at": 1738857600
    }
  },
  "vim": {
    "mode": "NORMAL"
  },
  "agent": {
    "name": "security-reviewer"
  },
  "worktree": {
    "name": "my-feature",
    "path": "/path/to/.claude/worktrees/my-feature",
    "branch": "worktree-my-feature",
    "original_cwd": "/path/to/project",
    "original_branch": "main"
  }
}
```

**Fields that may be absent:**

`session_name`

-- only when set via`--name`

or`/rename`

`workspace.git_worktree`

-- only inside a linked git worktree`vim`

-- only when vim mode is enabled`agent`

-- only when using`--agent`

`worktree`

-- only during`--worktree`

sessions`rate_limits`

-- only for Claude.ai Pro/Max after first API response

**Fields that may be null:**

`context_window.current_usage`

--`null`

before first API call`context_window.used_percentage`

-- may be`null`

early in session

| Tip | Details |
|---|---|
When does it update? |
After each assistant message, permission mode change, or vim mode toggle. Debounced at 300ms. |
No API tokens used |
Status line runs locally -- completely free. |
Hides during prompts |
Temporarily hidden during autocomplete, help menu, and permission prompts. |
Can use any language |
Bash, Python, Node.js -- anything that reads stdin and prints to stdout. |
Test your script |
Pipe sample JSON: `echo '{"model":{"display_name":"Opus"}}' |

Every setting lives in `settings.json`

. There are three levels, loaded in order (later overrides earlier):

| Level | Path | Scope |
|---|---|---|
| User | `~/.claude/settings.json` |
All projects on your machine |
| Project | `.claude/settings.json` (in repo root) |
Everyone on this repo |
| Managed | `~/.claude/settings.managed.json` |
Enterprise IT policy (read-only) |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`model` |
`string` |
`"claude-sonnet-4-6"` |
Default model for all sessions |
`availableModels` |
`string[]` |
all | Restrict which models users can pick |
`effortLevel` |
`"auto" | "low" | "medium" | "high"` |
varies | Opus 4.6 reasoning depth — lower = faster & cheaper |
`fastMode` |
`boolean` |
`false` |
2.5x faster output, higher per-token cost (same model) |
`fastModePerSessionOptIn` |
`boolean` |
`false` |
Require `/fast` each session instead of persisting |
`language` |
`string` |
— | Preferred language for Claude's responses |
`outputStyle` |
`string` |
`"default"` |
Response style: `default` , `Explanatory` , `Learning` , or custom |
`alwaysThinkingEnabled` |
`boolean` |
`false` |
Extended thinking on by default for all sessions |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`statusLine.type` |
`"command"` |
— | Must be `"command"` to enable a custom status line |
`statusLine.command` |
`string` |
— | Shell command or script path that reads JSON stdin, prints status to stdout |
`statusLine.padding` |
`number` |
`0` |
Extra horizontal spacing characters around the status line content |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`permissions.defaultMode` |
`string` |
`"default"` |
Default permission mode: `default` , `plan` , `bypassPermissions` , etc. |
`permissions.allow` |
`string[]` |
`[]` |
Tools always allowed without asking |
`permissions.deny` |
`string[]` |
`[]` |
Tools always denied |
`allowManagedPermissionRulesOnly` |
`boolean` |
`false` |
(Managed only) Block user/project permission rules |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`spinnerTipsEnabled` |
`boolean` |
`true` |
Show tips in the spinner while Claude works |
`spinnerTipsOverride` |
`object` |
— | Custom tip messages for the spinner |
`spinnerVerbs` |
`object` |
— | Custom verbs shown in spinner progress |
`terminalProgressBarEnabled` |
`boolean` |
`true` |
Progress bar in terminals that support it (Windows Terminal, iTerm2) |
`showTurnDuration` |
`boolean` |
`true` |
Show "Cooked for 1m 6s" after responses |
`prefersReducedMotion` |
`boolean` |
`false` |
Disable UI animations (spinners, shimmer, flash) for accessibility |
`companyAnnouncements` |
`string[]` |
— | (Managed only) Startup messages, one picked randomly |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`enabledPlugins` |
`object` |
`{}` |
Map of `"plugin@marketplace": true` to enable plugins |
`extraKnownMarketplaces` |
`object` |
`{}` |
Additional plugin marketplace sources |
`pluginConfigs` |
`object` |
`{}` |
Per-plugin configuration (MCP user configs, etc.) |
`skippedPlugins` |
`string[]` |
`[]` |
Plugins you declined when prompted |
`skippedMarketplaces` |
`string[]` |
`[]` |
Marketplaces you declined when prompted |
`strictKnownMarketplaces` |
`string[]` |
— | (Managed only) Allowlist of permitted marketplaces |
`blockedMarketplaces` |
`string[]` |
— | (Managed only) Blocked marketplace sources |
`pluginTrustMessage` |
`string` |
— | (Managed only) Custom message on plugin trust warning |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`enableAllProjectMcpServers` |
`boolean` |
`false` |
Auto-approve all MCP servers in the project |
`enabledMcpjsonServers` |
`string[]` |
`[]` |
Approved MCP servers from `.mcp.json` |
`disabledMcpjsonServers` |
`string[]` |
`[]` |
Rejected MCP servers from `.mcp.json` |
`allowedMcpServers` |
`string[]` |
— | Enterprise allowlist (undefined = allow all) |
`deniedMcpServers` |
`string[]` |
— | Enterprise denylist (takes precedence over allow) |
`allowManagedMcpServersOnly` |
`boolean` |
`false` |
(Managed only) Only admin-defined MCP servers apply |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`hooks` |
`object` |
`{}` |
Custom commands before/after tool executions |
`disableAllHooks` |
`boolean` |
`false` |
Kill all hooks and statusLine execution |
`allowManagedHooksOnly` |
`boolean` |
`false` |
(Managed only) Block user/project/plugin hooks |
`allowedHttpHookUrls` |
`string[]` |
— | URL patterns HTTP hooks may target (supports `*` wildcard) |
`httpHookAllowedEnvVars` |
`string[]` |
— | Env vars HTTP hooks may use in headers |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`respectGitignore` |
`boolean` |
`true` |
`@` file picker respects `.gitignore` patterns |
`autoMemoryEnabled` |
`boolean` |
`true` |
Auto-save useful context to `.claude/memory/` |
`claudeMdExcludes` |
`string[]` |
`[]` |
Glob patterns for CLAUDE.md files to skip loading |
`cleanupPeriodDays` |
`integer` |
— | Days to retain chat transcripts (0 = keep forever) |
`plansDirectory` |
`string` |
`"~/.claude/plans"` |
Where plan files are stored |
`fileSuggestion` |
`object` |
— | Custom script for `@` file autocomplete |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`apiKeyHelper` |
`string` |
— | Script path that outputs auth values |
`awsCredentialExport` |
`string` |
— | Script that exports AWS credentials |
`awsAuthRefresh` |
`string` |
— | Script that refreshes AWS auth |
`forceLoginMethod` |
`"claudeai" | "console"` |
— | Force login via Claude Pro/Max or Console billing |
`forceLoginOrgUUID` |
`string` |
— | Organization UUID for OAuth login |
`otelHeadersHelper` |
`string` |
— | Script that outputs OpenTelemetry headers |

| Setting | Type | Default | What It Does |
|---|---|---|---|
`includeGitInstructions` |
`boolean` |
`true` |
Include git commit/PR workflow instructions in system prompt |
`attribution` |
`object` |
— | Customize attribution for git commits and PRs |
`autoUpdatesChannel` |
`"stable" | "latest"` |
`"latest"` |
`stable` = ~1 week old, skips regressions. `latest` = newest |
`skipWebFetchPreflight` |
`boolean` |
`false` |
Skip WebFetch blocklist check (enterprise) |
`sandbox` |
`object` |
— | Sandbox execution configuration |
`teammateMode` |
`"auto" | "tmux" | "iterm" | "in-process"` |
`"auto"` |
How agent team teammates display |
`worktree` |
`object` |
— | Config for `--worktree` sessions |
`env` |
`object` |
`{}` |
Environment variables for sessions (many hidden settings live here) |

These go inside the `"env"`

object and unlock settings not available as top-level properties:

| Variable | What It Does |
|---|---|
`CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY` |
Max parallel tool calls (default varies) |
`CLAUDE_CODE_DISABLE_AUTO_MEMORY` |
`1` to disable auto memory |
`CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS` |
`1` to disable git instructions |
`CLAUDE_CODE_EFFORT_LEVEL` |
Override effort level |
`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` |
`1` to enable agent teams |
`CLAUDE_CODE_ENABLE_TELEMETRY` |
`1` to enable telemetry |
`CLAUDE_CODE_DEBUG_LOG_LEVEL` |
`verbose` for debug logging |
`DISABLE_AUTOUPDATER` |
`1` to disable auto-updates |
`ANTHROPIC_MODEL` |
Runtime model override |
`CLAUDE_CODE_SUBAGENT_MODEL` |
Model for subagents |
