Key takeaways

  • Run /statusline with a plain-English request, or add a statusLine entry to ~/.claude/settings.json that points to a script.
  • The script receives JSON on stdin with the model name, context window token counts and used percentage.
  • The status line runs locally and, per the docs, does not consume API tokens.

The Claude Code status line is a bar at the bottom of the terminal that runs a shell script you choose and prints whatever the script returns. To show the model and token usage, run /statusline with a plain-English request, or add a short script and a statusLine entry to ~/.claude/settings.json. The Claude Code docs describe both routes, and this guide follows them.

The status line runs on your machine and, according to the docs, does not consume API tokens. So you can show as much as you like without it adding to your usage.

How to set up a Claude Code status line the fast way

Type /statusline followed by what you want to see. The docs give this example:

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

Claude Code writes a script into ~/.claude/ and updates your settings for you. Approve the file edit prompts if it asks. To remove the status line later, run /statusline delete, or delete the statusLine field from settings.json by hand.

How to set up a status line by hand

You need jq, a command-line JSON parser, for the Bash version below. Python and Node.js scripts can parse JSON without it. The steps follow the docs, with the output line changed to show tokens. I ran this script in a test shell with mock JSON input, as the docs suggest. I did not run it inside Claude Code itself.

1. Save a script to ~/.claude/statusline.sh:

#!/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)
IN=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0')
OUT=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0')
echo "[$MODEL] ${PCT}% context | in ${IN} out ${OUT}"

2. Make it executable:

chmod +x ~/.claude/statusline.sh

3. Point Claude Code at it in ~/.claude/settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}

Claude Code reloads settings when you save the file, so the bar appears without a restart. With mock input of 15,500 input tokens, 1,200 output tokens and 8% context used, the script prints [Opus] 8% context | in 15500 out 1200.

You can also skip the file. The docs show an inline version that needs no script:

{
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
  }
}

Which fields show model and token usage

Claude Code sends session data to your script as JSON on stdin. These are the fields that matter for model and tokens.

Field What it holds
model.display_name, model.id The current model's name and identifier
context_window.total_input_tokens Tokens in the context window from the latest response, including cache reads and writes
context_window.total_output_tokens Output tokens from the latest response
context_window.context_window_size Maximum context size: 200,000 by default, 1,000,000 for models with extended context
context_window.used_percentage Share of the context window used, already calculated
context_window.current_usage The last call's tokens split into input, output, cache creation and cache read
cost.total_cost_usd Estimated session cost at list price, which may differ from your bill
rate_limits.five_hour.used_percentage Share of the 5-hour limit used (Pro, Max and Ultra subscribers only)

Two details trip people up. These counts describe the context window as of the last API response, not a running total for the session. And used_percentage counts input tokens only (input_tokens plus cache creation and cache read tokens), so output tokens do not move it.

Some fields can be empty. context_window.current_usage is null before the first API call and again after /compact, and the percentages can be null early in a session. That is why the script uses // 0 as a fallback. The rate_limits fields appear only for claude.ai subscribers and only after the first response, so read them with // empty.

When the status line updates

The script runs when a session starts or resumes, then again after each new assistant message, when /compact finishes, and when the permission mode or vim mode changes. Updates are debounced at 300 ms. If your bar shows time-based data, add "refreshInterval" to the statusLine block to re-run the command every N seconds, with a minimum of 1.

The optional padding field adds horizontal spacing in characters. Your script can print several lines, and can use ANSI color codes if your terminal supports them.

If the status line does not appear

The docs list these checks, in roughly this order:

  • Make sure the script is executable and prints to stdout, not stderr.
  • Run the script by hand with mock input: echo '{"model":{"display_name":"Opus"},"context_window":{"used_percentage":25}}' | ./statusline.sh
  • Accept the workspace trust dialog. Until you do, the status line stays blank.
  • Check for disableAllHooks set to true, or an organization-wide allowManagedHooksOnly setting, either of which can disable a custom status line.
  • On Windows with Git Bash, write paths in command with forward slashes. Backslashes are consumed as escape characters and the command fails without an error.
  • Run claude --debug to log your script's stderr and exit code.

A script that exits with a non-zero code, or prints nothing, leaves the bar blank. Keep it fast, because a slow script blocks updates.

What the status line does not replace

A status line shows the last response's numbers at a glance. For a fuller breakdown of where your tokens went, see our guide on how to check token usage in Claude. The docs also note that the /context command adds an estimate for messages sent since the last response, so it can read higher than the status line until the next response arrives.

Frequently asked questions

How do I show the model name in the Claude Code status line?

Read model.display_name from the JSON your script receives on stdin and print it. With jq, that is jq -r ".model.display_name". The /statusline command can also generate this for you.

Does the Claude Code status line use tokens?

No. The docs say the status line runs locally and does not consume API tokens.

Why is my Claude Code status line blank?

Common causes are a script that is not executable, prints nothing or exits with an error, an unaccepted workspace trust dialog, or disableAllHooks or allowManagedHooksOnly settings. Run claude --debug to see the script output and exit code.

How do I remove the Claude Code status line?

Run /statusline and ask it to delete or clear the status line, or remove the statusLine field from your settings.json.

Sources

  1. Customize your status lineAnthropic