---
title: OAuth Setup
description: Configure OAuth 2.1 for MCP clients with PKCE and dynamic client registration.
section: Authentication
order: 1
---

# OAuth Setup

PageWeave acts as an OAuth 2.1 Authorization Server for MCP clients.

## Discovery Endpoints

| Endpoint | RFC | Purpose |
|----------|-----|---------|
| `GET /.well-known/oauth-authorization-server` | RFC 8414 | Authorization server metadata |
| `GET /.well-known/oauth-protected-resource` | RFC 9728 | Protected resource metadata |
| `GET /.well-known/openid-configuration` | OIDC Discovery | OIDC-compatible discovery |
| `POST /oauth/register` | RFC 7591 | Dynamic client registration |

## OAuth Flow

1. Client fetches `/.well-known/oauth-protected-resource`
2. Client fetches `/.well-known/oauth-authorization-server`
3. Client registers via `POST /oauth/register`
4. Client redirects user to `/oauth/authorize` with PKCE `code_challenge`
5. User signs in and grants access
6. Client exchanges code for token at `POST /oauth/token`
7. Client calls `POST /mcp` with `Authorization: Bearer <token>`

## Scopes

34 resource-based scopes control MCP tool access:

| Resource | Scopes |
|----------|--------|
| `website` | `:read`, `:create`, `:edit`, `:delete` |
| `page` | `:read`, `:create`, `:edit`, `:delete` |
| `header` | `:read`, `:edit` |
| `footer` | `:read`, `:edit` |
| `html_head` | `:read`, `:edit` |
| `theme` | `:read`, `:edit` |
| `asset` | `:read`, `:create`, `:delete` |
| `form` | `:read`, `:create`, `:edit`, `:delete` |
| `table` | `:read`, `:create`, `:edit`, `:delete` |
| `row` | `:read`, `:create`, `:edit`, `:delete` |
| `submission` | `:read`, `:delete` |
| `webhook` | `:read`, `:create`, `:edit`, `:delete` |
| `domain` | `:read`, `:create`, `:delete` |
| `dns` | `:read`, `:write` |
| `access` | `:read`, `:delete` |
| `invitation` | `:read`, `:create`, `:delete` |
| `analytics` | `:read` |
| `version` | `:read`, `:pin`, `:unpin`, `:revert` |
| `preview` | `:read`, `:start`, `:stop` |

Default scopes for new clients: all `*:read` scopes. Write scopes must be explicitly requested.

## Token Lifetime

OAuth tokens expire after 1 hour. Clients should refresh tokens before expiration.

## Client Setup

All modern MCP clients support automatic OAuth 2.1 discovery and authentication. Add the MCP endpoint URL and the client handles the rest.

### Minimal Configs

| Client | Config File | Minimal Config | Docs |
|--------|-------------|----------------|------|
| **OpenCode** | `opencode.json` | `{"type": "remote", "url": "https://pageweave.dev/mcp", "enabled": true, "oauth": {}}` | [OpenCode MCP Docs ↗](https://opencode.ai/docs/mcp-servers/) |
| **Claude Code** | `.mcp.json` | `{"type": "http", "url": "https://pageweave.dev/mcp"}` | [Claude Code MCP Docs ↗](https://code.claude.com/docs/en/mcp) |
| **Claude Desktop** | `claude_desktop_config.json` | `{"command": "npx", "args": ["-y", "mcp-remote", "https://pageweave.dev/mcp"]}` | [Claude Desktop Auth Docs ↗](https://claude.com/docs/connectors/building/authentication) |
| **Cursor** | `.cursor/mcp.json` | `{"url": "https://pageweave.dev/mcp"}` | [Cursor MCP Docs ↗](https://cursor.com/docs/mcp) |
| **Windsurf** | `mcp_config.json` | `{"serverUrl": "https://pageweave.dev/mcp"}` | [Windsurf MCP Docs ↗](https://docs.windsurf.com/windsurf/cascade/mcp) |
| **Continue** | `config.yaml` | `type: streamable-http`<br>`url: https://pageweave.dev/mcp` | [Continue MCP Docs ↗](https://docs.continue.dev/customize/deep-dives/mcp) |

### What Happens Automatically

1. **Discovery** — Client detects the `401` challenge and fetches `/.well-known/oauth-protected-resource`
2. **Registration** — Client registers dynamically via `POST /oauth/register` (RFC 7591)
3. **Authorization** — Client opens your browser to `/oauth/authorize` with PKCE
4. **Token exchange** — Client exchanges the authorization code for tokens
5. **Storage & refresh** — Tokens are stored securely and refreshed automatically

No manual token management required.

### API Key Fallback

For programmatic access or legacy clients, authenticate with API keys (`pagew_...`) via `Authorization: Bearer <key>`. API keys bypass all scope checks and provide full access. Best for CI/CD and server-to-server use.
