LLM proxy that analyses token usage in context windows
Project description
Quick start | Motivation | What's new | Install guide | Coding agent setup | FAQ | Supported agents
ContextSpy is a context window profiler for large language models and common agentic AI coding tools. It is used to intercept requests to LLM API, analyze and visualize prompt composition, and track context changes between multiple requests in same session. Modern AI coding agents (GitHub Copilot, Claude Code, opencode, Cursor) pack a lot into each LLM request: system prompts, tool definitions and results, file contents, conversation history. It's often unclear why a session is slow, expensive, or hitting the context limit. ContextSpy makes the invisible visible — you see a live breakdown of every token category for every request, across sessions, over time.
Dashboard view
Think of your favorite CPU or memory profiler, just applied to contents of the context of AI agent. While you can optimize pefromance just by reviewing code, having a profiler to capture and visualise shapshot data helps alot. Same with LLM context optmisation.
Quick start
More details in install guide.
# macOS (Apple Silicon) — see install guide for Linux, Windows, and PyPI options
brew tap RimantasZ/contextspy
brew install contextspy
# Install the CA certificate (cloud mode only, one-time)
sudo contextspy install-cert
# or run contextspy install-cert and then
# printed install cert command with sudo
# Start the proxy
contextspy start
# Start your coding agent from separate terminal
# This will setup all unnecessary environment variables to route llm through the proxy
contextspy run claude <path to your project>
# contextspy run opencode <path to your project>
# contextspy run code <path to your project>
Open http://127.0.0.1:5173 in your browser for ContextSpy dashboard.
Alternatively, refer to configure your agent on how to route LLM traffic through proxy at http://127.0.0.1:8888
Why should I care?
Token costs are rising. With AI agents embracing more and more complex workflows and usecases, token consumption and subsequent cloud API bills are growing larger and larger. This is also applicable for AI coding agents and tools, where providers are gradually switching from subsidized subscription mode and are either reducing token limits or switching to token usage based billing (e.g. GitHub Copilot)
Input tokens are major part. When discussing AI model pricing, most people bring up token generation cost - that's where the numbers look most dramatic ($25 per million tokens for Opus 4.8 output vs $0.40 for gpt-5-nano). But in agentic workloads, input tokens outnumber output by 20-50x, or even more. So the most of your API bill is influenced by input context, not the output the model generates.
AI coding agents = lots of input. The expensive part is quick accumulation of context - with every turn it fills up with additional tokens - system prompt, skills, tool definitions, tool results, file contents, conversation history. You start with 5000 - 10000 tokens in fresh session, but by turn 25 it might be 30 to 50 thousand, spend some more time it might be hitting context window limit and compacting. Every API call to the model sends the full context as part of prompt - and here is where the token consumption and costs skyrocket quickly.
Why large context is bad
We all have been told that the more information we will give to the model, the more capable it will be. And there are models with 1M token (or even bigger) context windows.
There are three ways you pay for extra (and sometimes unnecessary) information in your context:
- API Costs - even with near perfect cache hits, input token costs outweigh output, often by order of magnitude or more.
- Compute and latency - larger contexts take considerably longer to process - especially in local hosted models
- Context rot - with larger contexts, LLMs start to lose precision rapidly, with 100k being the limit where rapid degradation starts. So you are paying for more expensive model, but getting performance of cheaper one - or even worse.
ContextSpy makes these costs visible so you can act on them.
How does it work
ContextSpy starts a HTTPS proxy (or reverse proxy for locally hosted models) which intercepts every request to LLMs, analyzes it and stores to local SQLite db. A webserver is also started on localhost, and serves dashboard to visualise all captured data.
Request view
Context breakdown
Session view
Features
- Two proxy modes — forward proxy for cloud APIs (OpenAI, Anthropic, Copilot), reverse proxy for local LLM servers (Ollama, llama.cpp, vLLM)
- Context breakdown — input tokens split into 8 categories: system prompt, tool definitions, tool results, file contents, conversation history, current user message, assistant prefill, uncategorised
- Live dashboard — real-time charts and per-request detail with a visual block map of the context window
- Session tracking — name and group requests by task to compare usage across runs
- SQLite storage — all data stored locally in
~/.contextspy/; no data leaves your machine - Agent detection — Copilot, Claude Desktop/Code, opencode, Cursor, and generic clients
Documentation links
- Installation — PyPI, Homebrew, .deb, binary, CA certificate setup
- Cloud API mode — intercept OpenAI, Anthropic, Copilot, etc.
- Local LLM mode — intercept Ollama, llama-server, vLLM
- Usage examples — practical recipes and common workflows
- CLI reference — all commands and options
- Development — architecture, data storage, contributing
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file contextspy-0.1.10.tar.gz.
File metadata
- Download URL: contextspy-0.1.10.tar.gz
- Upload date:
- Size: 792.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2670836936c95468c4d6fcf0bda8fe1029b48d6a8ac1d1afcdacbaf63cef2128
|
|
| MD5 |
495b666dfd1ae82604dc85b4741f616f
|
|
| BLAKE2b-256 |
a7e9f548e7c4d878a46ea7a947fcc8644baadb1a7270e1363002821f29fa124b
|
Provenance
The following attestation bundles were made for contextspy-0.1.10.tar.gz:
Publisher:
publish.yml on RimantasZ/contextspy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contextspy-0.1.10.tar.gz -
Subject digest:
2670836936c95468c4d6fcf0bda8fe1029b48d6a8ac1d1afcdacbaf63cef2128 - Sigstore transparency entry: 1777208343
- Sigstore integration time:
-
Permalink:
RimantasZ/contextspy@7dd86acd3f5ed5b2402150a7aee159ba0b7785f7 -
Branch / Tag:
refs/tags/v0.1.10 - Owner: https://github.com/RimantasZ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7dd86acd3f5ed5b2402150a7aee159ba0b7785f7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file contextspy-0.1.10-py3-none-any.whl.
File metadata
- Download URL: contextspy-0.1.10-py3-none-any.whl
- Upload date:
- Size: 798.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e955abe9ef150f2cba992f19fa6b32c44aff52de9121c6a28b8edd7aea3320d5
|
|
| MD5 |
982c224a8c248bf2fc4b963bd3541828
|
|
| BLAKE2b-256 |
a8c12d113dd85adb4bb243e4b76c4740bc1c94d83be59d0439a8ad75cfe1099d
|
Provenance
The following attestation bundles were made for contextspy-0.1.10-py3-none-any.whl:
Publisher:
publish.yml on RimantasZ/contextspy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contextspy-0.1.10-py3-none-any.whl -
Subject digest:
e955abe9ef150f2cba992f19fa6b32c44aff52de9121c6a28b8edd7aea3320d5 - Sigstore transparency entry: 1777208503
- Sigstore integration time:
-
Permalink:
RimantasZ/contextspy@7dd86acd3f5ed5b2402150a7aee159ba0b7785f7 -
Branch / Tag:
refs/tags/v0.1.10 - Owner: https://github.com/RimantasZ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7dd86acd3f5ed5b2402150a7aee159ba0b7785f7 -
Trigger Event:
push
-
Statement type: