Skip to main content

CLI proxy that reduces LLM token consumption by filtering command outputs

Project description

pytk — Python Token Killer

Python 3.11+ MIT License PyPI

CLI proxy that reduces LLM token consumption by 75–92% by filtering and compressing shell command outputs before they reach AI context.

When AI coding agents (Claude Code, Codex, Cursor, Hermes, etc.) run shell commands, the raw verbose output wastes thousands of tokens per session. pytk sits transparently between the agent and the shell — stripping noise, keeping only what matters.


Token Savings (30-min AI Coding Session)

Operation Frequency Without pytk With pytk Savings
ls / find 10× ~8,000 ~2,000 -75%
cat / read 20× ~60,000 ~12,000 -80%
grep / rg ~10,000 ~1,800 -82%
git status 10× ~6,000 ~1,200 -80%
git diff ~6,000 ~600 -90%
git push/commit ~1,600 ~128 -92%
pytest / go test ~10,000 ~750 -92%
Total ~101,600 ~18,478 -82%

Installation

# Recommended — installs as isolated global tool
uv tool install pytk

# Or with pip
pip install pytk

# Verify
pytk --help

Quick Start

pytk is a drop-in prefix — just add pytk before any supported command:

pytk ls -la src/
pytk git status
pytk git diff HEAD~1
pytk pytest tests/ -v
pytk grep "def run" src/ -r
pytk cat README.md

That's it. Same flags, same arguments — just compressed output.


Tutorial

1. See the difference

Let's compare raw vs filtered output side by side.

Raw git status (~800 tokens):

On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update index)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/pytk/cli.py
        modified:   src/pytk/filters/git.py

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        tests/test_new.py

no changes added to commit (use "git add" and/or "git commit -a")

pytk git status (~80 tokens):

modified:   src/pytk/cli.py
modified:   src/pytk/filters/git.py
untracked:  tests/test_new.py

2. Test output compression

Raw pytest (200+ lines, ~4,000 tokens):

collected 49 items

tests/test_cli.py::test_gain_no_stats PASSED                           [  2%]
tests/test_cli.py::test_list_filters PASSED                            [  4%]
tests/test_filters_git.py::test_git_status_strips_hints PASSED         [  6%]
... (46 more passing lines)
tests/test_filters_git.py::test_git_push_compressed FAILED             [ 95%]

FAILURES
=========
...long traceback...

pytk pytest tests/ (~15 lines, ~300 tokens):

FAILED: tests/test_filters_git.py::test_git_push_compressed
AssertionError: expected 'ok main' got 'ok main → origin/main'

1 failed, 48 passed in 0.14s

3. Track your savings

Every filtered command appends stats to ~/.pytk/stats.json. View cumulative savings:

pytk gain

Output:

                   pytk Token Savings
┌──────────┬──────┬─────────────┬─────────────┬───────────┐
│ Command  │ Runs │ Orig tokens │ Filt tokens │ Reduction │
├──────────┼──────┼─────────────┼─────────────┼───────────┤
│ git      │   12 │      14,400 │       1,440 │       90% │
│ pytest   │    5 │      40,000 │       3,000 │       92% │
│ ls       │    8 │       6,400 │       1,600 │       75% │
│ grep     │    6 │       7,500 │       1,350 │       82% │
│ cat      │    4 │      12,000 │       2,400 │       80% │
│ TOTAL    │   35 │      80,300 │       9,790 │       88% │
└──────────┴──────┴─────────────┴─────────────┴───────────┘

4. Escape hatch

Output looks wrong? Use passthrough to get raw unfiltered output:

pytk passthrough git log --oneline --graph

5. See all filters

pytk list-filters

AI Agent Integration

Claude Code

Run this in your project root:

pytk init --agent claude

Then paste the output into your CLAUDE.md. Claude will automatically prefix commands with pytk.

Or add manually to CLAUDE.md:

## Shell Commands
Always use `pytk <cmd>` instead of running shell commands directly.
This reduces token usage by filtering verbose output.

Examples:
  pytk ls -la src/
  pytk git status
  pytk git diff HEAD~1
  pytk pytest tests/
  pytk grep 'pattern' src/ -r
  pytk cat file.py

