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
| Item | Value |
|---|---|
| Resource | https://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 registration | Client ID Metadata Documents (CIMD) or pre-registration. No DCR |
| Grant | Authorization code with PKCE (S256) |
| Scopes | profile email. No API scope exists |
| Token | JWT, 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:
| URL | Status |
|---|---|
https://auth.namebeta.com/oidc/.well-known/openid-configuration | 200 |
https://auth.namebeta.com/oidc/.well-known/oauth-authorization-server | 200 |
https://auth.namebeta.com/.well-known/oauth-authorization-server/oidc | 404 |
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:
| Client | Where the client ID goes |
|---|---|
| Claude Code | claude mcp add … --client-id <client ID> |
| Codex | codex mcp add … --oauth-client-id <client ID> |
| Cursor | CLIENT_ID in the auth block of the server in mcp.json |
| Gemini CLI | oauth.clientId of the server in settings.json |
| Devin Desktop | devin 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 asmcp:tools; do not request one. - Refresh tokens. To get a refresh token, add
offline_accessto the scope and sendprompt=consent. Withoutprompt=consent,offline_accessis 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:
| Claim | Requirement |
|---|---|
iss | https://auth.namebeta.com/oidc |
aud | https://namebeta.com/api/mcp |
exp | Present and in the future |
sub | Present; 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.