Keep your context window lean. Let the sandbox do the heavy lifting.
A context-aware MCP server for Claude Code that compresses tool output by processing it in isolated subprocesses. Raw data stays in the sandbox — only concise summaries enter your context window.
Quickstart for Agents · Getting Started · How It Works · Configuration · CLI · Changelog
Install context-compress — a context-aware MCP server that compresses tool output
for Claude Code. It keeps raw data in sandboxed subprocesses so only concise
summaries enter the context window. Supports 11 languages (JS, TS, Python, Shell,
Ruby, Go, Rust, PHP, Perl, R, Elixir) with FTS5 search and smart truncation.
Steps:
1. Run: npm install -g context-compress
2. Run: claude mcp add context-compress -- node $(which context-compress)
3. Run: context-compress doctor # verify runtimes, hooks, FTS5
4. Optionally create .context-compress.json with:
{ "passthroughEnvVars": ["GH_TOKEN"], "debug": false }
After setup, the PreToolUse hook auto-redirects data-fetching tools through
the sandbox. Use execute() instead of Bash for large outputs, execute_file()
instead of Read for large files, and fetch_and_index() instead of WebFetch.
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
Based on context-mode by Mert Koseoğlu — rewritten in TypeScript with security hardening, architectural improvements, and better DX.
npm install -g context-compressclaude 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"]
}
}
}context-compress doctor┌─────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────┘
| 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 |
Real-time session statistics: bytes saved, tokens avoided, savings ratio. |
javascript · typescript · python · shell · ruby · go · rust · php · perl · r · elixir
Bun auto-detected for 3-5x faster JS/TS execution.
| context-mode | context-compress | |
|---|---|---|
| Credentials | 20+ auth env vars passed by default | Opt-in only (passthroughEnvVars: []) |
| Hook writes | Self-modifies settings.json |
Zero filesystem writes |
| Rust compile | Shell string → injection risk | execFileSync with array args |
| Upgrade | git clone arbitrary code |
Removed entirely |
| FTS5 indexing | Always dual-table (Porter + trigram) | Lazy trigram — 50% fewer writes |
| Runtime detect | Sequential execSync ~250ms |
Parallel Promise.all ~40ms |
| batch_execute | Sequential commands | Promise.allSettled parallel |
| Config | None | ENV + file + defaults |
| Errors | 23 silent catch blocks | CONTEXT_COMPRESS_DEBUG=1 logs all |
| Uninstall | None | context-compress uninstall |
Loaded in order: ENV vars → .context-compress.json → defaults
# Enable debug logging (stderr)
CONTEXT_COMPRESS_DEBUG=1
# Pass specific env vars to subprocesses (default: none)
CONTEXT_COMPRESS_PASSTHROUGH_ENV=GH_TOKEN,AWS_PROFILE
# Disable curl/wget blocking
CONTEXT_COMPRESS_BLOCK_CURL=0
# Disable WebFetch blocking
CONTEXT_COMPRESS_BLOCK_WEBFETCH=0
# Disable Read/Grep nudges
CONTEXT_COMPRESS_NUDGE_READ=0
CONTEXT_COMPRESS_NUDGE_GREP=0Create .context-compress.json in your project root or home directory:
{
"passthroughEnvVars": ["GH_TOKEN", "AWS_PROFILE", "KUBECONFIG"],
"blockCurl": true,
"blockWebFetch": true,
"debug": false
}context-compress # Start MCP server (stdio)
context-compress setup # Detect runtimes, show install instructions
context-compress doctor # Diagnose: runtimes, hooks, FTS5, version
context-compress uninstall # Clean removal: hooks, MCP reg, stale DBs context-compress doctor
[PASS] Performance: FAST — Bun detected
[PASS] Language coverage: 7/11 (64%)
[PASS] Server test: OK
[PASS] PreToolUse hook configured
[PASS] FTS5 / better-sqlite3 works
Version: v1.0.0
All checks passed.
context-compress/
├── src/
│ ├── index.ts # Entry point
│ ├── server.ts # MCP server (7 tools)
│ ├── executor.ts # SubprocessExecutor
│ ├── store.ts # ContentStore (FTS5)
│ ├── config.ts # Config system
│ ├── logger.ts # Debug logger
│ ├── snippet.ts # FTS5 snippet extraction
│ ├── stats.ts # Session tracker
│ ├── types.ts # Shared types
│ ├── runtime/
│ │ ├── plugin.ts # LanguagePlugin interface
│ │ ├── index.ts # Registry + parallel detection
│ │ └── languages/ # 11 language plugins
│ ├── hooks/
│ │ └── pretooluse.ts # PreToolUse hook (no self-mod)
│ └── cli/
│ ├── index.ts # CLI entry
│ ├── setup.ts # Interactive setup
│ ├── doctor.ts # Diagnostics
│ └── uninstall.ts # Clean removal
├── tests/
│ ├── unit/ # 7 unit test files
│ └── integration/ # 3 integration test files
├── hooks/
│ └── hooks.json # Hook matcher config
├── skills/ # Slash command definitions
└── dist/ # Compiled output
| Threat | Mitigation |
|---|---|
| Credential leakage | passthroughEnvVars defaults to [] — zero env vars passed unless opted in |
| Shell injection (Rust) | execFileSync with array arguments — no string interpolation |
| Hook self-modification | No fs.writeFileSync in hooks — zero filesystem side effects |
| Arbitrary code execution | No upgrade command — no git clone or npm install at runtime |
| Silent failures | Debug mode surfaces all catch block errors to stderr |
git clone https://github.com/Open330/context-compress
cd context-compress
npm install
npm run typecheck # Type checking
npm run lint # Biome linting
npm run test:unit # 36 unit tests
npm run test # All tests (unit + integration)
npm run build # Compile + bundleMIT — Based on context-mode by Mert Koseoğlu.