This page is for people building an MCP client. If you use Claude Code, Codex or Cursor, the client does all of this for you — see the quickstarts. The theme MCP server follows the MCP authorization specification: OAuth 2.1 with PKCE, Protected Resource Metadata (RFC 9728), Authorization Server Metadata (RFC 8414), Dynamic Client Registration (RFC 7591) and Resource Indicators (RFC 8707).

1. Discover

Call the server without a token. It answers 401 and points at its metadata:
Fetch the protected resource metadata to find the authorization server, then fetch /.well-known/oauth-authorization-server for its endpoints. Read endpoints from the metadata rather than hard-coding them.

2. Register

Register once per installation. Clients are public clients — there is no client secret — so token_endpoint_auth_method is none.
client_name is what the merchant sees on the consent screen, and what the issued key is named after. Use your product’s real name.

3. Authorize

Create a PKCE verifier (43–128 characters) and its S256 challenge, then send the user’s browser to the authorization endpoint:
The server validates the client, the exact redirect_uri, the PKCE challenge (S256 only) and the resource, then redirects the user to the PlatformDTC consent page. There the user signs in, sees your client_name, the host you will redirect to and the requested scopes, chooses a store, may remove scopes, and approves or denies. On approval the browser returns to your redirect_uri:
Check that state matches. The granted scopes may be fewer than you requested — read scope from the token response, and do not offer actions the grant does not cover.

4. Exchange the code

The access token is an sq_agt_* Agent Gateway key: bound to the store the user chose, carrying only the granted scopes, expiring after 1 hour, and named OAuth: <client_name>. It works on the MCP server and directly on the Agent Gateway /themes endpoints.

5. Call the server

6. Refresh

Refresh tokens rotate: every refresh returns a new refresh token, and the old one stops working. A refresh token is valid for 60 days from its last use.
Reusing an old refresh token revokes the whole token family, and the user has to authorize again. Store the new refresh token before using the new access token, and never run two refreshes for the same credentials at the same time — serialize them in your client.
Refresh tokens are stored only as a hash on our side; if you lose one, authorize again.

7. Revoke

When the user disconnects your client, revoke its token:

Static keys for headless use

A CI job or a server with no browser can skip OAuth and send a static sq_agt_* key, created under Agents → Access → API keys with the theme scopes it needs:
A static key does not expire on a timer. Give it the fewest scopes the job needs and revoke it when the job is retired.