open source · one Python file · runs on your machine

Your agent reads everything what matters.

Coding agents spend most of their tokens re-reading tool output: test runs, build logs, git output, JSON. headforward shrinks that output before the model sees it. Errors are always kept, and you keep using Claude Code exactly as before.

headforward hooks install global

First install it: pip install headforward · Quick start

Claude CodeClaude desktop appCodex CLIAiderAnthropic & OpenAI SDKs
Claude Code · Bash(make) · hook onbest case
cmdmake
raw300 lines, 8,722 characters
keptcompiling module... [x300]
keptBUILD OK: 300 modules
errorsalways kept
fullheadforward show ID
99%less on a repetitive build log
mixed real output: about 12% less
How it saves

Smaller context. Nothing dropped.

JSON becomes a table

Lists of same-shaped objects repeat every key on every row. headforward writes the keys once, the values as rows, and any value shared by every row just once. It rebuilds to the exact original.

Repeats become pointers

Agents re-read the same file and rerun the same tests. A tool result identical to an earlier one becomes a one-line pointer to it.

Logs lose the noise

Repeated lines collapse to one with a count. Terminal color codes, trailing spaces and runs of blank lines go.

Prompt caching keeps working

The same tool output always compresses to the same bytes and earlier turns never change, so Anthropic and OpenAI cache hits still land.

Measured

How much it saves depends on what your agent reads.

Data and logs shrink a lot. Source code is left exactly as written, so code-heavy sessions save less. Counted with OpenAI's o200k tokenizer.

92%fewer tokens

One API response: 30 order records as JSON, 1,112 → 90 tokens.

60%fewer tokens

A test session heavy on data: an API result fetched twice, 120 log lines, a file and a test run each repeated. 18,466 → 7,304 tokens.

14%smaller context on average, 30–36% with --smart

400 real coding-agent sessions from the public SWE-agent dataset, mostly reading and editing source code. --smart also recognizes lines the agent has already seen.

Your own numbers: headforward stats reports what Anthropic or OpenAI actually billed and what was saved.

What the model receives

Before and after, from the real tool.

API response

before · 479 characters
[
  {"id": 4101, "customer": "Ana Ruiz", "status": "shipped",
   "carrier": "DHL", "total": 18.5},
  {"id": 4102, "customer": "Ben Okafor", "status": "shipped",
   "carrier": "DHL", "total": 42.0},
  ... 2 more rows
]
after · 187 characters
{"_cols":["id","customer","total"],
 "_rows":[[4101,"Ana Ruiz",18.5],[4102,"Ben Okafor",42.0],
          [4103,"Chen Wei",9.99],[4104,"Dara Singh",61.25]],
 "_same":{"status":"shipped","carrier":"DHL"}}

Keys once, rows as values, shared values once. Rebuilds to the exact original.

Server log

before · 25 lines
INFO  GET /api/health 200 3ms
INFO  GET /api/health 200 3ms
... 22 more identical lines
ERROR POST /api/checkout 500: payment timeout
after · 2 lines
INFO  GET /api/health 200 3ms  [x24]
ERROR POST /api/checkout 500: payment timeout

Repeats become a count. The error is untouched.

Same test run, twice

before
(the full test output, sent again)
after
[Same output as tool call toolu_01 above.]

The first copy is still in the conversation, so nothing is lost.

Try it

Paste tool output or a prompt.

Runs entirely in your browser. The samples are examples; replace them with your own.

What the model sees
0%fewer tokens
0tokens saved
0saved if an agent reads this 1,000 times

Token counts here are estimates at about 4 characters per token. The script gives exact counts with tiktoken installed.

Three ways in

Pick the route that fits how you run Claude.

Hooks work everywhere Claude Code runs. The proxy routes also compress JSON and repeated reads, in the terminal and, with --https, the desktop app.

Hooks

Filter noisy commands

Tests, installs, builds, git log, ls -l and grep pass through the filter. Runs in every session, desktop app included.

headforward hooks install global
Always-on proxy

Compress every request

Starts at login (macOS) and serves Claude Code in every project. Add --https to reach the desktop app too. Off restores your settings.

headforward desktop on global
Wrap

One session at a time

Starts a private proxy, launches the agent pointed at it, and prints what you saved when you quit.

headforward wrap claude
Where it runsHooksAlways-on proxyWrap
Claude Code in a terminal✓ works✓ works✓ works
Claude Code in the desktop app✓ works✓ with --https– not launchable
Codex CLI, Aider– Claude onlyset the URL yourself✓ works
Your own SDK code– Claude onlyset the URL yourself–
Gateway chaining

Already using a gateway? headforward goes in front of it.

If your Claude Code settings already point ANTHROPIC_BASE_URL at a router, cost tracker or company proxy, desktop on takes that URL as its upstream, so nothing you rely on is skipped.

