An article, How I Cut Claude Code Token Usage by 90%+ With 5 Tools, Custom Hooks, and Enforcement (Medium, published 21 April 2026, updated 8 June 2026), promises to cut Claude Code token use by more than 90% with five tools, a set of hooks, a rewritten CLAUDE.md and an installer script. One reader's anecdote, from a run on two machines, is around 45,000 extra tokens at session start and no improvement, and the security response under it is more useful than the installer. The gap comes from a model of token use that is out of date, and from savings that work by hiding the evidence you'd need to check the result.
On the course, I ask engineers to show the checks they ran before accepting an assistant's work. I don't score token use. A low token count tells me very little if the change still needs to be checked or repaired, so I want to know the cost of getting to a verified result. That's how I've looked at the five tools in this article. Some may be useful, but I'd first try the settings Claude Code already provides.
Costs
For each request, Claude Code sends the system prompt, your CLAUDE.md files, the conversation it has retained and your new message. There is no separate memory at the model end between those requests. When space runs short, Claude Code clears older tool results before summarising the conversation (context management). Much of what it sends will match the previous request. Prompt caching lets the API charge about a tenth of the normal input rate for that matching prefix. New material costs more: writing it to the five-minute cache costs 1.25 times the base input rate, or twice the base rate for the one-hour cache (how Claude Code uses prompt caching, prompt caching prices).
The cache is a prefix match, so a change anywhere earlier in the request invalidates everything after it. Switching model or effort level, turning on fast mode for the first time in a conversation, changing tool definitions that were loaded upfront and a Claude Code upgrade each cause one re-read of the conversation billed as a new cache write rather than a read at a tenth of the rate (connecting, disconnecting or changing deferred MCP tools appends content instead and keeps the cached prefix). A warm prefix isn't guaranteed even then: the entry can expire between requests, and a changed cache key writes a fresh one. Deep into a long session, one full re-read can be the most expensive request you send.
A fair amount loads before you type anything: the system prompt, CLAUDE.md, auto memory, one-line skill descriptions and the names of your MCP tools. Run /context and it shows you the breakdown (explore the context window).
MCP tool definitions are where the original article's model has gone stale. Those definitions used to load in full, and Anthropic's own example, a setup connecting GitHub, Slack, Sentry, Grafana and Splunk, comes to about 55,000 tokens before any work starts. With the current default, startup includes the tool names and server instructions. Claude gets a tool's full schema when it searches for that tool. If your setup still loads schemas upfront, look for ENABLE_TOOL_SEARCH=auto: that setting waits until definitions exceed 10% of the context window before deferring them. Anthropic puts the typical saving from deferral at over 85%. It also reports poorer tool selection beyond 30 to 50 available tools (tool search tool, scale with MCP tool search). You still pay for server instructions and tool names. Schemas add to the conversation as they are requested, unless deferral has been turned off and they all load at the start. The documented ways to end up there are ENABLE_TOOL_SEARCH=false, the CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS variable, marking a server or tool alwaysLoad (which exempts just what it names), denying the ToolSearch tool, a model or deployment without tool reference support (older than the Claude 4.5 generation, or Claude through Azure-hosted Microsoft Foundry), and pointing ANTHROPIC_BASE_URL at a host other than Anthropic's, which you can override by setting ENABLE_TOOL_SEARCH yourself. Keep that last one in mind.
The results of the work add more input: files you read, searches you make and logs from commands or tests. A 500-line file can be a few thousand tokens on its own. Bash results are especially easy to underestimate if you only see the terminal notice. Claude Code can include roughly 30,000 characters of successful output before saving it in the session directory and returning a preview with a path. A failure gets a different treatment: roughly 10,000 characters from the beginning and end, without a saved-file path (output limits). Add Claude's replies and reasoning, charged as output tokens, and you have the two costs these tools aim to reduce.
Layers
The original stacks five tools and a set of hooks. Each one is a real project with a real use, and in most cases the project's own documentation is more careful about what it saves than the article is. For each layer, the first paragraph below is what it does and the second is what its own documentation adds.
Codebase Memory MCP
An MCP server with 15 tools. It parses the repository with tree-sitter into a graph of functions, classes, call chains and routes, and answers structural questions from the graph instead of from file reads.
The project publishes SHA-256 checksums and signed releases, and its own install scripts verify the checksums before extraction. The article's installer downloads the binary from the latest release and runs it without checking either.
context-mode
An MCP server with 11 tools plus hooks on six lifecycle events. Its ctx_execute runs supplied code in a subprocess and normally returns what the code prints. With a stated intent and more than about 5KB of output it indexes the full output in a local SQLite database and returns excerpts, without one the automatic indexing starts above 100KB, and ctx_batch_execute indexes every command (its execution path).
Read the security notes before treating that subprocess as a sandbox. It inherits your filesystem and network access. The database can contain prompts, decisions, errors and file activity, so choose its storage location accordingly. There is an interesting qualification in the README about short replies: it declines to enforce them, citing a Moonshot employee's account of two internal benchmarks where brevity prompts hurt coding and reasoning. We have no public reproduction of those results.
RTK
RTK is written in Rust and sits in front of Bash commands through a rewriting hook. Ask for a test run and the model gets the failures and a pass count. Ask for git status and it gets a compact list grouped by status.
A failed command also gets a saved failure log, within RTK's size and retention limits. Check those limits before relying on the file being there later. RTK only handles Bash output, and its README is clear that this accounts for only some of the input tokens in a session.
Headroom
With Headroom, requests go through a local proxy before reaching the API. The wrapper makes that happen by changing ANTHROPIC_BASE_URL. The proxy then compresses new tool output. Check the registrations it adds too: Serena is installed at user scope for code navigation unless you opt out.
According to its documentation, the default coding profile leaves earlier turns byte-identical to preserve cache hits. It temporarily stores the original output locally, giving the model a way to retrieve it. The proxy also decides whether a request has enough tools to use its own tool deferral.
Caveman
Caveman asks Claude to answer in short fragments. It also supplies a command to rewrite CLAUDE.md that way.
The README presents this as a way to make replies quicker and easier to read. There is an input cost, though: the skill adds 1,000 to 1,500 tokens per turn. If the replies were already short, the README says the net saving can be negative.
The hooks
Try following the gate hook in the companion repository. It intercepts the first call to Read, Grep, Glob or Search, blocks it and asks Claude to query the graph. The next call goes through, even if Claude ignored the request to use the graph. That is the extent of the enforcement. Another hook blocks Bash commands including cat, grep and find, telling Claude to use Read and Grep instead. I can see why someone might prefer those tools, but their results still enter the same conversation. For a quick lookup, the extra restriction can just get in the way.
A reader reported a different result. Their test of the full stack on two machines added around 45,000 startup tokens without improving the answers to simple questions. In reply, the author acknowledged the startup cost.
There are 26 tool definitions across the two servers, plus Serena's through the wrapper. According to Claude Code's documentation, a non-Anthropic base URL disables tool search. Most proxies cannot forward the tool reference blocks it needs. Headroom's issue tracker has an example of the cost. In June 2026, a user opened /context with and without the proxy. It showed about 25,000 extra startup tokens with the proxy: MCP tools previously marked as loading on demand now had individual token counts, and deferred built-in tools had also loaded in full (Headroom issue 746). The maintainers traced it to deferral and updated headroom wrap to set ENABLE_TOOL_SEARCH. Whether the reader's build predated that fix I can't tell, and that is the point: the stack changed the thing that decides the startup cost, and the published article reported no startup measurement. /context settles the first half, since with deferral on its MCP section says the tools load on demand and shows no per-tool cost. What it can't show is what the proxy does to the request afterwards, and for that you need the numbers the API reports back, input tokens plus cache reads and writes, which /usage (/cost is an alias) and a status line both show, for the same first prompt with and without the wrapper.
The graph project's 99.2% five-query claim deserves the same treatment (the Medium headline is 90%+). It comes from five structural queries against the graph, about 3,400 tokens, compared with a file-by-file baseline reading files one by one for the same answers, about 412,000, and you can already beat that baseline without a graph: Anthropic's code intelligence plugins give Claude go-to-definition for typed languages, so one call replaces a search and a run of candidate file reads (reduce token usage). A graph server may still earn its place on a large codebase. The project's evaluation across 31 repositories reports ten times fewer tokens than file-by-file exploration at an answer quality of 83% against 92% for the file approach, with the answers graded by hand by the first author. A reported saving, a long way short of 99%, and the gap you'll see is the one between it and the next-best method.
Evidence
Here is the test I'd apply to every layer.
If a saving means that neither you nor the model saw the output of a check, the check didn't count.
It can be a fine saving for exploration, and it's a bad one for verification.
Suppose a test fails in a context-mode run with an intent set. Beyond the indexing threshold, Claude sees excerpts of the output. It can search for more, but it has to know what to search for. A failure that uses unexpected wording may never come back in those results. The filter in Anthropic's cost-guide hook makes the problem easier to see: it pipes the test command through grep -A 5 -E '(FAIL|ERROR|error:)' | head -100. Nothing printed could mean the tests passed, or that no tests were collected at all. The pipeline also hides the original exit status. I want the command, status, counts and failing names kept together so I can distinguish those outcomes. RTK's test filter keeps the pass count and names of failures, and saves a failure log within its retention and size limits.
Compaction is the same category. It replaces the tool results in your window with a summary the model wrote, and the stack's settings ask for it at half the auto-compact window (the docs say that override applies only in sessions that already compact before the hard limit), so where it applies the evidence leaves the conversation earlier and more often, and you pay for more summarising requests. Compaction has its place, at a natural break between tasks and with a focus instruction for what to keep. When you're abandoning a path, /rewind truncates back to a point that's already cached and keeps the record intact.
I would be reluctant to make CLAUDE.md harder to understand for the saving on offer. Shortening it may remove a few hundred tokens from every request, but those tokens are normally in the cached prefix. On a warm turn they cost a tenth of the base input rate, with the higher cache-write charge applying when the cache is cold. An ambiguous instruction can easily cost more to resolve. Keep the file under the documented 200-line recommendation and move instructions for particular workflows into skills that load when used.
Subagents are a useful exception. Give one a noisy job and, as Anthropic recommends, let it keep the long tool output in its own conversation. I would still ask for enough detail to check its conclusion: the exact command, exit status, counts and failing names. Save the full log with tee and set -o pipefail, otherwise tee's status can hide the command's failure. Before a merge that depends on the result, read the saved log yourself.
Security
A commenter on the original was right about this part, and the author has since added a security section to the article. The detail is still worth setting out, because the same shortcuts appear in a lot of shared configurations.
The shipped settings set the permission mode to auto and switch on both skipDangerousModePermissionPrompt and skipAutoPermissionPrompt. Auto mode means a separate classifier model reviews actions instead of you. Anthropic's documentation says it reduces prompts and does not guarantee safety, and on current versions for Pro, Max and Team plans it is the starting mode anyway (permission modes). The first skip flag pre-accepts the one-time dialog in which you take responsibility for bypass-permissions mode, a mode these settings don't turn on and a flag the settings schema says the CLI normally manages itself. The second appears in neither the settings documentation nor the schema, so what it suppresses is undocumented, which is its own reason not to copy it. The course rule is that you never delegate more than you can verify.
A permission prompt is often the only moment you see a command before it runs.
Handing that moment to a classifier is a legitimate choice for some work. Make it knowingly, and put something in its place: a sandbox or container, or allow rules for the named commands you've decided to trust.
The installer installs Headroom through pipx (falling back to pip) and RTK separately, through Homebrew when it's available and otherwise by piping RTK's current master install script into sh (Headroom stopped bundling RTK in July 2026). RTK's own installer verifies the downloaded archive's checksum, but the companion's direct Windows RTK download and its moving latest Codebase Memory download verify nothing, skipping the checksums and signatures the graph project publishes, and a helper runs npx -y flutter-driver-mcp, unpinned, whenever an E2E runner definition or the synchronisation helper itself is edited. The wrapper replaces your claude command with a shell function that starts a proxy through which every request passes, code and pasted secrets included, and registers Headroom's own MCP server, plus Serena at user scope when uvx is available and you haven't opted out. All of it runs locally and all of it is published source (context-mode is under the Elastic License, Caveman's engine under BSL 1.1, and the rest use open-source licences), and it is still a set of privileged components trusted on the strength of a blog post. A hook moves Claude's memory files into the repository at .claude/memory and points a symlink there from ~/.claude/projects. It does not update .gitignore. Check whether the repository or your global excludes already ignore .claude/memory/, because otherwise git add -A will stage those files. Whatever Claude remembered, potentially including keys or pasted credentials, would then be ready for the next push.
The missing controls are fairly ordinary ones: versions pinned before installation, checksums checked after download, and an ignore rule for the memory directory. The companion does none of those for its direct downloads, npx helper and memory hook respectively. Add them before running it, and decide which permission prompts you are willing to replace.
Instead
- Take a baseline. Before the first prompt, open
/contextand note what loaded. After a prompt, read the input tokens, cache writes and cache reads in/usage(also available as/cost). A status line can display these as you work. If you add very little new content but keep paying for large cache writes, investigate that first. The prefix may be changing, the entry may have expired, or the cache key may have changed. A sudden drop in reads without a/cleardeserves the same check. - Check deferral behind a proxy. Changing
ANTHROPIC_BASE_URLdisables Claude Code's tool deferral unlessENABLE_TOOL_SEARCHis also set. Headroom's wrapper takes care of that, respecting an existing value and defaulting to off on Foundry. A proxy configured by hand may not. Before settingENABLE_TOOL_SEARCH=truefor an organisational gateway, establish that it forwards tool reference blocks, because requests fail if it cannot. Then compare the API token figures. - Keep servers out of the main conversation. Disable the ones a project doesn't need from
/mcp. Prefer a CLI such asghorawswhere one exists, since it adds no listing at all. Scope a specialised server to the subagent that needs it by defining it inline in the agent'smcpServersfrontmatter, since a string reference reuses a parent-configured connection, and the parent conversation never sees its tools (subagents). ReservealwaysLoadfor the handful of tools used on every turn. - Read your startup files. CLAUDE.md should stay under 200 lines. Put the longer workflow instructions in skills, and review auto memory too: up to the first 200 lines or 25KB of MEMORY.md enter each session.
- Ask a smaller question. Try
git diff --statbefore reading selected files, or name the failing test instead of running a whole suite. For pytest,pytest -q --tb=shortcuts routine noise while keeping a short traceback. You get less output without a separate tool deciding which parts matter. The usual inline limits are about 30,000 characters for successful Bash output and 25,000 tokens for MCP output. Beyond those, a saved file and reference take its place (MCP output limits). If you lower the limits as the stack does, expect more trips back to those files. - Give a subagent the noisy job. Ask it for the evidence described above and a saved full log.
- Choose when to reset. For unrelated work, use
/clear. It sends no model request on its own, though the next prompt pays the usual processing and cache costs for a fresh context. To abandon an approach, use/rewind. Save/compactfor a useful break and tell it what needs to survive. Choosing the model and effort level at the start avoids later switches that re-read the conversation at the cache-write rate. Reasoning is charged as output, so choose less effort for an easy task and more for a difficult one. - Plan before large changes. Plan mode explores and proposes before anything is edited, which is cheaper than re-work after the wrong first approach, and a specific prompt beats a vague one for the same reason.
- Check what the cache setting does for you. On a subscription the cache already lives for an hour, dropping to five minutes while you're drawing on usage credits. On an API key it lives five minutes, and
ENABLE_PROMPT_CACHING_1H=1extends that with cache writes billed at twice the base input rate instead of 1.25 times, which pays off only when your gaps between requests often fall between five minutes and an hour.
Gateways
There's a second way to keep tool definitions out of the session, which is to put one server in front of many APIs so the agent sees one small surface. Plasm is a recent example I've been following closely. Its agent languages entry describes it as treating agent integration as a language and plan problem rather than a transport problem: a capability graph schema maps each API's entities, relations, queries and effects, with typed inputs and outputs per action, the agent writes a short program over session-scoped symbols copied from a live teaching table rather than memorising vendor field names, and the same program string is reviewed as a dry run before it executes live. It reaches Claude Desktop and Cursor as a single MCP server (there is a CLI client too, compiling to the same plan representation), and its makers claim its tool descriptions come out around five times smaller than the equivalent JSON schemas. That figure is the vendor's, from its own packaged setups.
I haven't run it on real work yet, and the project is early: the core runtime, PlasmTools/plasm-core, is a Rust compiler and runtime dual-licensed under MIT and Apache-2.0, at version 0.4.45 with six repository stars when I checked on 21 August 2026. Its conformance testing is an executable language matrix run against fixtures rather than production APIs, which its entry notes is not a complete verification story. What I like is the shape of it. A plan you review before it runs is bounded delegation in tool form, and the saving comes from sending less, with nothing summarised after the fact. What I'd check before trusting it is the same as for any gateway. Read the trace rather than the plan's description of itself, and confirm that tools reaching you through an HTTP gateway are being deferred: one user whose HTTP MCP server fronted a gateway of about 250 tools reported 120,000 tokens loading upfront on every session even with tool search enabled, and the issue was closed as stale by a bot (issue 40314). The catalogue and its mapping layer are now part of what you're trusting, so read those too.
Start with /context today and read what's in the window before your first prompt. Then make the cheapest change that doesn't touch the evidence, and measure it with the numbers the API reports.
The verification rule in this article is Module 1 of San Digital's AI-Assisted Engineering course, and the delegation rule is Module 3. Context and cost get a module of their own later in the programme.