# auth.md — agent authentication for 21st

> How an AI agent obtains and uses credentials for https://21st.dev. Audience: agents and the developers wiring them up. Humans sign in at https://21st.dev/sign-in as usual.

## Discovery metadata

- Protected resource metadata (RFC 9728), origin: https://21st.dev/.well-known/oauth-protected-resource
- Protected resource metadata, full MCP: https://21st.dev/.well-known/oauth-protected-resource/api/mcp
- Authorization server metadata (RFC 8414): https://clerk.21st.dev/.well-known/oauth-authorization-server
- Authorization server (issuer): https://clerk.21st.dev
- OpenID Connect discovery: https://clerk.21st.dev/.well-known/openid-configuration

The authorization server is hosted by Clerk at `https://clerk.21st.dev`; https://21st.dev is the resource server only. RFC 9728 metadata on 21st points clients to that issuer, where the RFC 8414 and OpenID discovery documents are canonical.

## What is protected

| Surface | Endpoint | Credentials accepted |
| --- | --- | --- |
| MCP server (full) | https://21st.dev/api/mcp | Clerk OAuth access token, 21st API key, or CLI session token |
| MCP server (read-only) | https://21st.dev/api/mcp/readonly | Clerk OAuth access token, 21st API key, or CLI session token |
| REST API v1 | https://21st.dev/api/v1 | 21st API key (spec: https://21st.dev/openapi.json) |

Browsing and markdown pages need no credential at all. An unauthenticated full MCP call answers `401` with `WWW-Authenticate: Bearer resource_metadata="..."`, which starts the OAuth flow below. The read-only endpoint answers `401` with a generic `Bearer realm="21st"` challenge and no OAuth discovery metadata.

## Method 1: OAuth 2.1 with dynamic client registration

The user signs in and consents on 21st's own pages. Steps:

1. Register a client (RFC 7591): `POST https://clerk.21st.dev/oauth/register` with your `redirect_uris`, `client_name`, `grant_types` (`authorization_code`, `refresh_token`) and `token_endpoint_auth_method` (`none` for public clients). Request scopes from `openid profile email`.
2. Authorize: send the user to `https://clerk.21st.dev/oauth/authorize` with PKCE (`S256` required), `response_type=code`, your `client_id`, `redirect_uri`, and `scope`.
3. Exchange the code at `https://clerk.21st.dev/oauth/token` for an access token (and a refresh token when `offline_access` was granted).
4. Call `https://21st.dev/api/mcp` with `Authorization: Bearer <access_token>`. The same issued token is also accepted by `https://21st.dev/api/mcp/readonly`.
5. Revoke at `https://clerk.21st.dev/oauth/token/revoke` when done.

MCP clients that implement the MCP authorization spec (Claude, ChatGPT, Cursor, VS Code and others) do all of this automatically from the full endpoint's 401 challenge.

## Method 2: API key or CLI session token

Identity type: user-issued credential. A signed-in user creates a key at https://21st.dev/mcp; keys look like `21st_sk_...`. `npx @21st-dev/cli@latest init --client <cursor|claude|codex|vscode|devin> [--write]` prints or writes the MCP client config with a placeholder for that key, it does not issue one (`windsurf` remains an alias for `devin`). For the CLI itself, `21st login` saves a browser-issued session token locally instead.

Send an API key as a Bearer token on every request; that header works on both MCP endpoints and on REST v1:

```http
Authorization: Bearer 21st_sk_...
```

The MCP endpoints additionally accept the same key as `x-api-key: 21st_sk_...` (the header the `@21st-dev/magic` proxy and older client configs send). REST v1 reads `Authorization: Bearer` only and answers `401` to `x-api-key`.

Keys can be rotated or revoked by the user at https://21st.dev/mcp; a revoked key answers `401` immediately. Rate limits and plan quotas are per key and are reported in the REST API's error bodies (see the OpenAPI spec).

## Not supported

Anonymous agent registration, identity assertions (ID-JAG), verified-email claim ceremonies and the client-credentials grant are not offered. Every credential is tied to a human 21st account through OAuth consent, an account-issued API key, or `21st login`.

## Discovery contract

Bootstrap OAuth from https://21st.dev/api/mcp: use its 401 challenge's protected-resource metadata at https://21st.dev/.well-known/oauth-protected-resource/api/mcp, read the `authorization_servers` value, and fetch discovery from that issuer. The resulting Clerk OAuth token also works on https://21st.dev/api/mcp/readonly; that endpoint deliberately returns only a generic Bearer challenge and does not publish a second OAuth discovery document.

More for agents: https://21st.dev/llms.txt · https://21st.dev/mcp.md · https://21st.dev/.well-known/api-catalog
