a sphragis-oss project ← sphragis.eu

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

01

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.

02

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.

03

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.

04

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.

05

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.

06

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.