Skip to main content

Authorization

This page is for developers building or debugging an MCP client. If you only want to connect an existing client, see Connect a client.

NameBeta follows the MCP authorization specification: the MCP endpoint is an OAuth 2.1 resource server, and NameBeta's account service at auth.namebeta.com is the authorization server. Users sign in with their NameBeta account; there are no API keys.

Summary​

ItemValue
Resourcehttps://namebeta.com/api/mcp
Protected Resource Metadata (PRM)https://namebeta.com/.well-known/oauth-protected-resource/api/mcp
Authorization server (issuer)https://auth.namebeta.com/oidc
Client registrationClient ID Metadata Documents (CIMD) or pre-registration. No DCR
GrantAuthorization code with PKCE (S256)
Scopesprofile email. No API scope exists
TokenJWT, sent as Authorization: Bearer <token>

The flow​

Client namebeta.com auth.namebeta.com
│ POST /api/mcp (no token) │ │
│────────────────────────────────▶│ │
│ 401 + WWW-Authenticate │ │
│◀────────────────────────────────│ │
│ GET PRM │ │
│────────────────────────────────▶│ │
│ { resource, authorization_servers, scopes_supported } │
│◀────────────────────────────────│ │
│ GET /oidc/.well-known/openid-configuration │
│────────────────────────────────────────────────────────────────▶│
│ authorization code + PKCE, resource=https://namebeta.com/api/mcp│
│────────────────────────────────────────────────────────────────▶│
│ user signs in and consents, client gets a token │
│◀────────────────────────────────────────────────────────────────│
│ POST /api/mcp, Authorization: Bearer <JWT> │
│────────────────────────────────▶│ │
│ 200 │ │
│◀────────────────────────────────│ │

1. The 401 challenge​

A request without a token gets 401 Unauthorized:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://namebeta.com/.well-known/oauth-protected-resource/api/mcp", scope="profile email"
Content-Type: application/json

{"jsonrpc":"2.0","error":{"code":-32000,"message":"unauthorized"},"id":null}

A request that carries no credentials gets a bare challenge with no error attribute, as RFC 6750 §3.1 prescribes. A request whose token fails verification gets the same challenge with error="invalid_token" appended, and invalid_token as the JSON-RPC message.

2. Protected Resource Metadata​

GET https://namebeta.com/.well-known/oauth-protected-resource/api/mcp returns the RFC 9728 document:

{
"resource": "https://namebeta.com/api/mcp",
"authorization_servers": ["https://auth.namebeta.com/oidc"],
"scopes_supported": ["profile", "email"],
"bearer_methods_supported": ["header"],
"resource_name": "NameBeta MCP"
}

The same document is also served at the root, https://namebeta.com/.well-known/oauth-protected-resource, for clients that do not read resource_metadata from the challenge. Responses carry Cache-Control: public, max-age=3600.

3. Authorization server metadata​

The issuer https://auth.namebeta.com/oidc has a path, and its metadata is published only with the well-known suffix after that path:

URLStatus
https://auth.namebeta.com/oidc/.well-known/openid-configuration200
https://auth.namebeta.com/oidc/.well-known/oauth-authorization-server200
https://auth.namebeta.com/.well-known/oauth-authorization-server/oidc404

The MCP specification has clients try the path-inserted RFC 8414 URL first and fall back to OpenID Connect discovery, so a conforming client finds the first URL. The metadata advertises client_id_metadata_document_supported: true and code_challenge_methods_supported: ["S256"], and has no registration_endpoint.

4. Client registration​

NameBeta supports Client ID Metadata Documents (CIMD): your client_id is an HTTPS URL, and the document at that URL describes your client — its name, redirect URIs and so on. The authorization server fetches it during authorization, so there is no registration step.

Dynamic Client Registration (DCR, RFC 7591) is not offered. A client that can only register itself through DCR stops with an error such as "does not support dynamic client registration".

Pre-registered client IDs​

A client that cannot use a metadata document — one that only supports DCR, for instance — can still connect if it lets the user enter an OAuth client ID. Write to contact@namebeta.com with the client's name and the redirect URIs it uses, and we reply with a client ID. Clients take it in different places:

ClientWhere the client ID goes
Claude Codeclaude mcp add … --client-id <client ID>
Codexcodex mcp add … --oauth-client-id <client ID>
CursorCLIENT_ID in the auth block of the server in mcp.json
Gemini CLIoauth.clientId of the server in settings.json
Devin Desktopdevin mcp login … --oauth-client-id <client ID>

Cursor and Gemini CLI register themselves only through Dynamic Client Registration, not Client ID Metadata Documents, so they always need a client ID from us.

5. Authorization request​

Use the authorization code grant with PKCE (code_challenge_method=S256), and send the RFC 8707 resource parameter:

resource=https://namebeta.com/api/mcp
scope=profile email
  • Scopes. Request profile email, as the challenge and PRM advertise. They are identity scopes: the consent screen shows the user which account details the client sees. There is no API scope such as mcp:tools; do not request one.
  • Refresh tokens. To get a refresh token, add offline_access to the scope and send prompt=consent. Without prompt=consent, offline_access is silently dropped and you get only an access token.
  • The resource. It is what the server checks. Without it the token is still issued for NameBeta MCP, but send it anyway, as the MCP specification requires.

The first time a user authorizes any client, NameBeta creates their account with English as the language and USD as the currency. They can change both on namebeta.com.

6. Calling the endpoint​

Send the access token as Authorization: Bearer <token> on every request. Endpoint and transport shows a complete request.

How the server checks a token​

The server verifies the JWT signature against the issuer's JWKS (https://auth.namebeta.com/oidc/jwks) and then checks these claims:

ClaimRequirement
isshttps://auth.namebeta.com/oidc
audhttps://namebeta.com/api/mcp
expPresent and in the future
subPresent; identifies the NameBeta user

Scopes are not checked. The audience is the authorization boundary: a token minted for https://namebeta.com/api/mcp is valid for every tool. Any failure returns 401 with error="invalid_token"; refresh the token or authorize again. Troubleshooting lists the usual causes.