Hermes Agent

pytk init --agent hermes

Or add to your Hermes system prompt / skill:

# Use pytk for all shell commands to reduce token usage
# pytk ls, pytk git, pytk pytest, pytk grep, pytk cat

Codex / OpenAI Agents

pytk init --agent codex

Adds a section to AGENTS.md instructing Codex to use pytk for shell commands.

Any agent (generic)

The key principle: instruct your agent to prefix shell commands with pytk. The agent doesn't need to know anything about pytk internals — it just uses it like a regular command.

## Token Efficiency
Prefix all shell commands with `pytk` to reduce output verbosity:
pytk ls, pytk git status, pytk pytest, pytk grep, pytk cat

Supported Commands

Command Filter What's removed Savings
ls, find, tree LsFilter permissions, uid, gid, size, timestamps ~75%
git status GitFilter hints, tracking info, usage instructions ~80%
git diff GitFilter index xxxx..yyyy lines, keeps hunks ~90%
git log GitFilter author, date — keeps hash + message only ~80%
git push/commit/merge GitFilter progress lines, compressed to 1 line ~92%
pytest, python -m pytest TestFilter passing test lines, progress bars ~92%
go test, cargo test, npm test TestFilter passing test lines, progress bars ~92%
grep, rg, ag GrepFilter binary matches, excess per-file results ~82%
cat, head, tail CatFilter middle of long files, excess blank lines ~80%

Commands not in the list pass through unmodified — always safe to prefix with pytk.


CLI Reference

pytk <command> [args...]        # Run command with filter applied
pytk gain                       # Show cumulative token savings
pytk init [--agent NAME]        # Print agent integration snippet
pytk passthrough <cmd> [args]   # Run without filtering
pytk list-filters               # Show all filters + example savings

--agent options: claude, hermes, codex (default: prints all)


Contributing

git clone https://github.com/unrealandychan/pytk
cd pytk
uv sync --extra dev
pytest tests/ -v

Adding a new filter

  1. Create src/pytk/filters/myfilter.py extending BaseFilter:
from pytk.filters.base import BaseFilter

class DockerFilter(BaseFilter):
    def matches(self, cmd: list[str]) -> bool:
        return bool(cmd) and cmd[0] == "docker"

    def filter(self, output: str, cmd: list[str]) -> str:
        # your compression logic
        return output

    def savings_example(self) -> dict:
        return {"before": 500, "after": 100, "description": "docker ps with 10 containers"}
  1. Register in src/pytk/filters/registry.py:
from pytk.filters.myfilter import DockerFilter
FILTERS = [..., DockerFilter()]
  1. Add tests in tests/test_filters_myfilter.py
  2. Open a PR 🎉

Roadmap

  • docker ps / logs / build filter
  • kubectl get / describe / logs filter
  • npm install / yarn filter
  • curl / http response filter
  • Shell hook mode (auto-intercept without explicit pytk prefix)
  • VS Code extension

License

MIT — © 2026 unrealandychan

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytk_cli-0.2.0.tar.gz (47.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytk_cli-0.2.0-py3-none-any.whl (35.3 kB view details)

Uploaded Python 3

File details

Details for the file pytk_cli-0.2.0.tar.gz.

File metadata

  • Download URL: pytk_cli-0.2.0.tar.gz
  • Upload date:
  • Size: 47.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for pytk_cli-0.2.0.tar.gz
Algorithm Hash digest
SHA256 250721d8304424d19e7e9e9b8240837e7f8014eee54794ca759a3d4d7284838c
MD5 69c13a060a68df19cb5c7047e81abf82
BLAKE2b-256 3f2e9924c82a88cd9755f401b07204083f9f992883cd12f3f2cdfa495bd83790

See more details on using hashes here.

File details

Details for the file pytk_cli-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pytk_cli-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 35.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for pytk_cli-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a1097d6977f94342beb40bed3a6a277c94fc3d887848a33e948c0e2436b66ead
MD5 3efa1face896524805b8a19ca51512cd
BLAKE2b-256 457df8f849f2c6948ab0cc14d04d3ed6b32185a8ba8e02f8897754e09c0b669a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page