Issue MCP access tokens
Do this when something outside a browser needs to call AgentArea — a harness connecting to an MCP endpoint, a CI job starting a task, a script. Do not use these for a downstream MCP server’s own credential; that is the server’s secret, covered in Pass secrets to an MCP server. One token type covers the whole API. The same key authenticates/v1/mcp/{instance_id}/mcp, /client-mcp/{client_id}, task creation, and A2A.
Prerequisites
- A browser session or an existing key with access to the workspace. Key management is behind normal authentication.
- Somewhere to put the token immediately. The raw value is returned once.
Steps
1. Create a key
token appears in this 201 response and nowhere else. Only a SHA-256 hash is
stored, so a lost token cannot be recovered — create a new one and revoke the old.
Omit expires_in_days for a non-expiring key. Prefer an expiry for anything on a
laptop or in a build.
2. Use it
Every endpoint takes the same bearer header. Theaat_ prefix is what routes the
token to API-key validation rather than JWT or OAuth verification.
mcp_endpoint_url and
this token together — see Combine several MCP servers behind one
endpoint.
3. Audit what exists
token_prefix is the first 12 characters, which is how you identify a key
without the secret. access_count and last_accessed_at tell you whether a key
is still in use — check both before revoking one nobody claims.
4. Rotate
There is no rotate endpoint. Rotation is create-then-revoke, in that order:Verify
Confirm the new key authenticates and that the old one no longer does.access_count increments on use:
Troubleshooting
401 on every call with a newly created token. Check the prefix survived the copy. A token without theaat_ prefix is routed to JWT verification, fails
there, and reports the same 401 as a bad key. Shell quoting that drops the
underscore is the usual cause.
401 after weeks of working. The key expired. expires_at is set at creation
from expires_in_days and cannot be extended — PATCH is not supported on keys.
Create a replacement.
A client endpoint answers with “Not authorized for this client”. The key
authenticated but is not authorized for that client bundle, and because
/client-mcp/{client_id} speaks MCP the refusal arrives as a JSON-RPC error
rather than an HTTP 403. A workspace key is not automatically permitted to use a
registered client; the principal needs the use relation on it, or the token’s
subject must be the client itself.
A key you revoked still appears in the list. Revocation sets is_active to
false rather than deleting the row, so the audit trail survives. Filter on
is_active when you want live keys.
404 revoking a key by its prefix. DELETE takes the key’s id, not its
token_prefix. Look up the id from the list first.
You need per-endpoint scoping. These keys carry the workspace access of the
principal that created them; there is no per-endpoint or read-only scope on the
key itself. Constrain what a consumer can reach with governance policy and, for
MCP bundles, by curating the client’s member instances — not by scoping the token.