Skip to content

itchernetski/claude-code-token-watch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Claude Code Token Watch

Three Claude Code hooks that warn when a session starts burning tokens on the same anti-patterns. The hooks don't block anything — they inject a system message that the model sees and usually self-corrects on the next turn (delegating to a sub-agent, switching to Edit instead of re-reading, etc).

Tested on macOS only. Should work on Linux (uses bash, jq). Windows is not supported.

What it does

Hook Triggers when Hint it gives
token-watch-read.sh The same file is Read 3+ times in one session Suggests keeping the file's structure in context and using Edit without re-reading
token-watch-bash.sh 3+ recursive searches per session (grep -r, find ... -name, rg ...) Suggests delegating the search to an Explore sub-agent
token-watch-webfetch.sh 3+ WebFetch calls per session Suggests delegating browsing to a general-purpose sub-agent

Why

On a Claude subscription (Pro/Max), the 5-hour rate limit is consumed by tokens, and tokens are consumed by everything that lands in the conversation context — files, search results, fetched pages, history.

Three patterns disproportionately blow up context:

  1. Re-reading the same file — each Read ships the whole file again, even if it's already in cache.
  2. Recursive grep/find from the main thread — every match line ends up in the main context.
  3. Long sequences of WebFetch — each fetched page lands in the main context as a wall of HTML/markdown.

These hooks count occurrences per session and, after the third hit, post a system message. The model treats system messages as instructions, so on the next turn it usually self-corrects without you having to interrupt and remind it.

Prerequisites

  • Claude Code with hooks support
  • bash
  • jqbrew install jq (macOS) or apt install jq (Linux)

Installation

1. Clone and copy hooks

git clone https://github.com/itchernetski/claude-code-token-watch.git
cp claude-code-token-watch/hooks/token-watch-*.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/token-watch-*.sh

2. Register the hooks in ~/.claude/settings.json

Merge the contents of settings.example.json into your existing ~/.claude/settings.json. If you don't have hooks configured yet, the file from this repo is a complete working example.

If you already have a PreToolUse array, add these three entries to it:

{
  "matcher": "Read",
  "hooks": [{ "type": "command", "command": "~/.claude/hooks/token-watch-read.sh" }]
},
{
  "matcher": "Bash",
  "hooks": [{ "type": "command", "command": "~/.claude/hooks/token-watch-bash.sh" }]
},
{
  "matcher": "WebFetch",
  "hooks": [{ "type": "command", "command": "~/.claude/hooks/token-watch-webfetch.sh" }]
}

3. Reload

Open the /hooks menu inside Claude Code (which re-reads the config) or restart the CLI. Existing sessions don't pick up new hooks automatically.

How it works

Each hook receives the full hook input JSON on stdin (with session_id, tool_name, tool_input). It appends a record to a per-session log under /tmp/claude-token-watch/<session_id>/ and counts how many times the same pattern has occurred. On the third occurrence and beyond, it prints a JSON object with a systemMessage field — Claude Code displays this to the user and forwards it to the model on the next turn.

State is isolated by session_id, so parallel sessions in different projects don't interfere with each other. The OS cleans /tmp/ on its own.

Customization

Change the threshold

The default warning threshold is 3 occurrences per session. To make it stricter (warn on the 2nd) or looser (warn on the 5th), edit the magic number in each script:

if [ "$TOTAL" -ge 3 ]; then       # ← change here

Change the language of the warnings

Out of the box, the warning messages are in Russian. To translate, edit the string inside the --arg msg "..." argument in each script. The message structure is the same in all three.

Disable a single hook

Comment out or remove its entry from ~/.claude/settings.json and reload via /hooks.

Disable all hooks temporarily

Set "disableAllHooks": true at the top level of your settings file. Note this disables every hook, including the ones from this repo and any others you have configured.

Verifying that the hooks are wired up

The cleanest test is to trigger the third occurrence yourself:

# Simulate three Reads of the same file
for i in 1 2 3; do
  echo '{"session_id":"test","tool_name":"Read","tool_input":{"file_path":"/tmp/foo.py"}}' \
    | ~/.claude/hooks/token-watch-read.sh
done

The third invocation should print a JSON {"systemMessage": "..."} to stdout. If you see a JSON output, the hook works. If not, check that jq is installed and the script is executable.

To verify the hook fires inside an actual Claude Code session, ask Claude to read the same file three times in a row. After the third read, the warning will appear inline in the transcript.

License

MIT

About

Claude Code hooks that warn when a session starts burning tokens on repeated Reads, recursive greps, or WebFetch streaks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages