
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@sliday/tamp
Advanced tools
Token compression proxy for coding agents. Works with Claude Code, Aider, Cursor, Cline, Windsurf. 60-70% combined input+output savings with Caveman-integrated presets and per-command rewriters.
Token compression proxy for coding agents. 52.6% fewer input tokens, 60-70% combined with output compression. Zero code changes. Works with Claude Code, Codex CLI, opencode, Aider, Cursor, Cline, Windsurf, π¦ OpenClaw, and any OpenAI-compatible agent.
npx @sliday/tamp
# Install the plugin (auto-starts Tamp each session)
claude plugin marketplace add sliday/claude-plugins
claude plugin install tamp@sliday
The plugin adds /tamp:status and /tamp:config commands. It auto-starts Tamp but does not route traffic. Point Claude Code at Tamp once by adding to ~/.claude/settings.json:
{ "env": { "ANTHROPIC_BASE_URL": "http://localhost:7778" } }
That line makes Claude Code depend on Tamp. Run tamp install-service in the same sitting so the proxy is up at every login, and keep ~/.claude/settings.json.backup until you trust the setup. To undo, delete the ANTHROPIC_BASE_URL key.
TAMP_STAGES=minify,toon,strip-lines,whitespace,dedup,diff,prune tamp -y
Set provider to http://localhost:7778 β done. Full guide: docs/openclaw-setup.md
Claude Code βββΊ Tamp (localhost:7778) βββΊ Anthropic API
Aider/Cursor βββΊ β βββΊ OpenAI API
Gemini CLI βββββΊ β βββΊ Google AI API
Auto-detects API format, compresses tool output, forwards upstream. Error results skipped. JSON minified, arrays encoded columnarly, text/code normalized or semantically compressed.
Compression Stages (all enabled by default):
| Stage | What |
|---|---|
cmd-strip | Strip progress bars and spinners from command output (lossless) |
minify | Strip JSON whitespace |
toon | Columnar array encoding |
strip-lines | Remove line-number prefixes |
whitespace | Collapse blank lines |
llmlingua | Neural text compression |
dedup | Replace duplicates with refs |
diff | Replace similar re-reads with diffs |
prune | Remove low-value metadata |
Opt-in stages: strip-comments, textpress (LLM semantic compression), graph (session-scoped dedup β works on any coding agent: Codex, Claude Code, Aider β anywhere the same file is read twice, up to -99% per repeat block), px-render (renders dense tool_results as PNG image blocks via pxpipe β image tokens are priced by pixel area, so 4-64KB grep/code blocks drop ~80% on vision-legible models like Fable 5; see docs/notes-px-render.md), stale-inputs (prunes payloads from tool_use.input in older turns, keeping the call header β measured 18% on realistic requests), stale-images (evicts base64 images from older turns, keeping the newest 2 β ~4%)
stale-inputs and stale-images rewrite older turns, which invalidates the prompt cache. Both stay opt-in for that reason; weigh the token saving against cache-read pricing. See reports/magic-compact-review.md.
The llmlingua stage is enabled by default but requires a Python sidecar running on port 8788.
Tamp auto-starts the sidecar when uv is installed. Manual starts for all other cases:
uv run --with fastapi --with uvicorn --with llmlingua \
uvicorn server:app --host 127.0.0.1 --port 8788 \
--app-dir "$(npm root -g)/@sliday/tamp/sidecar"
curl -s http://localhost:8788/health # Verify: {"status":"ok","model_loaded":true}
tamp stop && tamp -y # restart Tamp, health endpoint will show `sidecar: ok`
What it will not touch. LLMLingua-2 paraphrases, and a paraphrased file path is a broken file path. At the default rate of 0.7 it turned real command output into this:
| Before | After |
|---|---|
/Users/x/.config/tamp/tamp.err.log | /Users/x./tamp.. |
"version":"0.8.17" | "version""0.. 17" |
launchctl bootout gui/501/dev.tamp.proxy | launchctl bootout gui/501/dev.. |
So Tamp skips the sidecar for any block carrying paths, URLs, JSON separators, hex ids, or semver, and sends only prose. Across Tamp's own benchmark fixtures that guard fires on 92% of text blocks, which is the honest measure of how much llmlingua contributes to a coding agent: very little. Keep it for doc-heavy and web-fetch traffic, drop it if you want a fully lossless pipeline:
TAMP_STAGES=cmd-strip,minify,toon,strip-lines,whitespace,dedup,diff,read-diff,prune tamp -y
# Option A: One-line installer
curl -fsSL https://tamp.dev/setup.sh | bash
# Option B: Manual
npx @sliday/tamp
export ANTHROPIC_BASE_URL=http://localhost:7778 # Claude Code
export OPENAI_API_BASE=http://localhost:7778/v1 # Aider, Cline
Use your agent as normal β Tamp compresses silently.
Codex CLI reads its upstream from ~/.codex/config.toml, not an env var. Add a custom provider:
model_provider = "tamp"
[model_providers.tamp]
name = "Tamp Proxy"
base_url = "http://localhost:7778/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"
Then export OPENAI_API_KEY=sk-... and run codex or codex exec "..." as usual. Tamp routes /v1/responses through the openai-responses adapter and compresses every function_call_output and custom_tool_call_output block, including outputs carried as input_text content arrays.
ChatGPT Plus / Pro subscription. If you sign in with codex login instead of using an API key, add this line to ~/.codex/config.toml:
openai_base_url = "http://localhost:7778/v1"
Tamp detects OAuth bearer tokens and routes them to chatgpt.com/backend-api/codex automatically, so your ChatGPT Plus/Pro subscription keeps paying for inference while Tamp compresses every tool result in flight. Verified against codex-cli 0.146.0.
One transport caveat: Codex 0.146 opens a WebSocket to <base>/responses first. Tamp proxies HTTP only, so it answers that upgrade with 501 and Codex falls back to its HTTPS transport. Expect a handful of failed to connect to websocket lines in the log; the session then runs normally.
npx @sliday/tamp -yβ,) β Modelssk-... keyhttp://localhost:7778/v1gpt-4o, gpt-5-codex, etc.)Cursor Pro subscription caveat. Cursor's bundled
cursor-*,composer-*,claude-*, andgpt-*models are routed through Cursor's own servers (api2.cursor.sh) regardless of the "Override OpenAI Base URL" setting β Tamp cannot intercept them. Compression only applies when you (a) bring your own OpenAI key and (b) select a model Cursor treats as external (e.g. an unbundledgpt-4owith BYOK, or a custom model name via a public tunnel).
opencode silently ignores OPENAI_API_BASE / OPENAI_BASE_URL. Configure base URLs per provider in ~/.config/opencode/opencode.json:
{
"provider": {
"anthropic": { "options": { "baseURL": "http://localhost:7778" } },
"openai": { "options": { "baseURL": "http://localhost:7778/v1" } },
"openrouter": { "options": { "baseURL": "http://localhost:7778/v1/openrouter" } },
"opencode": { "options": { "baseURL": "http://localhost:7778/v1/zen" } }
}
}
Restart opencode. Tamp's adapter table routes each provider to the correct upstream.
Config lives at ~/.kimi-code/config.toml (not ~/.kimi/), and the provider table is named after the managed provider:
[providers."managed:kimi-code"]
base_url = "http://localhost:7778/kimi/coding/v1"
# Moonshot API key instead of a subscription:
[providers.moonshot]
base_url = "http://localhost:7778/moonshot/v1"
Read this before you edit that file. Kimi Code stores its OAuth token under a key derived from the provider environment, and
base_urlis part of that key. Change the URL and the CLI loses the token it already has:No token for "kimi-code-env-92f579c50dab5f50". Run /login to authenticate.Every running agent fails at once, including background ones. Run
/loginin Kimi after the edit to re-authenticate under the new key, or leavebase_urlalone and accept no compression on Kimi. Restoring the original URL restores the original token.
An API-key Moonshot setup has no such problem; only the OAuth subscription path is affected.
npx @sliday/tamp -yOpenAI Compatiblehttp://localhost:7778/v1sk-...gpt-4o, claude-sonnet-4-5, or any model your key supportsCline talks directly to the configured base URL for every request β works seamlessly through Tamp.
npx @sliday/tamp -y~/.continue/config.json and add:{
"models": [
{
"title": "GPT-4o (via Tamp)",
"provider": "openai",
"model": "gpt-4o",
"apiKey": "sk-...",
"apiBase": "http://localhost:7778/v1"
}
]
}
Copilot does not expose a base URL setting and routes everything through GitHub's servers. Tamp cannot intercept Copilot traffic. Use Cline or Continue instead if you want compression in VS Code.
Run tamp init to create ~/.config/tamp/config. All variables work via env or config file.
One knob, nine stops. The 1β9 ladder is prefix-preserving (each level adds stages on top of the previous), so you can dial compression up or down without reasoning about individual stages.
| Level | Stages (cumulative) | Lossy | Expected savings | Preset alias |
|---|---|---|---|---|
| 1 | minify | β | ~15% | β |
| 2 | + whitespace, strip-lines | β | ~25% | β |
| 3 | + cmd-strip | β | ~35% | β |
| 4 | + toon, dedup, diff | β | ~45% | conservative |
| 5 | + llmlingua, read-diff, prune | yes | ~53% | balanced (default) |
| 6 | + strip-comments | yes | ~58% | β |
| 7 | + textpress, br-cache | yes | ~62% | β |
| 8 | + disclosure, bm25-trim | yes | ~67% | aggressive |
| 9 | + graph, foundation-models | yes | ~72% | max |
Three interchangeable ways to pick a level:
tamp --level 7 # CLI flag
TAMP_LEVEL=7 tamp # Environment variable
tamp settings # Interactive slider (+ advanced stage picker)
Precedence: --level > TAMP_LEVEL > config file > preset alias > default (balanced / L5). Setting TAMP_STAGES explicitly still wins over any level β the banner will show the full stage list instead of the Level line.
The named presets are aliases of levels and still work unchanged:
| Preset | Level | Savings | Description |
|---|---|---|---|
conservative | L4 | 45-50% | Lossless only (no neural) |
balanced (default) | L5 | 52-58% | Recommended, includes LLMLingua |
aggressive | L8 | 60-68% | Maximum, lossy stages enabled |
# Use a preset
export TAMP_COMPRESSION_PRESET=balanced
# Or override specific stages
TAMP_COMPRESSION_PRESET=balanced
TAMP_STAGES=minify,toon # Override preset
Task-type-aware output compression. Tamp classifies each request as safe (typo fixes, env var changes, doc updates) or dangerous (security, debug, refactor) and injects matching rules into the last user message before forwarding. Cache-safe β the prefix stays untouched so prompt caching keeps working.
Opt in (default is off β zero behavior change unless you flip the switch):
export TAMP_OUTPUT_MODE=balanced # off | conservative | balanced | aggressive
export TAMP_AUTO_DETECT_TASK_TYPE=true # default; set to false to force 'complex'
Mode behavior:
Supported on all providers: Anthropic, OpenAI Chat, OpenAI Responses (Codex), Gemini.
| Variable | Default | Description |
|---|---|---|
TAMP_PORT | 7778 | Listen port |
TAMP_HOST | 127.0.0.1 | Bind address. Loopback by default; set 0.0.0.0 to expose beyond the local machine (e.g. in a container) |
TAMP_UPSTREAM | https://api.anthropic.com | Anthropic (default) upstream |
TAMP_UPSTREAM_OPENAI | https://api.openai.com | Upstream for OpenAI-compatible routes (/v1/chat/completions, /v1/responses) |
TAMP_UPSTREAM_GEMINI | https://generativelanguage.googleapis.com | Upstream for Gemini (generateContent) routes |
TAMP_UPSTREAM_KIMI | https://api.kimi.com | Upstream for Kimi Code routes |
TAMP_UPSTREAM_MOONSHOT | https://api.moonshot.cn | Upstream for Moonshot OpenAI-compatible routes |
TAMP_MIN_SIZE | 200 | Min content size (chars) |
TAMP_MAX_BODY | 10485760 | Max request body (bytes, 10 MB). Larger bodies pass through uncompressed |
TAMP_LOG | true | Enable logging |
TAMP_LOG_FILE | (none) | Append logs to this file path, in addition to stderr |
TAMP_CACHE_SAFE | true | Compress newest only (prompt-cache safe) |
TAMP_REDACT | true | Mask secrets in tool output before anything leaves the machine |
TAMP_REDACT_MODE | mask | mask (replace with marker) or remove (delete value) |
TAMP_LLMLINGUA_URL | (none) | LLMLingua sidecar URL. Set to http://localhost:8788 to skip the auto-probe (avoids startup race if sidecar is still loading the model) |
Recommended setups:
# Default (balanced preset = L5)
npx @sliday/tamp
# Conservative (no Python, lossless only)
TAMP_LEVEL=4 npx @sliday/tamp -y
# Aggressive (maximum compression)
TAMP_LEVEL=8 npx @sliday/tamp -y
Compress CLAUDE.md and config files by 40-45%:
# Dry run (preview savings)
tamp compress-config --dry-run ~/.claude/CLAUDE.md
# Compress with backup
tamp compress-config ~/.claude/CLAUDE.md
# Compress multiple files
tamp compress-config ~/.config/tamp/config ~/.claude/CLAUDE.md
Inspired by JuliusBrussee/caveman-compress.
Tamp writes a PID file at ~/.config/tamp/tamp-${port}.pid on start and cleans it up on graceful shutdown (SIGINT, SIGTERM, SIGHUP). If a terminal dies and leaves the port bound, tamp -y will now detect it and print a friendly error instead of a cryptic EADDRINUSE:
[tamp] Tamp v0.5.4 already running on :7778 (pid 12345, started 3m ago).
Run 'tamp stop' to replace it, or set TAMP_PORT=7779 to run alongside it.
tamp stop β graceful SIGTERM to the running proxy, falls back to SIGKILL after 2stamp -y --force β replace any existing Tamp on the same port in one step (for scripts)# npx (no install)
npx @sliday/tamp
# npm global
npm install -g @sliday/tamp
tamp
Read this before you point an agent at Tamp permanently. Once ANTHROPIC_BASE_URL (or a config.toml base_url) names localhost:7778, that agent talks to nothing when Tamp is down. Every session fails until you start it again.
tamp install-service # launchd on macOS, systemd user unit on Linux
tamp status # confirm it came up
tamp uninstall-service # remove it
macOS installs ~/Library/LaunchAgents/dev.tamp.proxy.plist with RunAtLoad and KeepAlive, so Tamp starts at login and restarts if it dies. Logs land in ~/.config/tamp/tamp.err.log.
If you would rather not add a background service, keep the agent on its normal endpoint and start Tamp by hand when you want the savings.
npm install -g writes to npm config get prefix, which is not always the directory your shell resolves from. Check the copy you actually run:
grep '"version"' "$(dirname "$(readlink -f "$(command -v tamp)")")/../package.json"
If that disagrees with npm view @sliday/tamp version, install into the prefix your PATH uses:
npm install -g --prefix "$(dirname "$(dirname "$(readlink -f "$(command -v tamp)")")")" @sliday/tamp
Check session stats any time via the health endpoint via browser or terminal:
curl -s 'http://localhost:7778/health?text' # Human-readable
# Tamp v0.5.9 | 7 stages active | sidecar: n/a
# Requests: 63 | Blocks: 2
# Tokens saved: 1136 | Chars: 3482/61528 (5.7%)
# Est. savings: $0.0034 (Sonnet $3/Mtok) | $0.0170 (Opus $15/Mtok)
curl -s http://localhost:7778/health # JSON (for scripts/dashboards)
Inside Claude Code, run /tamp:status.
Claude Code sends full conversation history on every API call. Tool results accumulate β files, listings, outputs β all re-sent as input tokens.
With 52.6% average input compression: Save $0.19β$0.32 per 200-request session (Sonnet/Opus 4.6). Max subscribers get 47% more requests from fixed budgets. See whitepaper PDF for full benchmarks.
Output compression (new): Task-type-aware rules reduce output tokens by 65-75% on safe tasks (env vars, typos, docs) while preserving full output for dangerous tasks (security, debugging). Inspired by JuliusBrussee/caveman.
Combined impact: With new Caveman-integrated features, Tamp achieves 60-70% total token savings (input + output) in balanced mode.
Short answer: not much on the micro-benchmark, a lot on real sessions.
On the short single-request fixtures in bench/, the headline percentage barely moves β v0.5 baseline lands at 45.1%, L5 (balanced) at 45.3%, L9 (max) at 45.4%. The fixtures are too small to exercise the new stages: they don't contain re-reads, don't cross the disclosure threshold (>32 KB tool_result bodies), don't include the noisy CLI streams cmd-strip targets, and fit entirely inside a single request so cross-request session dedup (graph) is a no-op.
Where v0.8 actually pays off is session-scoped work, which is what coding agents do all day:
read-diff (L5) and graph (L9) eliminate the cost of re-reading the same file β a dominant pattern in multi-turn debugging sessions.disclosure (L8) keeps tool_result payloads over 32 KB from burning input tokens a second time when the agent references them later.cmd-strip (L3) removes per-command stdout noise (spinners, progress bars from npm, pip, cargo, docker) that the synthetic fixtures don't contain.br-cache (L7) and bm25-trim (L8) shave long-tail content the fixtures don't exercise.The real win in v0.8 is the level knob itself β a zip-like 1β9 dial that lets you trade compression aggressiveness for risk without memorizing stage names. To reproduce the numbers above, run node bench/runner.js --sweep (set OPENROUTER_API_KEY for the live A/B pass).
Tamp runs on localhost and forwards to the upstream you configure. Most stages are local-only: llmlingua talks to a sidecar on 127.0.0.1, foundation-models stays on-device. The one stage that sends content off-box is textpress (opt-in, level 7+), which posts to OpenRouter when OPENROUTER_API_KEY is set β leave it off if your tool output is sensitive.
Secret redaction is on by default (#6). Before any stage runs β including ones that ship text off-box β Tamp masks high-confidence secrets in tool output: provider-shaped keys (AWS, GitHub, Anthropic/OpenAI, Google, Slack, Stripe), JWTs, PEM private-key blocks, and UPPER_SNAKE secret assignments from .env/shell (API_TOKEN=β¦, DATABASE_PASSWORD=β¦). Masking keeps structure (API_TOKEN=βΉredacted:secretβΊ) so the model still reasons about it. Set TAMP_REDACT=false to disable, or TAMP_REDACT_MODE=remove to delete rather than mask. Detection favors precision over recall: it won't catch every secret, so treat your upstream's data policy as the final boundary.
This repo ships an agent harness (built with harn.app): AGENTS.md plus PreToolUse / Stop hooks under scripts/harness/ that block dangerous shell commands and gate completion on npm test. See .claude/settings.json.
npm test
node smoke.js
MIT Β© Stas Kulesh
FAQs
Token compression proxy for coding agents. Works with Claude Code, Aider, Cursor, Cline, Windsurf. 60-70% combined input+output savings with Caveman-integrated presets and per-command rewriters.
The npm package @sliday/tamp receives a total of 30 weekly downloads. As such, @sliday/tamp popularity was classified as not popular.
We found that @sliday/tamp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards usersβ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.