Skip to main content

OAuth 2.0 reference

If you're building an MCP client that needs to support the full Scorelytics authorization flow (instead of using a static API key), this page is the reference.

The implementation is RFC-compliant — RFC 6749 (OAuth 2.0), RFC 7591 (Dynamic Client Registration), RFC 9728 (Protected Resource Metadata) — so any standard library should work out of the box.

Discovery

Protected resource metadata

GET https://api.scorelytics.pro/.well-known/oauth-protected-resource
GET https://api.scorelytics.pro/.well-known/oauth-protected-resource/v1/mcp

Returns the authorization_servers list pointing at the Scorelytics authorization server (same host).

Authorization server metadata

GET https://api.scorelytics.pro/.well-known/oauth-authorization-server

Returns issuer, authorization endpoint, token endpoint, registration endpoint and supported grant types.

Dynamic client registration

POST https://api.scorelytics.pro/oauth/register
Content-Type: application/json

{
"redirect_uris": ["https://your-app.example.com/oauth/callback"],
"client_name": "Your App",
"token_endpoint_auth_method": "none"
}

Response: { client_id, client_secret? }. Public clients (token_endpoint_auth_method: "none") get only client_id and must use PKCE.

Authorization code flow

GET /oauth/authorize
?response_type=code
&client_id={client_id}
&redirect_uri={redirect_uri}
&state={random}
&code_challenge={pkce_challenge}
&code_challenge_method=S256
&scope=mcp:invoke

The user lands on the Scorelytics consent page, signs in, and is redirected back to your redirect_uri with ?code=....

Token exchange

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&code_verifier={pkce_verifier}

Response:

{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "...",
"scope": "mcp:invoke"
}

Refresh

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token={refresh_token}&client_id={client_id}

Refresh tokens rotate — store the new refresh_token returned in each response.

Calling the MCP server

Use the access_token as a Bearer credential:

Authorization: Bearer {access_token}

When the access token expires, you'll get 401 invalid_token. Refresh and retry.