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
- Client fetches
/.well-known/oauth-protected-resource - Client fetches
/.well-known/oauth-authorization-server - Client registers via
POST /oauth/register - Client redirects user to
/oauth/authorizewith PKCEcode_challenge - User signs in and grants access
- Client exchanges code for token at
POST /oauth/token - Client calls
POST /mcpwithAuthorization: Bearer <token>
Scopes
PageWeave uses two coarse bearer-token scopes:
| Scope | Meaning |
|---|---|
read |
Read-only access to MCP tools |
write |
Every mutating operation (pages, tables, assets, domains, DNS, team invites, ...) |
- OAuth clients always receive both scopes (
read write) — authorization never produces a partial-scope token and there is no step-up flow. The consent screen always grants the full set. - The read-only persona lives in API keys: a key created with the read-only checkbox in Settings → API keys can only call read tools; write tools return
403 Insufficient scope. - Per-tool authorization is role-based, not scope-based: which user may call which tool on which website is enforced server-side from the website role (
viewer/content/editor/admin). Scopes only gate read vs write. - Legacy scope names (the pre-57.0.0
resource:verbvocabulary, e.g.website:write,page:read) are still accepted at the OAuth endpoints and mapped to the coarse scopes, so clients registered before the vocabulary change keep working. Token responses always carry the canonical names (read write), so clients self-heal on refresh. Unknown scope names are still rejected withinvalid_scope.
The protected-resource metadata at /.well-known/oauth-protected-resource (RFC 9728) advertises scopes_supported: ["read", "write"] — MCP clients consult it after a 401.
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 ↗ |
| Claude Code | .mcp.json |
{"type": "http", "url": "https://pageweave.dev/mcp"} |
Claude Code MCP Docs ↗ |
| Claude Desktop | claude_desktop_config.json |
{"command": "npx", "args": ["-y", "mcp-remote", "https://pageweave.dev/mcp"]} |
Claude Desktop Auth Docs ↗ |
| Cursor | .cursor/mcp.json |
{"url": "https://pageweave.dev/mcp"} |
Cursor MCP Docs ↗ |
| Windsurf | mcp_config.json |
{"serverUrl": "https://pageweave.dev/mcp"} |
Windsurf MCP Docs ↗ |
| Continue | config.yaml |
type: streamable-httpurl: https://pageweave.dev/mcp |
Continue MCP Docs ↗ |
What Happens Automatically
- Discovery — Client detects the
401challenge and fetches/.well-known/oauth-protected-resource - Registration — Client registers dynamically via
POST /oauth/register(RFC 7591) - Authorization — Client opens your browser to
/oauth/authorizewith PKCE - Token exchange — Client exchanges the authorization code for tokens
- 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 enforce the same coarse scopes: a key created with the read-only checkbox is limited to read tools. Best for CI/CD and server-to-server use.