MCP Protected Resource Metadata (RFC 9728): What a 401 Points To | MCP Hunter

protected resource metadata

Also written PRM, RFC 9728, oauth-protected-resource, /.well-known/oauth-protected-resource

Protected resource metadata is a public JSON document, defined in RFC 9728, in which a guarded MCP server says which authorization servers issue its tokens. The server points to it from the WWW-Authenticate header of its 401, usually at /.well-known/oauth-protected-resource, and the MCP spec requires every guarded server to publish one.

What is protected resource metadata in MCP?

When a client calls a guarded MCP server without a token, the server answers 401 Unauthorized. The client then needs to know where to get a token, and the server is not the one that issues it: an authorization server is. Protected resource metadata is the document that connects the two. It is published by the MCP server, about itself, and it is public by design so that a client with no token can read it [2].

The MCP spec makes it mandatory: servers "MUST implement OAuth 2.0 Protected Resource Metadata", and the document "MUST include the authorization_servers field containing at least one authorization server" [1].

How does a client find it?

Two ways, and clients must support both [1]:

  1. From the 401. The server names the document in its WWW-Authenticate header:
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"
  1. From the well-known address. If the header carries no pointer, the client tries /.well-known/oauth-protected-resource on the server's host, with the endpoint's path appended first and without it second.

What is in the document?

Shape only, with example hosts:

{
  "resource": "https://mcp.example.com/mcp",
  "authorization_servers": ["https://auth.example.com"],
  "scopes_supported": ["read", "write"],
  "bearer_methods_supported": ["header"],
  "resource_name": "Example MCP Server",
  "resource_documentation": "https://docs.example.com/mcp"
}

RFC 9728 requires only resource, the identifier of the server itself [2]. The MCP spec adds authorization_servers as required [1]. Everything else is optional: the scopes a token can carry, how the token may be sent, a human-readable name, and links to documentation, a policy and terms.

From there the client fetches the authorization server's own metadata, registers if it needs to (through a client metadata document or Dynamic Client Registration), and runs the OAuth flow.

What do real MCP servers publish?

In our registry census on 20 August 2026, 263 remote MCP servers asked for credentials, and 186 of their 401s named a metadata URL (185 distinct). On 9 October 2026 we fetched each one:

What the document contained Servers
Returned a readable document 168 of 185
resource 167
authorization_servers 167
bearer_methods_supported 147
scopes_supported 128
resource_documentation 35
resource_name 32

Three patterns stand out. 184 of the 185 URLs used the standard /.well-known/oauth-protected-resource path. One document that did load named no authorization server, which leaves a client with nowhere to go. And the optional fields a person would read were mostly empty: only about 1 in 5 documents gave the server a name (32) or linked its documentation (35).

118 of the 167 that named an authorization server ran it on the same host as the MCP server itself, rather than at a separate identity provider.

These are aggregates of documents each server published about itself, and no server is named here.

How do I check my own?

Call your endpoint without a token and read the header, then fetch what it points to:

curl -sS -i https://your-server.example.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}' \
  | grep -i '^www-authenticate'

curl -sS https://your-server.example.com/.well-known/oauth-protected-resource

If the first command prints no resource_metadata, clients fall back to the well-known address, so make sure the second one answers. Fill in resource_name and resource_documentation while you are there: they cost nothing and are what a person sees when a client asks them to sign in.

On this board, a guarded listing shows what its document says: the name it gives itself, who issues its tokens and the permissions it declares, read on a stated date. Our connection test reports a 401 as a guarded server rather than a failure.

Sources

  1. Authorization, MCP specification 2025-11-25
  2. RFC 9728: OAuth 2.0 Protected Resource Metadata

Go deeper

Related terms