Why
On hosted, your provider key is saved encrypted and opened with your unlock for each call. On self-hosted there is nothing to save: the key is only ever on your machine, and the call goes from your machine straight to the provider. FlockTab sees the model and the token counts, which is what it needs to hold, settle and refuse.
Set it up
npm i -g @hanamorilabs/tab
tab up # first run asks for provider keys (typed without echo), then starts the proxy
tab login # choose 2 Self-hosted; approve this machine in the console
cd my-project
tab claude # or tab codex, ...The proxy is one small binary, flocktab-proxy. It comes with tab from npm for your platform; no Docker, no runtime. It listens on 127.0.0.1:8787 only. tab claude starts it by itself when it is down; tab down stops it.
What talks to what
| From | To | Carries |
|---|---|---|
| Your agent | 127.0.0.1:8787 | Its normal request, with the Agent's virtual key |
| Your proxy | proxy.flocktab.com | identity, reserve, commit, refund: the Agent's key, the model, token counts. No prompt, no reply, no provider key |
| Your proxy | The provider | The request, with your provider key from the local file |
A key can only reserve for its own Agent and settle its own holds. If flocktab.com cannot be reached, the call is refused: the local proxy fails closed like the hosted one.
Files on your machine
| File | What |
|---|---|
| ~/.flocktab/proxy.env | Provider keys, one per provider, owner-only. OPENAI_API_KEY and ANTHROPIC_API_KEY are accepted as they are. |
| ~/.flocktab/proxy.log | One line per call. See below. |
| ~/.flocktab/bin/flocktab-proxy | The binary, when it was fetched rather than installed with tab. |
| ~/.flocktab/config.json | This machine's session and Agent keys. |
Without tab: run the binary with those variables in its environment (HOST defaults to 127.0.0.1, PORT to 8787) and point the agent at http://127.0.0.1:8787/v1 with the Agent's key.
Its log
tab log --proxy -f # this machine's proxy, as calls happen
tab log -f # the ledger's view, hosted or self-hostedEach line: metered or subscription, vendor, Agent id, model, the outcome (settled, recorded, provider_error_refunded, or the refusal code), HTTP status, tokens in and out with cached input apart, and milliseconds. It never contains a virtual key, a provider key, a login, a prompt or any body, an email or an address. RUST_LOG=debug in proxy.env says more; FLOCKTAB_CALL_LOG=0 turns the call line off.
Updating
tab update installs the newest tab and with it the newest proxy, and restarts a proxy that was running. Stop your agents first: a restart cuts whatever is streaming through it. A proxy older than tab can miss features, and tab says so when it notices; tab down && tab up when nothing is running fixes it.
Subscriptions through it
A Subscription Agent works the same: the agent's own login goes to http://127.0.0.1:8787/t/<key>/<vendor>/..., the proxy asks flocktab.com whether the tab is open and the policies pass, forwards the call untouched, and reports the vendor's token counts, account and usage windows. No provider key is used for these calls, though the proxy still needs one key in proxy.env to start.
Slow models
FLOCKTAB_UPSTREAM_IDLE_MS: how long to wait for headers or the next bytes. Two minutes unless set.FLOCKTAB_UPSTREAM_TIMEOUT_MS: the longest one call may take. Ten minutes unless set.
Raise them in proxy.env for models that reason for a long time without sending anything.