Claude Codeyour session
headforward127.0.0.1:8787shrinks tool output
Your gatewaye.g. 127.0.0.1:17322routing, logging, keys
Anthropicapi.anthropic.comthe model

Turn it on

# detects the existing URL and forwards to it headforward desktop on global headforward desktop status

Turn it off

# stops the proxy and puts your URL back headforward desktop off

An ANTHROPIC_BASE_URL exported in your shell beats Claude Code settings and skips the chain. headforward doctor tells you when that happens.

Compared

Fewer tokens, without hiding the failure.

The same 7 real command outputs from one Mac, run through each tool. A check mark means every key fact we looked for (failing test names, error lines, list items) was still there.

OutputRaw tokensrtkHeadroomheadforward
Unit tests, 2 failures1,89967 · failures hidden1,899 ✓293 ✓
git log --stat, 40 commits4,8691,271 ✓4,869 ✓3,800 ✓
grep, 1 file963258 · matches cut963 ✓963 ✓
grep across 3 paths4,9211,741 ✓3,150 ✓3,385 ✓
ls -la, large folder10,4453,077 ✓10,445 ✓7,264 ✓
System log, 600 lines37,040614 · error cut36,279 ✓21,070 ✓
JSON, 25 items2,63593 · 1 of 25 shown1,592 ✓1,388 ✓
Total saved62,77289% · 9 of 19 facts6% · 19 of 1939% · 19 of 19

rtk 0.43.0 command wrappers, Headroom 0.41.0 default compress(), headforward hook plus proxy. rtk saves its full output to a file the agent can read later. Small benchmark, written by the headforward author; reproduce with python3 bench/compare_tools.py.

Install

One command. No dependencies.

Python 3.9 or newer on macOS, Linux or Windows.

  1. Install from PyPI.

    pip install headforward

    No pip? Copy the script instead, save it as headforward.py, and run python3 headforward.py wherever this page says headforward.

    # macOS: save what you just copied pbpaste > headforward.py

    Linux: xclip -o -sel clip > headforward.py. Windows: paste into Notepad and save as headforward.py.

  2. Turn on the hook, then start a new Claude Code session.

    headforward hooks install global
  3. Check your setup. It says exactly what to fix.

    headforward doctor
  4. Optional: exact token counts.

    pip install "headforward[exact]"
Read the script before you run it
Loading…
Questions

Before you try it.

Does it change the model's answers?

The default rules are lossless: every compressed result can be rebuilt exactly, or points to an identical copy already in the conversation. Whether a model behaves the same on your work is something you can check: headforward eval replays your recorded requests with and without compression and compares the answers.

Is my API key or Claude sign-in safe?

The proxy runs only on your computer, listens on 127.0.0.1, and passes credentials straight to Anthropic or OpenAI. They are never stored or logged. In --https mode it decrypts only api.anthropic.com, with a local certificate that can vouch for nothing else; every other site gets a plain tunnel it never reads.

Does it break prompt caching?

No. Compression is deterministic and never rewrites earlier turns, so each request still begins with the same bytes as the last one and cache hits keep landing.

Does it work with claude.ai or chatgpt.com?

Those sites talk directly to their own servers, so no proxy can sit in between. You can compress text before pasting it: pbpaste | headforward - -l high | pbcopy on macOS.

How do I know it's working?

In a new Claude Code session, run something noisy like your tests. Shortened output carries a line such as [40 passing test lines omitted; full output: headforward show ID]. headforward stats counts every request it touched.

What if something goes wrong?

Undo it in one command: headforward hooks uninstall global or headforward desktop off. Both restore your Claude Code settings from a backup, and plain claude works exactly as before.

What does it cost?

Nothing. It's MIT-licensed, one Python file, no account and no telemetry.

Know before you run it

What it does not do.

  • It only touches tool output. Your messages and the system prompt reach the model unchanged.
  • Savings depend on the work. JSON-heavy and log-heavy sessions save the most. Sessions that mostly read source code save little, because code is left as written.
  • History often costs more. Every reply resends the conversation. /clear between tasks and /compact in long sessions save more than any filter.
  • The desktop app needs --https. Its Code sessions ignore ANTHROPIC_BASE_URL, so desktop on --https serves them as their HTTPS proxy instead. If that proxy is down, those sessions can't connect until you run headforward desktop off.
  • A shell variable wins. ANTHROPIC_BASE_URL exported in your shell overrides Claude Code settings, including the always-on proxy.
  • Codex with a ChatGPT login talks to ChatGPT's servers, not the API, so it bypasses the proxy. Use an API key login.
  • Chat apps in the browser (claude.ai, chatgpt.com) can't be proxied. Use the prompt compressor and paste.