🐈 ctxcat
cat your repo into LLM context.
Pack any repository into a single, clean, token-aware document — ready to paste into Claude, ChatGPT, Gemini or any LLM.
One file. Zero dependencies. Respects .gitignore. Fits your context window.
Why?
You paste code into an LLM dozens of times a day. And every time it's the same dance:
😩 open file → copy → paste → open next file → copy → paste → "wait, which files did I already paste?" → the model has no idea how your project is structured → you blow past the context window → start over.
ctxcat ends the dance:
ctxcat --copy
That's it. Your entire repo — file tree, every relevant file, properly fenced and labeled — is on your clipboard, trimmed to fit your context window. Paste it. Ask your question. Done.
Install
pip install ctxcat
Or with exact token counting (adds tiktoken):
pip install 'ctxcat[accurate]'
No pip? It's a single file — just grab it:
curl -O https://raw.githubusercontent.com/kamilkubik89/ctxcat/main/ctxcat/cli.py
python3 cli.py --help
Usage
ctxcat # pack current dir → stdout
ctxcat ~/projects/myapp -o ctx.md # pack a repo → file
ctxcat --copy # pack → clipboard, ready to paste
ctxcat --list # what would be packed, with token counts
ctxcat -i 'src/**' -i '*.md' # only source + docs
ctxcat -x 'tests/*' -x '*.sql' # everything except tests and SQL
ctxcat --max-tokens 100000 # guarantee it fits a 100k window
ctxcat -f xml # XML output (great for Claude)
ctxcat -f txt | less # plain text, pipe-friendly
What makes it smart
🧠 Git-aware. Inside a git repo, ctxcat asks git ls-files — so it respects your .gitignore exactly, including nested and global ignores. No half-baked reimplementation.
✂️ Token budget with priorities. --max-tokens 100000 doesn't just truncate. It drops files in reverse order of importance — tests go first, then generic files, while your README, configs and core source survive. You always know what was trimmed.
🧹 Sane defaults. node_modules, lockfiles, binaries, images, .env, build artifacts, ML model weights — automatically skipped. The stuff you'd never paste anyway.
🔢 Token counts, always. Uses tiktoken when available, a proven ~4-chars/token heuristic otherwise. Every run tells you exactly how big your context is before you paste it.
🛡️ Fence-safe Markdown. Files containing ``` won't break your output — ctxcat picks a longer fence automatically. It's the little things.
📋 Clipboard built in. --copy works on macOS, Windows, X11 and Wayland. No plugins.
Example output
# Repository: myapp
## File tree
```
├── src/
│ ├── main.py
│ └── util.py
├── README.md
└── pyproject.toml
```
## Files
### README.md
...
### src/main.py
```python
def main():
...
```
The LLM sees your project the way you see it: structure first, then code, every file labeled.
vs. alternatives
| ctxcat | repomix | gitingest | |
|---|---|---|---|
| Zero dependencies | ✅ | ❌ (Node) | ❌ |
| Single file, curl-able | ✅ | ❌ | ❌ |
True .gitignore support (via git) |
✅ | partial | partial |
| Priority-based token budget | ✅ | ❌ | ❌ |
| Works offline, nothing leaves your machine | ✅ | ✅ | ⚠️ web service |
| Install size | ~15 KB | ~10 MB+ | — |
(All of these are great projects — ctxcat just optimizes hard for simplicity.)
All options
ctxcat [path] [options]
-o, --output FILE write to FILE instead of stdout
-f, --format {md,xml,txt} output format (default: md)
-i, --include GLOB only include matching paths (repeatable)
-x, --exclude GLOB exclude matching paths (repeatable)
--max-tokens N trim lowest-priority files to fit N tokens
--max-file-kb KB skip files larger than KB (default: 256)
-c, --copy copy result to clipboard
-l, --list list files + token counts, don't pack
-q, --quiet no summary on stderr
--version print version
Philosophy
- Do one thing well. Pack repo → LLM-ready text. That's it.
- Zero friction. No config file, no account, no server, no telemetry.
- Your code stays yours. Everything runs locally. Nothing is uploaded, ever.
- Boring technology. Pure Python stdlib. Auditable in one sitting — it's one file.
Contributing
PRs welcome! The whole tool is one file (ctxcat/cli.py) with a test suite. Read it over coffee, break it, fix it.
git clone https://github.com/kamilkubik89/ctxcat
cd ctxcat
python -m pytest # run tests
python -m ctxcat . # run from source
See CONTRIBUTING.md for details.
License
MIT — do whatever you want with it.
If ctxcat saved you a copy-paste marathon, a ⭐ makes the cat purr.
Metadata
Release files for ctxcat 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ctxcat-0.1.0.tar.gz | 63.9 kB | With provenance | Details for ctxcat-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ctxcat-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for ctxcat-0.1.0-py3-none-any.whl |
Total release size: 75.2 kB
Release files / ctxcat-0.1.0.tar.gz
| Download URL | ctxcat-0.1.0.tar.gz |
|---|---|
| Size | 63.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
76d9481510c94b0503ad33fac1b2099871950df84f638ff61bbc1eba1cd57112
|
|
BLAKE2b-256 checksum How to use checksums |
0723aa8cb35eb1f76c65ef011d55e91c6913289cd9b33e175c1dcbb32d88087a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / ctxcat-0.1.0-py3-none-any.whl
| Download URL | ctxcat-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4fa8612471742701bcf8ab2c6c265fabf178099e4a7962c97225830f2b5f0617
|
|
BLAKE2b-256 checksum How to use checksums |
70ddafa59c9bc087703490b4fb328183d2069ba6b3b631ecf12c67771451d472
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logSecurity for ctxcat 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for ctxcat-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.