Your agent isn't running out of context because of one big file. It is
running out because of accumulation: tool outputs, test logs, build logs,
repeated turns, and the same content pasted again in a slightly different
form. I kept watching sessions die on the tenth retry of the same failing
test — not because any single output was huge, but because nobody ever
threw anything away.
So I built Context Diet: an MCP server (plus a CLI) that shrinks the
content an agent actually sends, deterministically, with receipts. Every
output line is copied verbatim from the input. Every dropped line is
counted and categorized in a manifest. No model, no download, no data
leaves the machine.
What it does
Five tools, one promise — nothing invented:
-
diet_count— lines, bytes, and estimated tokens of a text. -
diet_dedupe— removes exact duplicate lines and repeated blocks. -
diet_extract— relevance-ranked excerpts for a query, with context around each hit. -
diet_summarize— an extractive summary to a token budget. It keeps headings, error and failure lines, and the first and last lines of each section. It never rewrites a word. -
diet_pack— the full pipeline: dedupe, then extract if you give it a query, then summarize to a budget, plus a manifest for every line.
The manifest is the point. A summary that silently rewrites your log is
a liability; a summary that says "kept 23 lines, dropped 54 as
duplicates, 4 in extraction, 88 in summarization" is something you can
diff and trust.
Measured, not claimed
On a real session log (verbose test runs, a README excerpt, a build
output — examples/session.log in the repo), packed to a 400-token
budget with the query test failure:
| Lines | Bytes | Est. tokens | |
|---|---|---|---|
| Before | 169 | 7,917 | 1,942 |
| After | 23 | 1,587 | 392 |
Token counts are estimates (a documented chars/4 rule); lines and
bytes are exact. The manifest adds up: 169 = 23 kept + 54 deduped + 4
extracted away + 88 summarized away. Verbatim: true.
How to run it
From source (the npm package arrives with the first npm publish):
git clone https://github.com/techdevfun/context-diet
cd context-diet
npm install && npm run build
node dist/cli.js pack --input examples/session.log --budget 400 --query "test failure"
As an MCP server over stdio, point your client at
node /path/to/context-diet/dist/server.js. The repo has a demo GIF
recorded from a real terminal session, CI on Node 20 and 22, and a test
suite that runs the server through a real MCP client.
How it compares (checked 2026-10-25)
This is a crowded corner, and the honest version is that each rival is
better at something:
- mcp-token-optimizer minifies code with AST awareness and restores formatting with Prettier. It works on code files; it does not touch logs, outputs, or conversation turns, which is where session context actually accumulates.
- LLMLingua / LLMLingua-2 compress harder (up to 20x on benchmarks) — but they need a model download and a Python/PyTorch stack, and their drops are unauditable at token granularity.
- Entroly claims 78% fewer tokens per request across whole codebases, with learned weights and a dashboard. That figure is self-reported, and the weighting is a black box: you cannot list exactly why a line was dropped.
- Vendor tool search / code mode (Claude Code deferral, Cloudflare Code Mode) report the biggest percentages, up to 99.9% — but they shrink tool definitions, not the content the agent accumulates. Different layer, complementary, not competing.
Where rivals beat us
Plainly: LLMLingua compresses harder than our typical 2–5x on logs.
mcp-token-optimizer understands code structure and restores formatting;
we treat code as text. Entroly covers whole codebases with a dashboard;
we are one focused pipeline. Vendor tool search fixes tool-schema bloat
at percentages we will never match, because that is not our layer. We
do not have those things in v1, and we do not claim them.
What we have instead is the one thing none of them offer: a
deterministic, auditable diet for session content, where every cut is
accounted for and nothing is invented.
Roadmap (not in v1)
LLM summarization (opt-in), model-based compression, AST-aware code
minification, cross-session cache, dashboard, auto-apply to agent
configs, JUnit/XML parsing, SARIF output, secret redaction.
Repo: https://github.com/techdevfun/context-diet — MIT licensed,
no account, no network, no model calls. If your sessions also die by
accumulation, try it on your own ugliest log and check the manifest.
Top comments (5)
The conservation arithmetic is the property worth building on: 169 = 23 kept + 54 deduped + 4 extracted + 88 summarized means a second tool can verify the compressor without rerunning it, the way double-entry bookkeeping lets you audit without redoing the work. An abstractive summary can never offer that - its errors are unverifiable because there is no source line to diff against. Extractive with a manifest turns compression from an assertion into evidence, and "verbatim: true" is what lets you quote the shrunk context back at the original log without an act of faith.
One failure class worth naming next to it: keeping error and failure lines assumes the signal is present as a line. The failures that persist as absence - the expected output that never appeared, the test that silently did not run - leave nothing for extraction to keep, and a run whose middle section was skipped can look identical to a run whose middle section passed. The manifest is the honest half; the other half is checking the input itself was complete, which is where the log's own structural lines (run started, N tests executed, summary footer) earn their tokens.
Sharp point — the manifest audits what was there, not what was missing. A skipped middle section can look identical to a passed one. Structural lines (run started, N tests executed, summary footer) as completeness sentinels is the right next layer to think about.
Exactly - and the sentinels get stronger when they arrive in pairs. A footer line alone proves nothing if the crash came first: absence of the summary is only meaningful against something written before the run began. "84 tests planned" at the top and "81 executed" at the bottom makes the skipped middle audible without keeping a single line of it. Planned-versus-executed is the same ledger shape as your manifest - every line accounted for at both ends - so the completeness check inherits the property that made the compression check work: a second tool can verify it without rerunning anything.
Prompting is the easy layer. The interesting work is in what happens after the model answers.
@arcwrightai Exactly — that's why every cut is accounted for in the manifest. The answer is only half the work; being able to verify what was kept and what was dropped is the other half.