Skip to content

50% off your first year. Join before 2027. Claim →

Make resource match the URL agents connect to

This check verifies that the resource field of your protected resource metadata is the URL agents connect to.

Check id resource_matches (resource matches). Results:

pass fail skipped

The resource value is your server’s resource identifier. An agent compares it with the URL it fetched the metadata for, and a document whose resource names another URL is not used: RFC 9728 requires the two to be identical, so a mismatch stops the sign-in before the user sees a login screen. The same value is then sent to the authorization server as the resource parameter, so tokens are issued for it.

  • Claude requires resource to equal your MCP server URL exactly as the user enters it, including any path (Claude: Authentication for connectors).
  • ChatGPT sends this exact value as the resource parameter during sign-in (OpenAI: Authentication), so a wrong value gives tokens for the wrong URL.
  • The MCP authorization specification uses the canonical URI of the MCP server as the resource, and prefers the form without a trailing slash (MCP: Canonical server URI).

Other agents follow the MCP specification; MCP Tower has not verified them.

  1. MCP Tower reads resource from the document the protected resource metadata check found. Without that document the check is skipped with “Needs the protected resource metadata.”
  2. It compares resource with your MCP endpoint URL and, once your server has a public hostname on MCP Tower, with the public URL as well. The comparison is an exact string comparison that ignores only a trailing /. Scheme, host, port, path and letter case must all be the same, so https://mcp.example.com:443/mcp, https://MCP.example.com/mcp and https://mcp.example.com do not match https://mcp.example.com/mcp.
  3. A match with either URL is pass. Anything else is fail. The message names the public URL when there is one, and the endpoint otherwise, because that is the URL agents use.

Query strings are left out of the message.

StatusMessageMeaningFix
passThe metadata’s resource matches the endpoint.Agents accept the document and ask for tokens for this URL.
failresource is “<resource>”, but agents connect to “<public URL or endpoint>”. Agents stop the flow when these differ.The value names another host, path or port, or is built differently.Set resource to the endpoint URL
skippedNeeds the protected resource metadata.The document was not found.Protected resource metadata

The next step for the failure is: “Set resource in the protected resource metadata to the exact URL agents connect to.”

  1. Take the URL users enter in their agent, such as https://mcp.example.com/mcp. With MCP Tower in front, that is your public hostname plus your MCP path.
  2. Set resource to that exact string. Keep the path, use lowercase for the scheme and host, leave out default ports, and drop any trailing slash.
  3. If your server builds the value from the incoming request, build it from a configured URL instead, so a proxy or a different Host header cannot change it.

A matching document:

/.well-known/oauth-protected-resource/mcp
{
"resource": "https://mcp.example.com/mcp",
"authorization_servers": ["https://auth.example.com"]
}
nginx.conf
# A fixed value, not one built from $host.
location = /.well-known/oauth-protected-resource/mcp {
default_type application/json;
return 200 '{"resource":"https://mcp.example.com/mcp","authorization_servers":["https://auth.example.com"]}';
}

Agents connect to https://mcp.example.com/mcp, and MCP Tower forwards to your origin at origin.example.com. When your origin’s document names the origin, MCP Tower rewrites the resource field on the way out: if the value is an absolute URL whose scheme, host and port are the origin’s, they become https://mcp.example.com and the path is kept. It rewrites only application/json responses of up to 64 KB, and leaves a value that names any other host as it is. A value with the wrong path is not fixed, so the path must be right at the origin.

That is why this check accepts both your endpoint URL and your public URL. A resource that names the origin also gets a warning from public audience, because tokens will be issued for the public hostname.

Fetch the document and print its resource:

Terminal window
curl -s https://mcp.example.com/.well-known/oauth-protected-resource/mcp \
-H 'Accept: application/json' | jq -r .resource

The problem is fixed when it prints the URL agents connect to, exactly:

https://mcp.example.com/mcp

Then select Scan again on the server’s page.