Skip to content

Commit 7c2d4c0

Browse files
domdomeggclaude
andcommitted
Simplify registry authorization docs to defer to MCP spec
Significantly simplified the registry authorization documentation to avoid duplication and potential drift from the MCP Authorization Specification. Feedback was to keep things as simple as possible to avoid confusion and ensure discussions about OAuth/authorization mechanics happen on the MCP spec itself, not the registry repo. Changes: - Reduced from 159 lines to ~25 lines - Removed all detailed MUST/SHOULD requirements, examples, and flows - Document now simply points to MCP spec and adds only registry-specific details - Kept only scope recommendations (mcp-registry:read, mcp-registry:write) - Added note about user-level authorization vs operation-level scopes - Clarified official registry uses different auth for legacy reasons 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 0112a94 commit 7c2d4c0

File tree

1 file changed

+15
-148
lines changed

1 file changed

+15
-148
lines changed
Lines changed: 15 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,26 @@
1-
# Registry Authorization Specification
1+
# Registry Authorization
22

3-
A standardized authentication and authorization mechanism for MCP registries, based on the [MCP Authorization Specification](https://modelcontextprotocol.io/specification/draft/basic/authorization).
3+
MCP registries wishing to implement authentication SHOULD follow the [MCP Authorization Specification](https://modelcontextprotocol.io/specification/draft/basic/authorization).
44

5-
**Scope:** This specification is intended for downstream sub-registries (e.g., private company registries). The official modelcontextprotocol.io registry remains public for reading, and uses a different auth system for publishing for legacy reasons (this may change in future).
5+
## How it works
66

7-
## Architecture
7+
The registry acts as an OAuth 2.1 Resource Server, identical to how MCP servers work. This means:
88

9-
Sub-registries implementing this specification act as OAuth 2.1 Resource Servers, identical to how MCP servers work:
9+
- **MCP clients** can reuse their existing MCP authorization implementation without any changes
10+
- **Registries** validate access tokens the same way MCP servers do
11+
- **Users** get a consistent login experience across MCP servers and registries
1012

11-
- **Registry** = OAuth 2.1 Resource Server (validates access tokens)
12-
- **MCP Client** = OAuth 2.1 Client (requests registry resources with tokens)
13-
- **Authorization Server** = Issues tokens and manages authentication
13+
## Registry-Specific Scopes
1414

15-
This allows clients to reuse their existing MCP authorization implementation without modification.
15+
Registries MAY use these scopes:
1616

17-
## Client Requirements
17+
- `mcp-registry:read` - List and read server metadata
18+
- `mcp-registry:write` - Publish, update, and delete servers
1819

19-
Clients MUST follow the [MCP Authorization Specification](https://modelcontextprotocol.io/specification/draft/basic/authorization) when authenticating to registries. The flow is identical to MCP server authentication.
20+
These are recommendations - registries may use any set of scopes they deem sensible.
2021

21-
### Discovery
22+
Note that scopes only control what *types* of operations a user can perform. Registries should still apply user-level authorization to control which specific resources a user can access. For example, a user with `mcp-registry:write` might only be able to publish servers to namespaces they own, and may not have permissions to edit servers if the registry treats servers as immutable.
2223

23-
Registries requiring auth SHOULD return discovery information via a 401 Unauthorized response with the WWW-Authenticate header:
24+
## Official Registry Authentication
2425

25-
```http
26-
GET /v0/servers HTTP/1.1
27-
Host: registry.example.com
28-
29-
HTTP/1.1 401 Unauthorized
30-
WWW-Authenticate: Bearer realm="MCP Registry", scope="registry:read", resource_metadata="https://registry.example.com/.well-known/oauth-protected-resource"
31-
```
32-
33-
(but for compatibility with the MCP spec, registries MAY serve metadata at a well-known URI)
34-
35-
Clients supporting auth MUST then retrieve the Protected Resource Metadata from the provided URL:
36-
37-
```json
38-
{
39-
"resource": "https://registry.example.com",
40-
"authorization_servers": ["https://auth.example.com"],
41-
"scopes_supported": ["registry:read", "registry:write"],
42-
"bearer_methods_supported": ["header"]
43-
}
44-
```
45-
46-
### Authorization Server Discovery
47-
48-
Clients MUST discover the authorization server using standard OAuth 2.0 / OpenID Connect well-known endpoints, following the same priority order specified in the MCP Authorization Specification.
49-
50-
### Token Requests
51-
52-
Clients MUST include the `resource` parameter (RFC 8707) identifying the registry in all token requests:
53-
54-
```http
55-
POST /token HTTP/1.1
56-
Host: auth.example.com
57-
Content-Type: application/x-www-form-urlencoded
58-
59-
grant_type=authorization_code
60-
&code=AUTHORIZATION_CODE
61-
&redirect_uri=http://localhost:3000/callback
62-
&client_id=CLIENT_ID
63-
&code_verifier=CODE_VERIFIER
64-
&resource=https%3A%2F%2Fregistry.example.com
65-
```
66-
67-
Clients MUST use PKCE with the S256 challenge method.
68-
69-
### Authenticated Requests
70-
71-
Clients MUST include the access token in the Authorization header for all authenticated requests:
72-
73-
```http
74-
GET /v0/servers HTTP/1.1
75-
Host: registry.example.com
76-
Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...
77-
```
78-
79-
Clients MUST NOT include tokens in query strings.
80-
81-
### Scope Selection
82-
83-
Clients MUST follow this priority hierarchy for scope selection:
84-
85-
1. Use scopes from the `WWW-Authenticate` header's `scope` parameter if provided
86-
2. Use all scopes from `scopes_supported` in Protected Resource Metadata if available
87-
3. Omit the scope parameter if neither option exists
88-
89-
### Step-Up Authorization
90-
91-
When clients receive a 403 response with `error="insufficient_scope"`, clients SHOULD:
92-
93-
1. Parse the required scopes from the `scope` parameter in the WWW-Authenticate header
94-
2. Initiate a new authorization flow with the expanded scope set
95-
3. Retry the original request with the new token
96-
97-
Clients MUST implement retry limits to prevent infinite loops.
98-
99-
## Security Requirements
100-
101-
Registries and clients implementing this specification MUST follow all security requirements defined in the [MCP Authorization Specification](https://modelcontextprotocol.io/specification/draft/basic/authorization).
102-
103-
### Scopes
104-
105-
Registries SHOULD use scopes aligned with their API operations:
106-
107-
- `registry:read` - List and read server metadata
108-
- `registry:write` - Publish and update servers
109-
- `registry:admin` - Administrative operations (optional)
110-
111-
Registries MAY define additional scopes for fine-grained access control (e.g., `registry:read:acme-internal` for organization-specific private servers).
112-
113-
### Permission-Based Server Visibility
114-
115-
Registries MAY implement permission-based filtering of server lists. When a client provides an access token, registries SHOULD filter the response based on the token's claims, excluding servers the user does not have permission to access.
116-
117-
Example approach:
118-
119-
```json
120-
{
121-
"name": "io.github.acme/internal-tools",
122-
"title": "ACME Internal Tools",
123-
"visibility": "private",
124-
"allowed_scopes": ["registry:read:acme-internal"]
125-
}
126-
```
127-
128-
When listing servers, the registry filters results based on the token's scope claims. Users without appropriate scopes do not see private servers in responses.
129-
130-
### Step-Up Authorization Responses
131-
132-
When a user attempts an operation requiring additional permissions, registries SHOULD return a 403 response with:
133-
134-
```http
135-
HTTP/1.1 403 Forbidden
136-
WWW-Authenticate: Bearer error="insufficient_scope", scope="registry:read registry:write", resource_metadata="https://registry.example.com/.well-known/oauth-protected-resource"
137-
```
138-
139-
## Benefits
140-
141-
**For clients:** Zero new code required - reuse existing MCP authorization implementation with identical flow and libraries.
142-
143-
**For sub-registries:** Industry-standard OAuth 2.1 with flexible permissions and proven security model.
144-
145-
**For users:** Consistent login experience across MCP servers and registries.
146-
147-
## Comparison with Official Registry Authentication
148-
149-
The official modelcontextprotocol.io registry uses a custom JWT-based authentication system for publishing servers. Reading servers remains public and does not require authentication.
150-
151-
We may in future look at moving the official registry to this standardized OAuth 2.1-based system for consistency.
152-
153-
## References
154-
155-
- [MCP Authorization Specification](https://modelcontextprotocol.io/specification/draft/basic/authorization)
156-
- [OAuth 2.1 Authorization Framework](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1)
157-
- [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707)
158-
- [RFC 7591: OAuth 2.0 Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591)
159-
- [Issue #751](https://github.com/modelcontextprotocol/registry/issues/751)
26+
The official modelcontextprotocol.io registry remains public for reading. For publishing servers, it uses a custom JWT-based authentication system for legacy reasons - see [its API spec](official-registry-api.md#authentication). This may change in future to align with the MCP Authorization Specification.

0 commit comments

Comments
 (0)