OAuth is the second way a client can authenticate, and it exists for one practical reason: several connector interfaces — Claude Desktop’s custom connectors among them — have no field for a bearer token. They expect to be handed a URL, discover the rest for themselves, and send the user off to sign in.
With OAuth enabled, a client needs nothing but your endpoint URL.
Turning it on
Sokket → Settings → General → Enable OAuth 2.1, then save.
OAuth requires the MCP server itself to be enabled — the toggle alone does nothing. While OAuth is off, the discovery documents return 404 and connector interfaces have no way to configure themselves. Manually issued bearer tokens keep working either way.
The current state is shown on Sokket → Connections → OAuth, along with the three URLs a client uses.
What a connection looks like end to end
- Your client fetches the discovery documents from your site root and learns where everything lives.
- It registers itself (dynamic client registration) and gets a client ID.
- It opens your site’s authorization page in a browser.
- WordPress asks the person to sign in, if they aren’t already.
- The consent screen names the client and asks them to choose Read-only or Full access.
- On approval, the client receives a short-lived authorization code, exchanges it for tokens, and starts making MCP calls.
Every connection is bound to the WordPress user who approved it and acts as that user, with exactly the same capability checks as a bearer token.
Discovery
Sokket serves the two standard metadata documents at your site root, above the REST namespace:
| Document | Path |
|---|---|
| Protected resource metadata (RFC 9728) | /.well-known/oauth-protected-resource |
| Authorization server metadata (RFC 8414) | /.well-known/oauth-authorization-server |
Both accept the resource path appended after the document name, as the RFCs allow. They advertise the endpoints:
| Endpoint | URL |
|---|---|
| Authorization | https://yoursite.com/sokket-oauth/authorize |
| Token | https://yoursite.com/wp-json/sokket/v1/oauth/token |
| Dynamic client registration | https://yoursite.com/wp-json/sokket/v1/oauth/register |
| Revocation | https://yoursite.com/wp-json/sokket/v1/oauth/revoke |
Supported: the authorization_code and refresh_token grants, the code response type, and PKCE with S256 — the only code challenge method offered, and required.
Scopes and access levels
There are two scopes:
| Scope | Meaning |
|---|---|
mcp:read | Read tools only. Every write tool is blocked. |
mcp:write | Write tools permitted, subject to the user’s capabilities. |
On the consent screen these appear as Read-only and Full access. Two rules govern the result:
- A client that asked only for
mcp:readcannot be upgraded on the consent screen. If it didn’t request write access, it doesn’t get it, whatever the user picks. - The granted scope is canonical. A grant without
mcp:writeis treated as read-only on every request, regardless of anything else stored on the row.
OAuth grants are not per-tool. Unlike a bearer token, an OAuth connection has no tool allowlist — within its access level, it can reach every tool the bound user has the capability for. If you need a connection restricted to a specific handful of tools, issue a bearer token instead. The finer control is the reason to prefer tokens when your client supports them.
The consent screen
The person approving sees who is asking (the client’s registered name), which site they are connecting to, which WordPress account they are signed in as, and the two access levels to choose between. Approving redirects back to the client; declining sends an access_denied error back instead.
By default any user who can read — that is, any logged-in user — may approve a connection for their own account. Their capabilities still bound everything the connection can do. Sites that want to restrict this to certain roles can use the sokket_oauth_user_can_authorize filter; see the Developer Reference.
Token lifetimes
| Credential | Lifetime |
|---|---|
| Authorization code | 5 minutes, single use |
| Access token | 1 hour |
| Refresh token | 30 days |
Clients refresh silently, so a working connection stays working without anyone signing in again. A scheduled cleanup task prunes expired codes and tokens from the database.
Managing connections
Sokket → Connections → OAuth has two tables.
Active connections lists every approved grant: the client, the WordPress user, the access level (Read-only or Full access), when it was approved, and when it was last used. Revoke kills it immediately — the access and refresh tokens stop working on the next request, and the client has to go through consent again.
Registered clients lists the applications that may start an authorization. Clients that discover your site register themselves and are marked Self-registered; ones you add by hand are marked Added by admin. Each row shows the client ID, its redirect URIs, its origin, and when it was last used, with a Delete action.
Adding a client by hand
Only needed for an interface that asks you to paste a client ID and secret rather than registering itself. Under Add a client manually:
- Name — how it appears on the consent screen, e.g. Claude Desktop.
- Redirect URIs — one per line, matched byte for byte. HTTPS only, except on
localhost. A trailing slash that the client doesn’t send is enough to break the flow. - Issue a client secret — tick only if that interface asks for one. Apps that can’t keep a secret (desktop and mobile clients) should rely on PKCE instead, which Sokket requires anyway.
The client secret, like a bearer token, is shown once and stored only as a hash.
New tools and existing OAuth connections
Because grants are scope-based rather than per-tool, an already-connected client picks up newly added tools automatically — subject to its access level. A read-only connection will not gain new write tools; to grant those, the user has to reconnect and choose Full access.
One practical caveat: clients cache the tool list from the handshake, and this server does not push a tools/list_changed notification. After a plugin update that adds tools, reconnect the server in your client (or restart it) so the new tools appear.
Security notes
- PKCE
S256is required on every authorization, so an intercepted code is useless without the verifier. - Redirect URIs are matched exactly against the registered set. Errors that can’t be attributed to a verified redirect URI are rendered on screen rather than redirected, as OAuth 2.1 requires.
- Tokens are stored as hashes, never in plaintext, and looked up without caching.
- Turning the toggle off immediately 404s discovery and rejects every OAuth-authenticated request, without touching your bearer tokens.