MCP Proxy Endpoint
Reference for POST /api/proxy/mcp — proxy key auth forms, webhook credential injection, and the tv_session upstream auth type.
POST /api/proxy/mcp
The MCP proxy endpoint. An agent's MCP client points at a proxy URL; Token Vault authenticates the proxy key, evaluates ABAC policies, and forwards the request to your webhook's /v1/proxy with a signed ticket. Your webhook injects the real credential (substituting ${TOKEN} in your header templates) and calls the upstream service; Token Vault streams the response back but never sees the credential.
{
"mcpServers": {
"github": {
"url": "https://api.tokenvault.uk/api/proxy/mcp",
"headers": { "Authorization": "Bearer mcp_…" }
}
}
}Authentication
The proxy's mcp_… key, one of two ways (checked in this order):
| Method | Example | Notes |
|---|---|---|
Authorization header | Authorization: Bearer mcp_… | Preferred |
x-mcp-key header | x-mcp-key: mcp_… | For clients that reserve Authorization |
A ?key= query parameter is not accepted. A long-lived key in a URL is recorded by
every hop that logs a request line and cannot be scrubbed afterwards.
Keys are issued when you create a proxy in the dashboard, shown once, and revocable in one click.
Upstream auth types
| Type | Credential source | Path |
|---|---|---|
| Token (default) | A credential stored on your webhook | TV → webhook /v1/proxy → webhook injects and calls upstream |
tv_session | Token Vault's own session token (tvsess_…), auto-refreshed and bound to an agent | TV injects Authorization: Bearer tvsess_… and dials the upstream directly — no webhook hop, because the injected token is TV's own, not a stored credential |
tv_session is for gating your own MCP servers with Token Vault identities: your server validates the session via the introspection endpoint.
Behaviour notes
- Upstream
3xxresponses are not followed (the bearer must never leak to a redirect target). - Expired stored credentials are refreshed by your webhook before the upstream call — the agent never sees a 401.
- Policy denials: on
GET/DELETE/OPTIONS(no JSON-RPC body), the standardPOLICY_DENIEDbody —403for most rule types,429for an ABACrate_limitrule. OnPOST, arate_limitrule denial is the-32029JSON-RPC shape (429) described below; any other rule denies with the plain403body above (this endpoint has no tool result to attach a non-rate-limit denial to — unlike/api/agents/mcp, it's a transparent proxy with no tools of its own). - Webhook offline →
502with codeWEBHOOK_UNAVAILABLE: a harder form of the kill switch.
Rate limiting and JSON-RPC error shape
This endpoint shares the same penalty box → floor → account-aggregate pipeline as the
MCP credentials endpoint — its own proxy_mcp floor
scope (300/minute per proxy) in place of the agent's agent_credentials scope. initialize,
tools/list, and notifications/* are exempt from the floor and never strike, but still count
against the account-wide aggregate ceiling; the SSE GET transport probe always counts against the
full floor.
A POST denial (limiter, penalty box, or a policy rate_limit rule) comes back as a JSON-RPC error
carrying your request's id, HTTP 429, and Retry-After — the same {"code":-32029,...} shape
documented on the MCP credentials endpoint.
GET/DELETE/OPTIONS denials, which carry no JSON-RPC body, keep the plain-JSON shape shown
above instead.
A JSON-RPC batch body is passed through to your webhook/upstream as-is (this endpoint is a transparent proxy, not a tool server) — it's still rate-limited as a single unit the same way the credentials endpoint's batches are.
Ready to try it?
Sign up free with Google — your credentials stay on your own webhook, and the quickstart gets an agent fetching its first credential in about ten minutes.
MCP Endpoint
Reference for POST /api/agents/mcp — the MCP server exposing list_credentials and get_credential tools, with tvagent_ key or OAuth 2.1 session auth.
Token Refresh
The canonical reference for OAuth token refresh — webhook-autonomous by default, notify hints, and the narrow opt-in TV-mediated path for built-in providers.