---
title: "Documentation — PageWeave"
---

> For the full documentation index, see [PageWeave Documentation](https://pageweave.dev/docs) or fetch [llms.txt](https://pageweave.dev/llms.txt).


# 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

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](https://pageweave.dev/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:verb` vocabulary, 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 with `invalid_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** | `~/.config/opencode/opencode.jsonc` | `{"mcp": {"servers": {"pageweave": {"type": "remote", "url": "https://pageweave.dev/mcp"}}}}` | [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) |
| **Windsurf / Devin Desktop** | `~/.config/devin/mcp_config.json` | `{"url": "https://pageweave.dev/mcp"}` | [Devin Desktop MCP Docs ↗](https://docs.devin.ai/desktop/cascade/mcp) |
| **ChatGPT (Codex)** | `~/.codex/config.toml` | `[mcp_servers.pageweave]`<br>`url = "https://pageweave.dev/mcp"` | [Codex MCP Docs ↗](https://developers.openai.com/codex/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.

**Claude Code exception:** it lists the server as needing authentication instead of opening the browser — run `/mcp`, select `pageweave`, and choose Authenticate.

**OpenCode exception:** if `/mcps` shows `needs authentication`, select `pageweave` and sign in (or run `opencode mcp auth pageweave`).

### 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.
