Install
$ agentstack add mcp-open330-context-compress ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ● Filesystem access Used
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
context-compress
Stop drowning your AI agent in shell output. Large tool output stays searchable — not stuffed into the context window. Use it through an MCP server, a drop-in CLI, agent plugins, or all three.
[](https://github.com/Open330/context-compress/actions/workflows/ci.yml) [](https://www.npmjs.com/package/context-compress) [](https://nodejs.org) [](LICENSE) [](tsconfig.json) [](#contributing)
[Quickstart](#quickstart) · [Plugin Support](#plugin-support) · [Compression Modes](#compression-modes) · [vs RTK](#head-to-head-with-rtk) · [How It Works](#how-it-works) · [Configuration](#configuration) · [CLI](#cli) · [Changelog](CHANGELOG.md)
93% token reduction aggressive mode
Searchable raw data retained FTS5 + BM25
4 modes incl. LLM-judged auto • aggressive • balanced • conservative
Plugins Codex + Claude MCP • hooks • skills
Quickstart
# 1. Install
npm install -g context-compress
# 2. One-line setup — registers the MCP server, installs the hook,
# enables transparent Bash compression
context-compress setup --auto
# 3. (optional) Pick a mode for the session
export CONTEXT_COMPRESS_MODE=balanced # or: aggressive, conservative, auto
That's it. Restart Claude Code and shell output is now compressed before it enters context.
> Prefer no MCP at all? context-compress wrap "" compresses any shell command's output — drop-in for RTK. See [CLI](#cli).
Quickstart for AI agents — paste this prompt and your agent will install it
Install context-compress — an MCP server that compresses tool output for Claude Code.
Raw data stays in sandboxed subprocesses, only concise summaries enter your context window.
Saves ~99% of tokens on large outputs while keeping everything searchable via FTS5.
npm install -g context-compress
context-compress setup --auto
context-compress doctor
More info: https://github.com/Open330/context-compress
Why?
Every byte of tool output that enters your Claude Code context window reduces quality and speed. A single git log or npm test can dump 50KB+ into context — that's ~12,000 tokens gone.
context-compress intercepts these tools, processes output in a sandbox, and returns only what matters:
Before: git log --oneline -100 → 8.2KB into context
After: execute("git log ...") → 0.3KB summary + full data searchable in FTS5
It works in two modes that compose freely:
- MCP server — registers as a Claude Code MCP server with 8 tools (
execute,search,batch_execute,fetch_and_index,index,execute_file,stats,discover). Agents call them directly when output would be large. - Standalone CLI —
context-compress wrap ""runs any shell command and pipes the output through the same compression pipeline. Drop-in for RTK and friends. The PreToolUse hook can routeBashcalls through it transparently whenCONTEXT_COMPRESS_FILTER_BASH=1.
> Based on context-mode by Mert Koseoğlu — rewritten in TypeScript with security hardening, architectural improvements, and better DX.
Getting Started
Install
npm install -g context-compress
Plugin Support
context-compress now ships plugin metadata for agent hosts:
| Host | Files | What they enable | |:--|:--|:--| | Codex | .codex-plugin/plugin.json, .mcp.json, skills/ | MCP server registration plus skills in plugin-aware Codex flows. | | Claude Code | .claude-plugin/plugin.json, .claude-plugin/marketplace.json, hooks/claude-codex-hooks.json | PreToolUse routing, skills, and MCP config from a plugin install. | | Manual / fallback | context-compress setup --auto | Writes ~/.claude/settings.json directly when plugin installation is not available. |
The plugin manifests are designed for built package/archive installs where dist/, hooks/, and skills/ are present together. For a raw source checkout, run npm install && npm run build before testing the plugin locally, or use the global npm setup above.
One-line setup
context-compress setup --auto
Writes ~/.claude/settings.json for you: registers the MCP server, installs the PreToolUse hook, enables transparent Bash compression. Idempotent — re-running with the same paths makes zero changes. Preserves any unrelated user settings.
Manual setup
claude mcp add context-compress -- node $(which context-compress)
Or add to your project's .mcp.json:
{
"mcpServers": {
"context-compress": {
"command": "node",
"args": ["/path/to/context-compress/dist/index.js"]
}
}
}
Verify
context-compress doctor
How It Works
┌─────────────────────────────────────────────────────────┐
│ Claude Code │
│ │
│ "Run tests" ──→ PreToolUse Hook intercepts │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ context-compress │ │
│ │ MCP Server │ │
│ └────────┬─────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Executor │ │ Store │ │ Stats │ │
│ │ (11 lang)│ │ (FTS5) │ │ Tracker │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ ▼ ▼ │
│ Raw output Indexed & Only summary │
│ stays here searchable enters context │
└─────────────────────────────────────────────────────────┘
8 MCP Tools
| Tool | What it does | |:-----|:-------------| | execute | Run code in 11 languages. Only stdout enters context. | | execute_file | Process a file via FILE_CONTENT variable — file never enters context. | | index | Chunk markdown/text into FTS5 knowledge base for search. | | search | BM25 search with Porter stemming → trigram → fuzzy fallback. | | fetch_and_index | Fetch URL → HTML-to-markdown → auto-index. Preview only in context. | | batch_execute | Run N commands + search in ONE call. Replaces 30+ tool calls. | | stats | Session + cumulative statistics: bytes saved, tokens avoided, savings ratio. | | discover | Lists indexed sources, top searchable terms, and suggests next actions. |
Supported Languages
javascript · typescript · python · shell · ruby · go · rust · php · perl · r · elixir
> Bun auto-detected for 3-5x faster JS/TS execution.
Compression Modes
context-compress offers four compression modes that trade fidelity for compactness. Pass --mode to the CLI, set CONTEXT_COMPRESS_MODE in your environment, or let the default (balanced) just work.
| Mode | Strategy | Use when | |:--|:--|:--| | conservative | ANSI strip only — preserves every byte of meaningful content | You need full fidelity, debugging output, archival logs | | balanced (default) | Strip noise (progress bars, deprecation warnings, hint lines) — keep metadata (commit bodies, file dates, full test failures) | Day-to-day agent work where context might be re-read | | aggressive | Drop metadata too — git log → oneline, ls -la → name+size, find lower threshold, grep grouped | Maximum token savings; agent will rarely need the dropped detail | | auto | An LLM (Anthropic API or claude -p) picks one of the above per command, based on a 500-byte sample of the output. Decisions cached for 24h | You don't want to think about it — let the model judge per output |
# CLI flag (per-call override)
context-compress wrap --mode aggressive "git log -50"
# Env var (set once for the session)
export CONTEXT_COMPRESS_MODE=aggressive
The PreToolUse hook also forwards CONTEXT_COMPRESS_MODE automatically when wrapping Bash commands, so agents transparently get whatever mode you've configured.
Beyond mode selection
Three capabilities layer on top of the modes above. All are grounded in the 2026 agent-compression literature, whose central finding is that token-level extractive compression (LLMLingua-2, Selective Context) breaks agents by destroying action grammar — so context-compress only ever operates on whole structural units, never partial tokens.
- Format-aware compression — when no command-specific filter matches, output is compressed by its shape. Pretty-printed JSON is minified losslessly (balanced) or collapsed to a schema + sample (aggressive); NDJSON folds into per-shape summaries; repetitive logs fold into
template ×countvia variable masking (Drain-style). Error/warning lines are always kept verbatim, and balanced-mode JSON stays parseable. Typical wins: JSON −41% (still valid) to −96%, logs −98%. - Intent-conditioned summaries — pass
intenttoexecuteand large output is indexed, then the top query-ranked sections are inlined up to a byte budget (CONTEXT_COMPRESS_INTENT_BUDGET_BYTES, default 1800) instead of only listing section titles — fewer follow-upsearch()round-trips. Error lines are surfaced as a safety net. - Self-tuning
automode (ACON-style) — when a command is compressed aggressively and then re-run fast (≤30s) repeatedly,autorecords the "regret" and downgrades that command one step to preserve fidelity. Downgrades only ever reduce compression, so a false positive costs tokens, never correctness. See the self-tuning table instats.
Verify fidelity yourself with the quality-regression benchmark, which measures survival of task-critical information, not just token ratio:
npm run bench:quality # report at docs/quality-regression-report.md
Head-to-head with RTK
Reproduce locally:
git clone https://github.com/rtk-ai/rtk /tmp/rtk && (cd /tmp/rtk && cargo build --release)
RTK_BIN=/tmp/rtk/target/release/rtk tsx scripts/benchmark-vs-rtk.ts
Result on this repository (RTK 0.39.0 vs context-compress 2026.5.0):
| Command | Raw | RTK | CC conservative | CC balanced | CC aggressive | CC auto (LLM) | |:--|--:|--:|--:|--:|--:|--:| | git status | 577 B | 241 B (58%) | 577 B (0%) | 375 B (35%) | 187 B (68%) | balanced (35%) | | git log -10 (full) | 21.3 KB | 3.2 KB (85%) | 21.3 KB (0%) | 4.6 KB (79%) | 947 B (96%) | balanced (79%) | | git log -50 (full) | 36.9 KB | 10.1 KB (73%) | 36.9 KB (0%) | 12.3 KB (67%) | 3.2 KB (91%) | balanced (67%) | | git diff --stat | 425 B | 424 B (0%) | 425 B (0%) | 425 B (0%) | 425 B (0%) | balanced (0%) | | ls src/ | 149 B | 229 B (-54%) | 149 B (0%) | 149 B (0%) | 149 B (0%) | conservative (0%) | | ls -laR src/ | 3.8 KB | 229 B (94%) | 3.8 KB (0%) | 3.1 KB (19%) | 877 B (78%) | aggressive (78%) | | find *.ts | 1.0 KB | 589 B (44%) | 1.0 KB (0%) | 183 B (83%) | 183 B (83%) | aggressive (83%) | | npm test | 21.8 KB | 114 B (99%) | 16.7 KB (24%) | 120 B (99%) | 120 B (99%) | balanced (99%) | | Overall (byte-weighted) | 85.9 KB | 15.0 KB (82.5%) | 80.8 KB (6.0%) | 21.2 KB (75.4%) | 6.0 KB (93.0%) | 19.0 KB (77.9%) |
Three things to take from this table:
balancedis competitive on its own. The default mode hits ~75% reduction without dropping any metadata — agents get full commit headers, file perms/dates, and complete test failure detail. Only 7pp behind RTK while making a different fidelity trade-off.aggressivedecisively wins on raw compression — 93.0%, beating RTK by 10.5pp. Pick this when you want maximum token savings and the agent will rarely re-read the dropped detail.autolets the model pick. Per-command LLM judgment landed at 77.9% overall — between balanced and aggressive. The interesting result is what it picked:balancedfor git/test outputs (where commit bodies and failure detail matter),aggressiveforls -laRandfind(where the question is "what's there?", not "show me everything"),conservativefor tiny outputs where compression is pointless.
Aggressive mode covers a wider command surface than the table above hints — it also handles df (drops pseudo-filesystems), du (top-N by size), ps aux (PID/%CPU/%MEM/CMD only, drops kernel threads), npm ls (strips tree-drawing chars + deduped/extraneous markers), and grep/rg (groups by file, truncates long lines).
What balanced now does (over conservative):
ls -l*dropstotal N,./..entries (universal noise) but keeps perms/datesgit logkeeps headers + first 3 body lines per commit, replacing the rest with[+N lines omitted]find/ls -Rsummarizes per-directory once output exceeds 20 entries- Generic dedup/progress/group runs at 5KB instead of 10KB
> RTK has a single fixed compression strategy — comparable to context-compress aggressive. context-compress lets the agent choose: reach for aggressive when the question is "what changed", balanced when the question is "explain why".
Token Reduction
context-compress achieves 99.2% token reduction across a typical 12-operation coding session.
| Operation | Before | After | Reduction | |:--|--:|--:|--:| | Read bundled file (776KB) | 194,076 tok | 105 tok | 99.9% | | Playwright snapshot (56KB) | 14,000 tok | 75 tok | 99.5% | | Read CSV/JSON data (100KB) | 25,000 tok | 125 tok | 99.5% | | Read source file (21KB) | 5,250 tok | 88 tok | 98.3% | | npm install log (15KB) | 3,750 tok | 50 tok | 98.7% | | curl API response (12KB) | 3,000 tok | 88 tok | 97.1% | | npm test (42 tests) | 935 tok | 45 tok | 95.2% | | batchexecute (5 cmds) | 6,250 tok | 375 tok | 94.0% | | fetchand_index (45KB page) | 11,250 tok | 750 tok | 93.3% | | grep (small output) | 361 tok | 361 tok | 0% | | Session Total | 267,121 tok | 2,223 tok | 99.2% |
Without context-compress, 12 operations consume 133% of the 200K context window — overflowing it entirely. With context-compress, the same operations use 1.1%, leaving 98.9% free for actual conversation.
> Data isn't deleted — it's indexed in FTS5 and searchable on demand. Small outputs ( server.ts is now thin (132 lines) — it constructs deps, builds a ToolContext, registers the 8 tool modules, and wires shutdown. All tool handlers live under src/tools/, all reusable helpers under src/util/.
Security
| Threat | Mitigation | |:-------|:-----------| | Credential leakage | passthroughEnvVars defaults to [] — zero env vars passed to subprocesses unless opted in | | Shell injection | execFileSync with array arguments throughout — no string interpolation into shells | | SSRF / private-IP fetch | fetch_and_index blocks RFC1918, link-local, loopback, IPv4-mapped IPv6 (incl. hex form ::ffff:HHHH:HHHH), CGNAT | | DNS rebinding (TOCTOU) | resolveAndValidate + URL pinning to the resolved IP with original Host header preserved | | Path traversal | isWithinProject uses realpathSync to defeat symlink escapes; falls back to string-prefix for not-yet-existing paths | | Hook self-modification | Hooks are read-only — no fs.writeFileSync in src/hooks/. Hook integrity SHA-256 verified by doctor | | Arbitrary code execution | No upgrade command — no git clone or npm install at runtime. Setup writes only to ~/.claude/settings.json | | Silent failures | CONTEXT_COMPRESS_DEBUG=1 surfaces all catch-block errors to stderr | | Subprocess sandboxing | OS-level sandboxing not enforced (by design for the MCP
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Open330
- Source: Open330/context-compress
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.