RTK
CLI proxy reduces LLM token consumption 60-90% on dev commands. Intercepts command output (git, test runners, linters, build tools), returns only essential info to agent context window.
- Single Rust binary, zero runtime deps
- <10ms overhead per command
- Fail-safe: falls back to raw output if filter breaks
- Preserves exit codes for CI/CD compatibility
Installation
brew install rtk # macOS (Homebrew)
cargo install rtk-ai # From crates.io
Verify correct binary (name collision with another rtk package):
rtk --version # Should show "rtk 0.31.0" or newer
rtk gain # Should show token savings (NOT "command not found")
Global Setup
Use rtk init -g for hook-based integration. Recommended approach -- transparently rewrites commands with zero manual effort:
rtk init -g
Installs:
~/.claude/hooks/rtk-rewrite.sh— PreToolUse hook rewrites Bash commands throughrtk hook~/.claude/RTK.md— slim reference (10 lines, minimal token cost)- Hook entry in
~/.claude/settings.json
After setup, all agent Bash commands auto-rewritten. Example: git status becomes rtk git status transparently.
Other Agents
rtk init --agent cursor # Cursor
rtk init --codex # Codex CLI (base + variants)
Windsurf and Cline use rules files (.windsurfrules, .clinerules) generated by rtk init.
Uninstall
rtk init -g --uninstall
How It Works
Hook intercepts PreToolUse Bash events, rewrites commands via rtk rewrite, returns compressed output. Strategies: filtering (ANSI, boilerplate), grouping (errors by rule), truncation, deduplication.
Supported Commands
- Git: status ~80%, log ~75-92%, diff ~70%, commit ~90%
- Tests: pytest/cargo test ~90%, vitest ~99%
- Linters: ruff/eslint ~80-84%, tsc/mypy ~80-83%
- Builds: cargo build ~80%, next build ~87%
- File ops: ls/tree ~80%, grep/rg ~75%, find/fd ~70%
Meta Commands
Run directly -- never through proxy:
rtk gain # Token savings dashboard
rtk gain --history # Per-command history with savings %
rtk gain --graph # Visual savings graph
rtk gain --project # Scoped to current project
rtk discover # Scan agent history for missed optimizations
rtk learn # Detect project patterns, suggest optimizations
rtk session # Adoption overview
rtk proxy <cmd> # Run raw command (no filtering), still tracked
rtk rewrite "<cmd>" # Preview what a command would be rewritten to
rtk config # Show current configuration
rtk verify # Integrity check
rtk hook-audit # Audit hook installations
Configuration
User Config
~/.config/rtk/config.toml:
[tracking]
history_days = 90
[display]
colors = true
max_width = 120
[filters]
ignore_dirs = [".git", "node_modules", "target", "__pycache__", ".venv"]
[hooks]
exclude = [] # commands to skip rewriting
Use [hooks] exclude to bypass rewriting where raw output needed.
Custom Filters (TOML)
Declarative filter pipelines for commands RTK doesn't cover natively.
Project-local: .rtk/filters.toml (requires rtk trust for security)
User-global: ~/.config/rtk/filters.toml
Example -- compress Terraform plan output:
[filters.terraform-plan]
command = "terraform"
subcommand = "plan"
strip_ansi = true
strip_lines_matching = ["Refreshing state...", "Reading...", "data\\."]
truncate_lines_at = 200
max_lines = 100 changes detected"
[[filters.terraform-plan.replace]]
pattern = "Plan: (\\d+) to add"
replacement = "+$1"
[[tests.terraform-plan]]
input = "Refreshing state...\nPlan: 3 to add"
expected = "+3"
Pipeline stages (applied sequentially):
strip_ansi— remove escape codesreplace— regex substitutions (chainable)match_output— short-circuit if pattern matches (withunless)strip_lines_matching/keep_lines_matching— filter lines by regextruncate_lines_at— limit line lengthhead_lines/tail_lines— retain first/last N linesmax_lines— absolute line capon_empty— fallback message if result empty
Trust Gating
Project-local .rtk/filters.toml requires explicit trust:
rtk trust # Trust current project's filters
rtk untrust # Revoke trust
Debugging
RTK_TOML_DEBUG=1 rtk <cmd> # Log matched filters to stderr
RTK_DISABLED=1 <cmd> # Bypass RTK entirely
RTK_NO_TOML=1 rtk <cmd> # Bypass TOML filters only
rtk proxy <cmd> # Run raw, still track usage
File Reading Modes
rtk read filter levels: NoFilter (unchanged), MinimalFilter (strips comments/blanks), AggressiveFilter (imports + signatures only). Data formats (JSON, YAML, TOML) bypass aggressive filtering.
Best Practices
- Use
rtk init -gfor global hook -- most transparent - Let hook rewrite automatically, don't manually prefix
- Run
rtk gainregularly,rtk discoverfor missed opportunities - Use
rtk proxy <cmd>for full unfiltered output - Start with defaults; add TOML filters only for project-specific tools
- Include
[[tests]]in custom filters - Tee saves raw output on failures to
~/.local/share/rtk/tee/