tokensaver-egress
Capture HTTPS traffic from your AI agents (Claude Code, Cursor, n8n, …) and send audits to the TokenSaver control plane.
You run a small proxy on your machine. Your tools talk to the proxy; the proxy talks to Anthropic / OpenAI / … and reports what happened to TokenSaver (Flux IA).
Your agent ──HTTPS──► tokensaver-egress ──► api.anthropic.com / …
│
└── audits ──► api.tokensaver.fr → Flux IA
Install
pip install -U tokensaver-egress
tokensaver-egress setup # interactive wizard (recommended)
Or open the menu with a bare tokensaver-egress in a terminal (TTY).
Requires Python ≥ 3.10 and a TokenSaver API key (ts_…) from platform.tokensaver.fr.
Easiest path: guided setup
tokensaver-egress setup
The wizard walks you through:
- API key (
TOKENSAVER_API_KEY) - Ingest URL (default: production TokenSaver)
- MITM on/off + create the local CA if needed
- Trust instructions (and optional macOS keychain trust)
- Body capture on/off
- Port (default
8888) - Saves
~/.tokensaver-egress/env+client-env.sh, then offers to start the proxy
In another terminal:
source ~/.tokensaver-egress/client-env.sh
claude # or your agent
Next time you can run tokensaver-egress → Start proxy now, or:
source ~/.tokensaver-egress/env
tokensaver-egress serve
5-minute setup (manual MITM)
MITM mode can see model, tokens, and tool names. You must trust a local certificate once.
1. Configure TokenSaver
export TOKENSAVER_API_KEY=ts_your_key_here
export TOKENSAVER_INGEST_URL=https://api.tokensaver.fr/api/v1/egress/ingest
2. Create the local CA (once)
tokensaver-egress init-ca
# Writes: ~/.tokensaver-egress/ca/ca.crt
Trust that CA on this Mac (system keychain), then tell Node (Claude Code) to use it:
# macOS — trust the CA (admin password)
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain \
"$HOME/.tokensaver-egress/ca/ca.crt"
# Every terminal where you run Claude Code / Node agents
export NODE_EXTRA_CA_CERTS="$HOME/.tokensaver-egress/ca/ca.crt"
3. Start the proxy
EGRESS_MITM_ENABLED=true tokensaver-egress serve --port 8888
Leave this terminal open. You should see something like listening on …8888.
4. Point your tools at the proxy
In another terminal:
export HTTPS_PROXY=http://127.0.0.1:8888
export HTTP_PROXY=http://127.0.0.1:8888
export NODE_EXTRA_CA_CERTS="$HOME/.tokensaver-egress/ca/ca.crt"
# Example: Claude Code
claude
5. Check Flux IA
Open platform.tokensaver.fr → Flux IA / egress flows. New calls should appear within seconds.
Everyday commands
| Command | What it does |
|---|---|
tokensaver-egress |
Interactive menu (TTY) or help |
tokensaver-egress setup |
Guided setup (API key, CA, options, start) |
tokensaver-egress serve |
Start proxy on 0.0.0.0:8888 (loads ~/.tokensaver-egress/env) |
tokensaver-egress serve --port 8890 |
Use another port |
tokensaver-egress init-ca |
(Re)generate the MITM CA |
Ctrl+C |
Stop serve |
If the port is busy:
✖ Cannot listen on 0.0.0.0:8888 (Address already in use).
Try: tokensaver-egress serve --port 8889
Stop whatever is on 8888 (often another egress), or pick a free port and update HTTPS_PROXY.
Examples
A. Claude Code (full capture)
# Terminal A — proxy
export TOKENSAVER_API_KEY=ts_…
export TOKENSAVER_INGEST_URL=https://api.tokensaver.fr/api/v1/egress/ingest
EGRESS_MITM_ENABLED=true EGRESS_CAPTURE_BODIES=1 \
tokensaver-egress serve --port 8888
# Terminal B — agent
export HTTPS_PROXY=http://127.0.0.1:8888
export HTTP_PROXY=http://127.0.0.1:8888
export NODE_EXTRA_CA_CERTS="$HOME/.tokensaver-egress/ca/ca.crt"
claude
EGRESS_CAPTURE_BODIES=1 stores request/response bodies in TokenSaver (auth headers are masked). Omit it if you only want metadata (host, latency, tokens).
B. One-shot curl through the proxy
# Proxy already running with MITM + CA trusted
export HTTPS_PROXY=http://127.0.0.1:8888
curl -sS https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-haiku-4-5-20251001","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}'
C. Metadata only (no TLS decrypt)
No CA trust needed. You still see host / bytes / latency, not model tokens.
export TOKENSAVER_API_KEY=ts_…
export TOKENSAVER_INGEST_URL=https://api.tokensaver.fr/api/v1/egress/ingest
tokensaver-egress serve --port 8888
# Client
export HTTPS_PROXY=http://127.0.0.1:8888
export HTTP_PROXY=http://127.0.0.1:8888
D. Local TokenSaver backend (dev)
export TOKENSAVER_API_KEY=ts_…
export TOKENSAVER_INGEST_URL=http://localhost:8000/api/v1/egress/ingest
EGRESS_MITM_ENABLED=true tokensaver-egress serve --port 8888
Modes (simple)
| Mode | How you enable it | What you get |
|---|---|---|
| Explicit | HTTPS_PROXY → proxy |
Host, size, latency |
| MITM | + EGRESS_MITM_ENABLED=true + trusted CA |
Model, tokens, tools, optional bodies |
| Transparent | Linux TPROXY (advanced) | No proxy env on the client; metadata only |
Most people want MITM + explicit proxy (sections above).
Transparent (Linux only):
sudo EGRESS_PORT=8888 ./scripts/tproxy-setup.sh up
tokensaver-egress serve --transparent --port 8888
Useful environment variables
| Variable | Meaning |
|---|---|
TOKENSAVER_API_KEY |
Your ts_… key (required to ship audits) |
TOKENSAVER_INGEST_URL |
SaaS default: https://api.tokensaver.fr/api/v1/egress/ingest |
EGRESS_MITM_ENABLED |
true = decrypt known LLM hosts |
EGRESS_CAPTURE_BODIES |
1 = store bodies in Flux IA |
EGRESS_ENFORCE_ENABLED |
1 = block non-approved catalogue assets |
TOKENSAVER_NO_BANNER |
1 = hide the ASCII logo |
NODE_EXTRA_CA_CERTS |
Path to ca.crt for Node / Claude Code |
Troubleshooting
| Symptom | Fix |
|---|---|
pip install -U stays on an old version |
pip install -U --no-cache-dir tokensaver-egress |
| TLS / certificate errors in Claude Code | Trust ca.crt and set NODE_EXTRA_CA_CERTS |
| Nothing in Flux IA | Check TOKENSAVER_API_KEY + TOKENSAVER_INGEST_URL; watch proxy logs |
| Port already in use | tokensaver-egress serve --port 8889 (update HTTPS_PROXY) |
| Want quieter startup | TOKENSAVER_NO_BANNER=1 tokensaver-egress serve |
Security
- Run MITM only on machines you control. The CA can decrypt traffic you route through the proxy.
HTTPS_PROXYis easy to unset — it is not a hard security boundary. For lock-down, use transparent mode / NetworkPolicy (see runbook).- Bodies are optional; auth headers are masked unless you opt into raw headers.
Related
| Package | Role |
|---|---|
tokensaver-cli |
Route Claude Code / Cursor through TokenSaver APIs |
tokensaver-sdk |
Python SDK |
| Runbook (platform) | Full ops guide |
Monorepo helpers (developers):
./scripts/start-egress.sh --mode mitm --capture-bodies
./scripts/stop-egress.sh
License
MIT © TokenSaver
Release files for tokensaver-egress 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tokensaver_egress-0.1.5.tar.gz | 79.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tokensaver_egress-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 158.6 kB
Release files / tokensaver_egress-0.1.5.tar.gz
| Download URL | tokensaver_egress-0.1.5.tar.gz |
|---|---|
| Size | 79.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62c985a53933ec69f8fb9eba8c1c07fd1af63aefdf89ae369a3c79f7e46f35ae
|
|
BLAKE2b-256 checksum How to use checksums |
d4bcd401d3fcc7f2cea819d2d5caa3d2c24a3e7b99119efb643658cf97665020
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / tokensaver_egress-0.1.5-py3-none-any.whl
| Download URL | tokensaver_egress-0.1.5-py3-none-any.whl |
|---|---|
| Size | 78.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
00fd581785facff757e30905ec44be3bd668b36cb346dc6a674352bfea189e8b
|
|
BLAKE2b-256 checksum How to use checksums |
6aa639b3e649d0c82c1babdcd4b5e81d2865041a0bf6a61e77f2471e053ce44a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|