WordPress MCP OAuth 2.1 with PKCE: Setup and Clients
WordPress MCP OAuth 2.1 with PKCE in GoBuildWP: discovery endpoints, client registration, consent, token lifetimes, revocation and which clients use it.
OAuth 2.1 with PKCE exists here so that a browser-based client never has to hold a long-lived WordPress credential. The user signs in on the site, the site issues a token scoped to that user, and the client gets something it can lose without you having to change a password. It is more moving parts than an Application Password, and it is the right trade when the client is shared, hosted, or not entirely yours.
What you will do 6 steps
Confirm HTTPS and pretty permalinks
Open Connect and pick your client
Copy the OAuth endpoint
Authorize in the browser
Verify the token and connected app
Revoke when finished
When to choose OAuth over an Application Password
OAuth is the better route whenever the client supports it. The client never stores a WordPress password, each authorization is bound to one WordPress user and one client, tokens expire on their own, and you can revoke a single client from WordPress without disturbing anything else.
Use an Application Password when the client supports that generated route and core Application Password availability and HTTPS policy permit it, including applicable local-development exceptions. A local bridge can reach a private site only through its own network access; switching credentials does not change reachability.
- The site is served over HTTPS with a trusted certificate
- Pretty permalinks are enabled so /wp-json/ URLs resolve
- Your CDN, WAF or security plugin allows /wp-json/mcp/wppilot-oauth, the discovered registration/token/revocation routes under /wp-json/wppilot/v1/oauth/, /.well-known discovery and the WordPress authorization/consent flow; /wp-json/mcp/wppilot serves the separate credential route
- You are signed in to WordPress as the user the connection should act as
What GoBuildWP exposes
The OAuth-authenticated MCP endpoint is /wp-json/mcp/wppilot-oauth on your own site. Application Password clients use /wp-json/mcp/wppilot instead. Both are served by your WordPress install; no GoBuildWP-hosted service sits in the middle.
Use the generated /wp-json/mcp/wppilot-oauth endpoint and the discovery and authentication steps for your particular client. Standards support does not guarantee configuration from the base URL alone. GoBuildWP publishes /.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource and /.well-known/openid-configuration. Dynamic client registration is supported, which is why most clients need nothing more than the endpoint URL.
The only scope is mcp. GoBuildWP deliberately does not model permissions as OAuth scopes, because the real authority comes from the WordPress user's capabilities, the abilities you have enabled, and the active safety profile. A token cannot grant more than the person who authorized it already had.
Run the authorization flow
Open the GoBuildWP Connect screen, choose your exact client, and copy the generated configuration. On a public site almost every client runs the flow itself against the remote URL, from Claude Code, Cursor and VS Code to Zed, Cline, Kilo Code, OpenCode, Amazon Q and Kiro, OpenClaw and Devin Desktop; some then need one command to start the sign-in, such as codex mcp login or openclaw mcp login. Roo Code is the exception and uses the npx mcp-remote bridge, which performs the same flow locally. On a site the Connect screen sees as local, every OAuth entry uses that bridge.
The client opens your WordPress login and a consent screen naming the application. Approve it while signed in as the WordPress user the agent should act as. This is the single most consequential choice in the setup: the connection inherits that user's capabilities.
The exchange uses the authorization code grant with PKCE. The authorization code is single-use and expires after one minute, so if you leave the consent screen open and come back later the client will simply start again.
- The consent screen names the client you expect
- You are logged in as the intended WordPress user, not an unrelated administrator
- The client reports the server as connected afterwards
- Ability discovery returns results
Token lifetimes and refresh
Access tokens are valid for one hour. Refresh tokens are valid for fourteen days and are used automatically by the client to obtain a new access token without prompting you.
If a client sits unused for longer than fourteen days, the refresh token expires and the next request fails with an authorization error. That is expected behaviour, not a fault: re-run the authorization flow and the client reconnects.
Short access tokens are the reason OAuth is preferable on a production site. A leaked access token is useful for at most an hour, whereas a leaked Application Password stays valid until someone revokes it.
Review and revoke connected apps
WordPress shows a Connected Apps screen listing every application currently holding an authorization for your user, with the scope it was granted. Revoking an entry immediately invalidates its tokens.
Review this list on the same cadence you review users. Revoke anything you no longer recognise, anything tied to a machine you no longer control, and any client you set up for a one-off task.
Revoking a client does not remove the WordPress user, change the safety profile, or undo work already recorded in the change ledger. It only ends that client's ability to make new calls.
- Every listed application is one you recognise
- One-off or evaluation clients have been revoked
- Departed team members no longer hold an authorization
- The remaining connections belong to users with appropriate capabilities
When the flow fails
A browser flow that never returns needs callback, discovery and security-layer diagnosis. Confirm that /.well-known/oauth-authorization-server returns JSON from the same network the client is on.
If the flow completes but the client reports unauthenticated, inspect token validity, exact issuer/resource values and the returned error, then check whether Authorization reaches WordPress. Header stripping is one possible cause.
A hosted remote connector cannot reach a private site without an appropriate network path. A locally running bridge may reach it if its own network can. OAuth or Application Password selection changes authentication, not reachability.
Which clients sign in with OAuth, and how
Every client in the registry can use OAuth 2.1; what differs is who runs the flow. The client runs the OAuth 2.1 flow itself against your site. An Application Password or access token is the alternative where the client lists it.
| Client | OAuth path | Other credentials it accepts |
|---|---|---|
| Claude Code | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Claude Desktop | Desktop, CLI and IDE clients with native OAuth | Desktop extension bundle, Access token, Application Password |
| Claude on the web | Web and hosted apps | Access token |
| ChatGPT | Web and hosted apps | None: OAuth only |
| Mistral Le Chat | Web and hosted apps | Access token |
| Manus | Web and hosted apps | Access token |
| Perplexity | Web and hosted apps | Access token |
| Codex desktop app | Desktop, CLI and IDE clients with native OAuth | None: OAuth only |
| Codex CLI | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Cursor | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| VS Code | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Factory Droid | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Kimi Code CLI | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Qwen Code | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| ZCode (GLM) | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| GitHub Copilot | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Antigravity CLI | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Antigravity IDE | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Devin Desktop | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Zed | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Cline | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| OpenClaw | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Kilo Code | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Amazon Q | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| OpenCode | Desktop, CLI and IDE clients with native OAuth | Access token, Application Password |
| Roo Code | Clients that use the mcp-remote bridge | Access token, Application Password |
Questions this guide answers
What is the OAuth endpoint, and is anything hosted by GoBuildWP?
The OAuth-authenticated MCP endpoint is /wp-json/mcp/wppilot-oauth on your own site; Application Password clients use /wp-json/mcp/wppilot. Both are served by your WordPress install. No GoBuildWP-hosted service sits in the middle.
How long do the tokens last?
Access tokens are valid for one hour and refresh tokens for fourteen days, with the client refreshing automatically. A client left unused for more than fourteen days will fail its next request; re-run the authorization flow and it reconnects.
What OAuth scopes does GoBuildWP use?
One, mcp. Permissions are deliberately not modelled as scopes, because the real authority comes from the WordPress user's capabilities, the abilities you have enabled and the active safety profile. A token cannot grant more than the person who authorized it already had.
The browser flow never returns. What should I check?
Either the callback could not reach the client or a security layer blocked discovery. Confirm /.well-known/oauth-authorization-server returns JSON from the same network the client is on, and that issuer, resource and redirect_uri match the actual registration and discovery values. An alias alone is not evidence of failure.
How do I revoke a client's access?
From the WordPress Connected Apps screen, which lists every application currently holding an authorization for your user. Revoking invalidates its tokens immediately. It does not remove the WordPress user, change the safety profile, or undo work already recorded in the change ledger.
Review noteRequirements and credential methods follow the shipped GoBuildWP source (WordPress 6.9+, PHP 8.0+). Client menus, account plans and third-party behaviour can change; use the installed version and live schema. Our evidence standard.