
auth_headers() -> dict[str, str] is a valid session. A paywalled API
returns its tokens; a public API returns an empty dict. This is the design that keeps
the engine API-agnostic — adding an API is data (the spec) plus, at most, this one
adapter.
Sessions you get out of the box
Session
A two-token authenticated session (JWT + API token). Returned by the access
handshake.
NoAuthSession
For public, no-auth APIs —
auth_headers() returns an empty dict.stub_session
A non-live session for recorded demos: auth headers are present but not real.
Store your keys safely — the credential resolver
You don’t have to hand-write aSession. Gecko ships a credential resolver that keeps
provider secrets in your OS keychain and injects them at call time — the key never
enters the agent’s context, shell history, a dotfile, or a log, and it never leaves
your machine.
op / vault / pass) → an environment variable (CI/headless). For CI, just
export COLOSSEUM_COPILOT_PAT=....
Local vs hosted. Because the key stays on your machine, an API that needs your
key runs locally (
gecko auth set … then serve it). The hosted
mcp.geckovision.tech serves only the public surfaces — Gecko never holds a user’s
key, so a keyed, per-person API can’t be a shared hosted surface.How auth gating works
When a session returns an empty auth-header dict, Gecko treats it as “this session can’t satisfy auth-gated operations” and hides those operations from the agent — it could only mis-call them. A session with auth surfaces everything, unchanged. If an auth-gated tool is forced anyway,prepare() raises a typed error
rather than firing a request that can’t succeed.
The two-token handshake (worked example)
The live reference integration (the TxODDS World Cup API) uses a flow the agent never has to learn. Gecko encodes it so the agent only ever describes intent:The on-chain step
Thesubscribe transaction itself is a wallet-signing, network-specific step that
lives outside the access layer (in scripts/). The access layer takes the resulting
txSig plus a signer and finishes the session.
Short-lived tokens & OAuth — auto-refresh
Most production APIs hand you a short-lived access token plus a refresh token (the OAuth pattern). Gecko manages that lifecycle for you, behind the sameauth_headers() seam — the agent never sees an expiry:
- Proactive refresh — when the token is within a leeway window of expiry, the session refreshes it before returning headers.
- Reactive self-heal — if a live call still comes back
401, Gecko re-authenticates and retries the identical call once (bounded — a second failure raises a typed, redacted error, never an infinite loop).
OAuth2Lifecycle refreshes via a refresh_token grant,
and adapters like oauth2_from_dpo2u() read a local token file and refresh on their own.
What Gecko never does with credentials
- It never exposes auth headers in the agent-facing tool definitions.
- It never logs tokens or keys — secrets are redacted before any error is raised.
- Its control plane never stores or transmits your secret: the credential resolver reads it from your local OS keychain (or env) and injects it at call time, on your machine. Gecko only ever sends it toward the API’s own host — never anywhere else.