OAuth API reference
The OAuth 2.1 endpoints the control plane serves for MCP connectors: discovery, dynamic registration, authorization, PKCE token exchange, refresh and revocation.
Last updated:
/.well-known/oauth-authorization-server
RFC 8414 metadata. Also served with the `/v1/mcp` suffix.
/.well-known/oauth-protected-resource/v1/mcp
RFC 9728 metadata for the MCP endpoint: `resource`, `authorization_servers`, `bearer_methods_supported`.
/oauth/register
RFC 7591 dynamic client registration.
Registration body
Twenty registrations per address per hour; a twenty-first is `rate_limited`.
| Name | Type | Description |
|---|---|---|
redirect_uris
required
|
string[] | Each `https://…`, or `http://127.0.0.1…` / `http://localhost…` for a local client. Exact match at authorization time. |
client_name
|
string | Shown on the consent screen. |
token_endpoint_auth_method
|
string | Only `none` is accepted: public clients with PKCE. A confidential client is refused. |
grant_types
|
string[] | Subset of `authorization_code`, `refresh_token`. |
/oauth/authorize
Starts the flow. `response_type=code`, `client_id`, `redirect_uri`, `code_challenge` (43–128 chars) with `code_challenge_method=S256`, optional `state`, `scope` and `resource` (must be this server’s `/v1/mcp` if given). An unknown client or a redirect URI that does not match answers 400 without redirecting; other errors redirect with `error`. Success redirects to the dashboard consent page.
/oauth/token
Form-encoded or JSON. `grant_type=authorization_code` with `code`, `code_verifier`, `redirect_uri`, `client_id`; or `grant_type=refresh_token` with `refresh_token`. Errors follow RFC 6749: `invalid_grant`, `invalid_client`, `invalid_request`.
Token response
| Name | Type | Description |
|---|---|---|
access_token
|
string | A Browserberg API key of kind `oauth`. One hour. |
token_type
|
string | `Bearer`. |
expires_in
|
integer | 3600. |
refresh_token
|
string | Ninety days, single-use: each refresh returns a new one and retires the old. |
scope
|
string | What was granted; `browserberg` today. |
/oauth/revoke
`token` and optional `token_type_hint`. Revokes an access token, or a refresh token and every access token it minted. Always 200.
Discovery
BASE="https://browserberg.com"
# The discovery documents an MCP client reads on its own. No credential needed.
curl -s "$BASE/.well-known/oauth-authorization-server" \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print("issuer:", d["issuer"]); print("authorize:", d["authorization_endpoint"].replace(d["issuer"], "")); print("token:", d["token_endpoint"].replace(d["issuer"], "")); print("pkce:", d["code_challenge_methods_supported"])'
curl -s "$BASE/.well-known/oauth-protected-resource/v1/mcp" \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print("resource ends with:", d["resource"].rsplit("/", 2)[-2:])'
issuer: https://browserberg.com
authorize: /oauth/authorize
token: /oauth/token
pkce: ['S256']
resource ends with: ['v1', 'mcp']