# Kitepod auth.md

How an AI agent or MCP client gets access to Kitepod. Kitepod is a remote MCP server that reaches a person's self-hosted WordPress sites; every token acts for a signed-in person, on the sites they connected.

## Audience

MCP clients and AI agents (Claude, ChatGPT, Cursor, Claude Code and any client that speaks MCP over Streamable HTTP with OAuth 2.1).

## Discover

1. `POST https://kitepod.com/mcp` without a token returns `401` with `WWW-Authenticate: Bearer resource_metadata="..."`.
2. Protected Resource Metadata (RFC 9728): `https://kitepod.com/.well-known/oauth-protected-resource`. The resource is `https://kitepod.com/mcp` and the authorization server is `https://kitepod.com/api/auth`.
3. Authorization Server Metadata (RFC 8414): `https://kitepod.com/.well-known/oauth-authorization-server/api/auth` (also at `https://kitepod.com/.well-known/oauth-authorization-server`).

## Register

Pick one. Neither needs a secret pasted anywhere.

- **Client ID Metadata Document:** use an HTTPS URL that serves your client metadata as your `client_id`. No registration call.
- **Dynamic Client Registration (RFC 7591):** `POST https://kitepod.com/api/auth/oauth2/register`. Public clients use `token_endpoint_auth_method: "none"`. Desktop clients with loopback redirect URIs (`http://localhost`, `http://127.0.0.1`) are registered as native apps.

Kitepod does not create accounts for agents on their own. A person signs in to Kitepod and approves the client.

## Authorize

Authorization code flow with PKCE (S256) at `https://kitepod.com/api/auth/oauth2/authorize`, then `https://kitepod.com/api/auth/oauth2/token`. The person sees a consent page listing the scopes and can untick the optional ones. Ask for `offline_access` to get a refresh token.

| Scope | Grants |
| --- | --- |
| `sites:read` | Content, settings, history and health. Comes with any site scope. |
| `sites:write` | Write, edit and publish posts, pages, media, menus and SEO. Every change can be undone. |
| `sites:design` | Styles, templates and the customizer. |
| `sites:code` | Theme files, snippets and files in wp-content (needs Code turned on in wp-admin). |
| `sites:admin` | Plugins, themes, users and advanced settings. |

Without a `scope` parameter a client gets `openid profile email offline_access sites:read sites:write`.

## Use

Send the access token as `Authorization: Bearer <token>` on `POST https://kitepod.com/mcp` (Streamable HTTP). The tools a token sees follow its scopes. On every call the site still applies its own approval policy and the capabilities of the WordPress user chosen when it was connected: some writes return `pending_approval` with a link a person must open, and an agent can never approve its own work.

## Revoke

`POST https://kitepod.com/api/auth/oauth2/revoke` (RFC 7009). A person can also disconnect a client from the Kitepod dashboard; its tokens stop working at once.
