> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokencraft.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP OAuth

> Connect MCP clients to Tokencraft with OAuth — no manual API key required

# MCP OAuth

Tokencraft hosts a remote MCP server at `https://app.tokencraft.dev/api/mcp`. MCP clients such as **Cursor**, **Claude** (remote MCP), and the **Figma plugin** authenticate via OAuth instead of pasting an API key.

<Note>
  For CI/CD and automation scripts, use [manual API tokens](/authentication) instead of OAuth.
</Note>

## Why OAuth?

| Use case                                | Auth                                                      |
| --------------------------------------- | --------------------------------------------------------- |
| Cursor, Claude remote MCP, Figma plugin | **OAuth** (this page)                                     |
| CI/CD, GitHub Actions, scripts          | **API key** (`tkc_…`) — [Authentication](/authentication) |

OAuth benefits:

* No token to copy into config files
* Scoped consent per application (`read:tokens`, `write:tokens`, `export:tokens`)
* Revocable from [API Settings](https://app.tokencraft.dev/api-settings)
* 30-day access tokens, automatically renewed on re-authorization

## Discovery endpoints

MCP clients discover OAuth metadata automatically:

| Endpoint                                      | Purpose                                    |
| --------------------------------------------- | ------------------------------------------ |
| `GET /.well-known/oauth-authorization-server` | Authorization server metadata (RFC 8414)   |
| `GET /.well-known/oauth-protected-resource`   | Protected resource metadata for `/api/mcp` |

Example authorization server metadata:

```json theme={null}
{
  "issuer": "https://app.tokencraft.dev",
  "authorization_endpoint": "https://app.tokencraft.dev/mcp/authorize",
  "token_endpoint": "https://app.tokencraft.dev/api/oauth/mcp/token",
  "registration_endpoint": "https://app.tokencraft.dev/api/oauth/mcp/register",
  "revocation_endpoint": "https://app.tokencraft.dev/api/oauth/mcp/revoke",
  "scopes_supported": ["read:tokens", "write:tokens", "export:tokens"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_post", "none"]
}
```

When a client calls `/api/mcp` without a token, the server responds with `401` and a `WWW-Authenticate` header pointing to the protected-resource metadata. The client then starts the OAuth flow.

## Authorization flow

```mermaid theme={null}
sequenceDiagram
  participant Client as MCP_Client
  participant Auth as mcp_authorize
  participant Token as api_oauth_mcp_token
  participant MCP as api_mcp

  Client->>Auth: GET /api/oauth/mcp/authorize (PKCE + scopes)
  Auth->>Auth: User logs in (if needed)
  Auth->>Client: Redirect with authorization code
  Client->>Token: POST /api/oauth/mcp/token
  Token->>Client: access_token (30 days)
  Client->>MCP: Bearer token on /api/mcp
```

### Steps

1. **Authorize** — Client redirects the user to `/api/oauth/mcp/authorize` with:
   * `client_id`, `redirect_uri`, `response_type=code`
   * `scope` (space-separated scopes)
   * `state` (CSRF protection)
   * `code_challenge` + `code_challenge_method=S256` (PKCE, recommended)

2. **Consent** — User reviews the request on `/mcp/authorize` and approves or denies.

3. **Code exchange** — Client posts to `/api/oauth/mcp/token`:

```bash theme={null}
curl -X POST https://app.tokencraft.dev/api/oauth/mcp/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "redirect_uri=https://your-app/callback" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "code_verifier=PKCE_VERIFIER"
```

4. **Use token** — Include the access token in MCP requests:

```
Authorization: Bearer <access_token>
```

## Scopes

| Scope           | Access                                                              |
| --------------- | ------------------------------------------------------------------- |
| `read:tokens`   | List and read workspaces, tokensets, modes, tokens                  |
| `write:tokens`  | Create, update, delete resources (subject to workspace permissions) |
| `export:tokens` | Export tokensets and modes (JSON, CSS, iOS, Android)                |

## Dynamic client registration

MCP clients can register automatically (RFC 7591):

```bash theme={null}
curl -X POST https://app.tokencraft.dev/api/oauth/mcp/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My MCP Client",
    "redirect_uris": ["https://my-app.example/callback"]
  }'
```

Response includes `client_id` and `client_secret`. Public clients using PKCE can authenticate with `token_endpoint_auth_method: none`.

## Token lifecycle

* **Authorization codes** expire after 10 minutes and are single-use.
* **Access tokens** expire after 30 days.
* Tokens are stored in the `api_tokens` table and named `MCP OAuth — {client name}`.
* OAuth tokens are 64-character hex strings (no `tkc_` prefix).
* They authenticate identically to manual API tokens via `Authorization: Bearer`.

## Revocation

Revoke a token in either way:

1. **Dashboard** — [API Settings](https://app.tokencraft.dev/api-settings) → delete the `MCP OAuth — …` token
2. **API** — `POST /api/oauth/mcp/revoke` with the token value

```bash theme={null}
curl -X POST https://app.tokencraft.dev/api/oauth/mcp/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_TOKEN"
```

## Connect a remote MCP client

### Cursor

1. Open **Cursor Settings → MCP**
2. Add a remote server with URL: `https://app.tokencraft.dev/api/mcp`
3. On first use, Cursor opens the browser for OAuth consent
4. Approve the requested scopes — no manual token needed

### Claude (remote MCP)

Add the hosted URL in your client's remote MCP configuration. The client discovers OAuth via the well-known endpoints.

## Figma plugin OAuth

The Figma plugin cannot receive browser redirects directly. It uses a polling bridge:

1. Plugin opens `/api/oauth/mcp/authorize` in the system browser (`client_id=figma-plugin-v1`)
2. User logs in and consents
3. Browser redirects to `/mcp/figma-callback?code=…&state=…`
4. Plugin polls `GET /api/oauth/figma-plugin/poll?state=…` until the code is available
5. Plugin exchanges the code at `/api/oauth/mcp/token` with PKCE

See [Figma Integration](/integrations/figma) for the full plugin guide.

## Rate limits

OAuth tokens share the same rate limits as manual API tokens: **100 requests per minute** per token.

## Next steps

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/mcp/configuration">
    Hosted vs local MCP setup
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    Manual API tokens for CI/CD
  </Card>

  <Card title="Tools" icon="wrench" href="/mcp/tools">
    Available MCP tools
  </Card>

  <Card title="Figma" icon="figma" href="/integrations/figma">
    Figma plugin OAuth flow
  </Card>
</CardGroup>
