The usual way puts the key in the agent’s context
To give an agent a tool you put an API key in an MCP config file. That file is plaintext, any process can read it, and the agent reads it to start the server — so the credential lands in the agent’s own context, and from there in the transcript and wherever transcripts are kept.
supertoolkit holds the credential in a process the agent cannot read, and puts it
on the wire on the way out. Clients need no modification: they are started with
HTTPS_PROXY pointing at the broker and a placeholder where their
token would be.
Five operations, and three never send a lasting secret
What a service needs decides what the broker does. The catalogue declares it, so a new scheme is an entry rather than a branch in the request path.
- substitute long-lived on the wire
A stored token replaces the placeholder on the wire.
github · slack · notion · openai · cloudflare · resend
- substitute, scheme-aware long-lived on the wire
Decode the Basic header, replace the value, re-encode. A plain string swap matches nothing here.
stripe
- sign no long-lived secret on the wire
The request is signed inside the broker. The credential is an HMAC over the method, path and body — not a value anything can carry.
aws-sts
- mint no long-lived secret on the wire
A JWT is minted from a stored private key and exchanged for an installation token that expires in an hour.
github-app
- acquire no long-lived secret on the wire
A stored refresh token is exchanged for a short-lived access token. The refresh token only ever reaches the provider’s token endpoint.
x · google
A read is the agent’s. A write is yours.
Policy is one file you commit, holding no secrets. Defaults come from the catalogue and fail safe: a read is agent-callable, a write needs approval, and anything unclassified is treated as a write.
services:
github:
capabilities:
create_issue: approval
profiles:
reader:
github: [get_user, list_repos] waiting on you
github / create_issue
title=“Flaky test in the broker”
The agent is told pending and nothing happens. Approving performs
it and records what came back; refusing performs nothing. Expiry is never
approval.
Afterwards, a record that answers the question
What was done, under which policy, and what the provider said. What is recorded about the credential is a fingerprint, or the name of the operation that replaced it — never the value, and there is a test for every scheme.
$ stk audit
Oct 15 02:20:28 github create_issue approval 201 Created
POST /repos/you/your-repo/issues · credential: sha256:40a7a1d2319d
Oct 15 02:20:15 github get_user agent 200 OK
GET /user · credential: sha256:40a7a1d2319d What it does not do
Read this before trusting it with something that matters. Each of these is a decision or a measurement, not an oversight.
- A client that ignores proxy configuration goes around the broker
- It fails silently, sending the placeholder to the provider and getting a plausible 401. Nothing inside a proxy can detect a client that never speaks to it — so
stk doctor --probedetects it from outside, using a hostname that can never resolve. - Brokered mTLS does not work
- 502, loud, nothing sent. The broker holds no client certificate. Tunnel that host instead.
- WebSocket and other upgrades are refused
- A credential is substituted on an HTTP request, and an upgraded connection carries no further requests to substitute into. 501, with the way out.
- On Linux the store key is a file beside the ciphertext
- There is usually no OS keychain, so a credential on a server is less well protected than the same one on a laptop.
The full list, with what each would cost to change, is in the limitations page.
Have a look
It runs on your own machine. There is no account, nothing phones home, and the only hosts it contacts are the providers you connect.
git clone https://github.com/SuperJackfruitLabs/supertoolkit
cd supertoolkit && go build -o stk ./cmd/stk
./stk init
./stk add github && ./stk connect github
./stk doctor --probe # prove your clients go through the broker
./stk run -- your-agent