context compression for agent tool outputs
The narrow passage your
tool outputs squeeze through.
A local context-compression layer for agent tool outputs: JSON field pruning driven by per-tool rules, text compression for log dumps, byte-level measurement, and reversible truncation. Nothing leaves your machine and nothing sits in the credential path.
# Homebrew (macOS / Linux)
brew install --cask sphragis-oss/sphragis/isthmos
# or with Go
go install github.com/sphragis-oss/isthmos/cmd/isthmos@latest why isthmos
Measure first, prune honestly
Measurement before rewriting
Verbose tool outputs are a large share of context on some workflows and a rounding
error on others. Shadow mode (ISTHMOS_SHADOW=1) logs what rules would save
on your real traffic before a single byte is rewritten.
Rule-based pruning
Tool names are glob-matched; listed keys are dropped recursively. max_items
caps arrays, max_str caps strings, min_bytes leaves small
payloads alone. When rules overlap, the strictest positive limit wins.
Text that keeps its errors
max_lines keeps head and tail, dedup collapses repeated lines
into a labelled count, and error-looking lines (error, panic,
traceback) are never dropped. That is what an agent is usually looking for.
Reversible truncation
Cut payloads are encrypted (AES-256-GCM) into a local store and the marker carries the
recovery command: isthmos reveal <id>. If the store cannot be
written, isthmos does not truncate at all.
Fail-open, out of the credential path
No proxy in front of your API keys. One static binary with a fast cold start, and any error means untouched passthrough. A replacement is only ever emitted when the result is strictly smaller.
Adapters, not lock-in
A native Claude Code PostToolUse hook, a generic filter mode
for anything that can pipe through a command, and an importable Go package. The core is
agent-agnostic.
quick start
Hook it, pipe it, check it
Claude Code (native hook)
{
"hooks": {
"PostToolUse": [
{
"matcher": "mcp__.*",
"hooks": [
{"type": "command",
"command": "$HOME/.local/bin/isthmos hook",
"timeout": 5}
]
}
]
}
}
Rewrites tool_response in place via updatedToolOutput. The
example points at $HOME/.local/bin; adjust it to wherever your install
landed (which isthmos, Homebrew uses its own prefix).
Any other agent
# stdin in, pruned stdout out
some-tool --json | isthmos filter -tool mcp__github__search_repos
# verify the wiring
isthmos doctor
Wire it into any wrapper, shell function, or orchestrator that can interpose a pipe.
doctor exits non-zero only when something is actually broken.
No config means no rewriting. Rules live in
~/.config/isthmos/rules.json; a missing file makes isthmos a deliberate
no-op. Start from rules.example.json, which covers Atlassian and GitHub MCP
noise fields.
measurement
Savings you can audit
Every invocation appends before/after byte counts to a local log, including calls the rules
left untouched. isthmos stats turns it into a savings table:
$ isthmos stats -since 168h
TOOL CALLS IN OUT SAVED SAVED% %ALL ~TOKENS REVEALS
mcp__atlassian__searchJiraIssuesUsingJql 42 1.9MB 0.6MB 1.3MB 68.4% 68.0% 340787 3
mcp__github__get_me 7 12.3KB 4.1KB 8.2KB 66.7% 0.4% 2099 0
TOTAL 49 1.9MB 0.6MB 1.3MB 68.4% 68.4% 342886 3 Honest denominators. SAVED% is local to a tool;
%ALL is the same saving as a share of every byte isthmos measured, so a flashy
local percentage cannot pose as an overall one. A rising REVEALS count means a
rule is over-pruned: loosen it instead of celebrating its SAVED%.
open source
Found a narrower path?
Isthmos is Apache-2.0 and built in the open. Pruning rules are the highest-value contribution: bring one backed by real before/after byte counts. And if it earns a place in your setup, a star helps others find it.