Developer tools#MCP#Coding agent#Agent memory
Headroom: compress tool output before it reaches the model
Headroom is a local context-compression layer that routes JSON, code and prose to different compressors, keeps originals retrievable and reports 57% savings.
Project facts
GitHub Ecosystem- License
- Apache-2.0
- Language
- Python
- Stars
- 75,879
- Data checked
- 2026-10-19
Snapshot figures reflect the check date and may change over time.

The token bill for a coding agent is rarely dominated by your prompt. It is the tool output: a hundred search results, thousands of lines of test logs, whole JSON payloads, files read twice. Headroom inserts a local compressor in between, routes each payload by content type, and sends the compressed version to the model. Originals stay on your machine and can be fetched back through headroom_retrieve. The repository uses Apache-2.0, is primarily Python, and had 75,879 stars on October 19, 2026.

Core features
- Five ways to attach: call
compress(messages)from the Python or TypeScript library; runheadroom proxy --port 8787as a local proxy that needs no code change in any language; wrap an agent withheadroom wrap claude|codex|cursor|aider|opencode|cline|zcode; install the MCP server forheadroom_compress,headroom_retrieveandheadroom_stats; or mount it as ASGI middleware and an adapter for LangChain or the Vercel AI SDK. - Routing by content type: CacheAligner first flags volatile content that would break a provider’s KV-cache prefix, ContentRouter decides whether the block is JSON, code or prose, and the matching compressor runs. SmartCrusher handles JSON arrays and keeps error items, statistical outliers and first/last boundaries; CodeCompressor is AST-aware for Python, JS/TS, Go, Rust, Java, C/C++, C# and PHP; Kompress-v2-base is the project’s own text model, with weights on Hugging Face.
- Compress only new bytes: live-zone compression touches only what arrived this turn, so the frozen prefix stays byte-identical and the provider cache still hits. CacheAligner only labels content; it never rewrites prompts.
- Reversible compression: CCR caches originals locally and lets the model retrieve them on demand. That is the substantive difference from summarizing old messages away — the information is still there.
- Output tokens too: two opt-in switches trim what the model writes back. Verbosity steering appends a “be terse, don’t restate context” note to the end of the system prompt, and effort routing lowers thinking budget when a turn only resumes after a tool result. Both are off by default; set
HEADROOM_OUTPUT_SHAPER=1to enable them. - Shared memory across agents: Claude, Codex, Gemini and Grok can share one store with automatic deduplication, and
headroom learnmines failed sessions and writes corrections intoCLAUDE.local.md,AGENTS.mdorGEMINI.md.
Typical use cases
- Anyone running long coding sessions daily: a refactor that reads files and runs tests repeatedly spends most of its window on tool output; compressing it stretches the same subscription further.
- SRE incident response: feeding logs and monitoring output from dozens of services to a model is exactly the scenario with the highest measured savings.
- Multi-agent workflows: compress context before passing it between subagents; SharedContext exposes the interface directly.
- Teams that want to measure the saving:
headroom dashboardbreaks down calls and savings per tool and model, andheadroom savingsruns the numbers against your own traffic.
Benchmarks
These four scenarios come from the README. They were measured with the provider tokenizer and the shipped compress(), run offline with a fixed seed, and the script is included (benchmarks/index_proof_table.py --seed 20260902), so the numbers are reproducible:
| Scenario | Before | After | Saved |
|---|---|---|---|
| Code search (100 results) | 17,199 | 13,597 | 21% |
| SRE incident debugging | 55,957 | 24,340 | 57% |
| Codebase exploration | 58,801 | 33,895 | 42% |
| GitHub issue triage | 46,067 | 32,429 | 30% |
The README reports compression cost of 0.21 ms p50 on a 10K-token JSON search result and 1.4 ms at 100K tokens. On accuracy, GSM8K and TruthfulQA at N=100 came out at ±0.000 and +0.030; the authors note the delta falls inside the confidence interval, so it is not a detected improvement. SQuAD v2 holds 97% at 19% compression and BFCL holds 97% at 32%. Read that as stated: highly repetitive payloads can clear 90%, while prose and already-dense output barely move.
Quick start
uv tool install --python 3.13 "headroom-ai[all]"
headroom wrap claude # wrap one coding agent
headroom proxy --port 8787 # or run a generic proxy
headroom doctor # confirm routing works
headroom dashboard # live savings, with the proxy running
Or use it as a library:
from headroom import compress
messages = [{"role": "user", "content": "Analyze these results"}]
result = compress(messages, model="gpt-4o")
Summary
It targets a real and increasingly expensive problem: most of what enters an agent’s context is boilerplate written for machines, but deleting it risks dropping the one line that matters. Headroom’s approach — compress locally, route by type, keep originals retrievable, hold the prefix stable — is considerably safer than truncation, and the adoption (75,879 stars) shows the demand.
Know the limits. An anonymous beacon is on by default and reports compression ratios, provider and model IDs, OS and architecture; it does not send prompts, completions, code or file paths, and HEADROOM_TELEMETRY=off, DO_NOT_TRACK=1 or HEADROOM_OFFLINE=1 turns it off. headroom wrap points traffic at the default upstream, so a third-party OpenAI-compatible provider needs --openai-api-url or your key goes to OpenAI and comes back 401. Short exchanges, prose and dense payloads see little or no reduction, and blocks under min_input_words return byte-identical. Environments that cannot run local processes are out of scope. For teams there is an open-source edition and a paid Enterprise tier, with model routing and prompt-injection detection on the paid side. Where context-mode moves tool output into a sandbox, Headroom keeps the original and shrinks the transfer; the two can be layered. Python, Apache-2.0.