Skip to main content

OAuth authentication

Use your MCP SDK's OAuth support where available. HolyShift supports public clients with PKCE S256 and token_endpoint_auth_method: none.

Discover the endpoints​

An unauthenticated MCP request returns HTTP 401 with a WWW-Authenticate header pointing to:

https://v3.holyshift.ai/.well-known/oauth-protected-resource/mcp

The resource metadata names the authorization server. Fetch its metadata at:

https://v3.holyshift.ai/.well-known/oauth-authorization-server

Use the returned endpoint URLs rather than deriving them in your integration.

OperationCurrent endpoint
Register a clientPOST /api/oauth/register
AuthorizeGET /api/oauth/authorize
Exchange or refresh tokensPOST /api/oauth/token
Revoke a tokenPOST /api/oauth/revoke

Identify your client​

HolyShift supports two options:

  • Client ID metadata document: use an HTTPS URL as your client_id. Serve a public JSON document describing your client. The URL must be publicly reachable and must not redirect.
  • Dynamic client registration: register your client with JSON. This works for clients that expect a registration endpoint.

Example dynamic registration:

curl --request POST 'https://v3.holyshift.ai/api/oauth/register' \
--header 'Content-Type: application/json' \
--data '{
"client_name": "Example integration",
"redirect_uris": ["http://127.0.0.1:8765/callback"],
"token_endpoint_auth_method": "none"
}'

Keep the returned client_id. Redirect URIs must use HTTPS, HTTP loopback or a supported native app scheme. Loopback redirects may use a different port from the registered one.

Authorize the account​

Generate a fresh state and PKCE verifier for each attempt. Send the person to the discovered authorization endpoint with:

ParameterValue
response_typecode
client_idYour client ID
redirect_uriA registered callback URI
scopemcp
stateA random value you validate on return
code_challengeBase64url-encoded SHA-256 of the verifier, without padding
code_challenge_methodS256
resourcehttps://v3.holyshift.ai/mcp

The person signs in and approves access in HolyShift. Validate state and the returned authorization-server iss before accepting the callback. An authorization error returns error instead of a code.

Exchange the code at the token endpoint using form encoding:

grant_type=authorization_code
client_id=<your client ID>
code=<authorization code>
redirect_uri=<the same callback URI>
code_verifier=<the original verifier>

The code is single-use. A valid exchange returns access_token, token_type, expires_in, refresh_token and scope.

Store and refresh tokens​

Access tokens last one hour. Refresh tokens last 30 days and rotate on every successful refresh.

grant_type=refresh_token
client_id=<your client ID>
refresh_token=<current refresh token>

Atomically replace the stored access and refresh tokens with the new pair. Serialize refresh attempts for an account: reusing an old refresh token can revoke the entire grant. A short retry grace window refuses the reused token without revoking the grant, but does not return the lost token pair.

Tokens are opaque; do not parse them as JWTs. Store them securely and keep them out of URLs, analytics and logs.

Revocation​

Send a form-encoded token to the revocation endpoint. Revoking the refresh token disconnects the grant. The person can also disconnect the app under Settings → Connected apps, invalidating its tokens immediately.

There is currently one scope, mcp, with no read-only variant. It grants the person's existing reach, not administrator access.