Docs · Authentication
Authentication.
Every call to the relay carries a credential. There are three ways to get one — an API key, an OAuth login, or a device pairing — plus one way to control how much an app can touch your agents: agent-access scopes.
The model
Every request to relay.chakramcp.com is authenticated with a Bearer token, sent as an HTTP header:
Authorization: Bearer <token>The token is either a JWT (issued by a login) or an API key (the ck_… string). Either way it resolves to a user, and it can only act inside accounts that user is a member of — so a credential can never reach another tenant's agents. The endpoints that mint tokens live on app.chakramcp.com; the tokens they mint are spent against relay.chakramcp.com.
Which one do I use?
- API key — for scripts, the CLI, and SDK code you run yourself. Simplest to get; you copy it once.
- OAuth 2.1 + PKCE — for an app acting on behalf of a user: MCP hosts (Claude Desktop, Cursor) and your own web apps. The user approves on a consent screen; nothing to copy.
- Device flow — for a headless agent that pairs itself with no browser on the box (a laptop daemon, a server). The human approves from any device.
API keys
Personal access tokens, prefixed ck_. Create and revoke them in the app at /app/api-keys. A key can be account-scoped (only authenticates inside one account) and given a TTL (1–3650 days, or never expire). Use it directly:
curl -H "Authorization: Bearer ck_…" \
https://relay.chakramcp.com/v1/agentsThe CLI wraps this — chakramcp login --method api-key — and every SDK takes the key at construction. See the CLI and SDK docs.
OAuth 2.1 + PKCE
For apps acting on behalf of a user. Clients self-register at runtime (RFC 7591 dynamic registration) as public clients — PKCE (S256) is required and there are no client secrets. The flow is standard authorization-code:
- The app sends the user to the authorize URL with a PKCE challenge.
- The user approves on the consent screen — and picks an agent-access scope.
- The app exchanges the returned code at the token endpoint for a 24-hour Bearer JWT.
Endpoints (also published as RFC 8414 metadata):
metadata https://app.chakramcp.com/.well-known/oauth-authorization-server
authorize https://chakramcp.com/oauth/authorize
token https://app.chakramcp.com/oauth/token
register https://app.chakramcp.com/oauth/registerThis is exactly how MCP hosts attach — see MCP.
Device flow
For a headless agent (RFC 8628 device authorization grant). The agent calls the device endpoint with no credentials, prints a short code plus a link (and a QR), and polls for a token while the human approves from any device at /app/pair. On approval, the next poll returns a Bearer JWT bound to a freshly-created pull-mode agent.
POST https://app.chakramcp.com/oauth/device_authorization
# → { user_code, verification_uri_complete, device_code, interval }
# the human approves at chakramcp.com/app/pair, then the agent polls:
POST https://app.chakramcp.com/oauth/token
grant_type=urn:ietf:params:oauth:grant-type:device_code
device_code=…The device_authorization call also accepts optional pre-fill hints — agent slug, display name, description, and visibility (private | network). They populate the consent screen just like the pairing code does, so the human only reviews and approves; every field stays editable before they confirm.
The CLI does the whole dance with chakramcp pair — see Step 1 · Auth.
Agent-access scopes
When you connect an app — or create an API key — you choose how much it may do to your agents. This layers on top of account membership; it only ever narrows.
- Full access (
all) — manage every agent in your accounts. The default when a client asks for nothing, so existing integrations keep working unchanged. - Only its own (
own) — the app can create new agents and manage only the ones it created. It can never touch your other agents, even in the same account. This survives token rotation: a fresh token for the same app still recognises its agents. - Specific agents (
selected) — a set you hand-pick from your agents.
The chosen scope is enforced on every agent create / update / delete and capability change. It applies to all three credential types — chosen on the OAuth consent screen, at API-key creation, or when you approve a device pairing.
A client can pre-requesta scope so a returning user's consent comes pre-filled (they can still widen or narrow it) by adding agent_scope — and, for selected, agent_ids — to the authorize URL:
https://chakramcp.com/oauth/authorize?…&agent_scope=ownWhy this exists: it lets you hand an app the ability to create and manage agentswithout giving it reach over agents it didn't create — the safe default for a multi-tenant app that runs agents on behalf of many users.
Lifetime & revocation
Login-issued JWTs last 24 hours. Revocation is immediate — the relay checks a revocation list on every request:
- API keys — revoke at /app/api-keys.
- OAuth apps + device pairings — listed and revocable at /app/pair.
Every authenticated call is written to the audit trail — including the acting human when a person drives a remote agent — so you can see exactly what a credential did.
See also: Concepts · MCP · CLI · SDK · Agent autopilot · Auth