Skip to main content

OAuth reference

Auto runs an OAuth 2.1 authorization server for the MCP endpoints. For a walkthrough, see Build an MCP client.

Issuerhttps://app.auto.inc/api
Grant typesauthorization_code, refresh_token
PKCERequired. S256 only.
Client registrationDynamic (RFC 7591), no approval needed
Client authnone (public), client_secret_basic, client_secret_post
Scopesmcp:images (current), mcp:photos (legacy)
Access tokenJWT, 1 hour
Refresh tokenOpaque, 30 days, rotates on use
OpenID ConnectNot supported

Discovery​

All discovery documents allow any origin and are cached for an hour.

DocumentURL
Authorization server metadatahttps://app.auto.inc/.well-known/oauth-authorization-server/api
Protected resource, current serverhttps://app.auto.inc/.well-known/oauth-protected-resource/api/mcp/v1
Protected resource, /mcp/v2https://app.auto.inc/.well-known/oauth-protected-resource/api/mcp/v2
Protected resource, legacyhttps://app.auto.inc/.well-known/oauth-protected-resource/api/mcp/legacy

For clients that don't insert the issuer path, /.well-known/oauth-authorization-server serves the same metadata. /.well-known/oauth-protected-resource serves the /mcp/v1 document.

Scopes​

ScopeResourceThe user sees
mcp:images/mcp/v1, /mcp/v2List and search your synced camera roll, show those pictures in compatible apps, and organize them into albums in Auto.
mcp:photos/mcp/legacyList and search your photos and show them in compatible apps.

When you authorize for /mcp/v1, Auto turns a request for mcp:photos into mcp:images. A scope that belongs to another resource is dropped.

POST /api/oauth/register​

Registers a client. No authentication.

FieldTypeRequiredNotes
client_namestring, 1 to 200 charactersYesShown on the consent page.
redirect_urisstring[]YesAt least one. See the rules below.
grant_typesstring[]NoDefault ["authorization_code", "refresh_token"].
response_typesstring[]NoDefault ["code"].
scopestringNoSpace-separated. Default: all scopes.
token_endpoint_auth_methodstringNoDefault none.
software_idstring, up to 200No
software_versionstring, up to 200No

Redirect URIs: any https: URI. http: for localhost, 127.0.0.1 and [::1] only. Custom app schemes are allowed. file:, data: and javascript: are refused.

201: the registered client, with client_id and client_id_issued_at. A confidential client also gets client_secret, once. Registering the same public client again returns the same client_id.

400: invalid_client_metadata or invalid_redirect_uri.

GET /api/oauth/authorize​

Shows the sign-in and consent page in the user's browser.

ParameterRequiredNotes
response_typeYescode
client_idYes
redirect_uriYesMust exactly match a registered URI.
code_challengeYes43 to 128 characters.
code_challenge_methodYesS256
resourceNoThe MCP URL. Default https://app.auto.inc/api/mcp/v1. Always send it.
scopeNoDefault: the client's registered scopes.
stateNoReturned as is. Always send it.

On Allow, Auto redirects with code and state. On Deny, it redirects with error=access_denied. Other errors after the redirect URI is checked come back the same way, with error and error_description:

errorCause
invalid_requestA parameter is missing or wrong.
invalid_scopeThe scope is unknown, was not registered, or does not apply to the resource.
invalid_targetThe resource is not an Auto MCP URL.

A bad client_id or redirect_uri shows an error page and does not redirect.

POST /api/oauth/token​

Takes application/x-www-form-urlencoded or JSON. Public clients send client_id in the body. Confidential clients use HTTP Basic or client_id plus client_secret in the body.

Authorization code grant

FieldRequired
grant_type=authorization_codeYes
codeYes. Single use, valid 10 minutes.
redirect_uriYes. Same as in the authorize request.
code_verifierYes. 43 to 128 characters of A-Z a-z 0-9 - . _ ~
client_idYes, for public clients

Refresh grant

FieldRequired
grant_type=refresh_tokenYes
refresh_tokenYes
client_idYes, for public clients

200:

{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "mF4wT0p...y2Qk",
"scope": "mcp:images"
}

Each refresh returns a new refresh token and ends the old one.

Errors: invalid_request, invalid_client (401), invalid_grant, unauthorized_client, unsupported_grant_type.

POST /api/oauth/revoke​

Ends a grant (RFC 7009). No client authentication.

FieldRequiredNotes
tokenYesA refresh token or an access token.
token_type_hintNoaccess_token or refresh_token.

Revoking either token ends the whole grant. Access tokens stop working on the next request. The answer is 200 even if the token was not valid. A malformed body gets 400 invalid_request.

Calling the MCP server​

Send the access token in the Authorization header. Auto does not read tokens from the URL or the body.

POST /api/mcp/v1 HTTP/1.1
Host: app.auto.inc
Authorization: Bearer eyJ...
Content-Type: application/json
Accept: application/json, text/event-stream
StatusHeader
401WWW-Authenticate: Bearer scope="mcp:images", resource_metadata="https://app.auto.inc/.well-known/oauth-protected-resource/api/mcp/v1"
403WWW-Authenticate: Bearer error="insufficient_scope", scope="mcp:images", resource_metadata="..."

An API key also works as the bearer token. It skips the scope check.