Skip to content

RFC 8414 Compliance #822

@dr3s

Description

@dr3s

Describe the bug

NOTE: if a server implements PRM then this issue should be moot. Entering this issue because the current sdk should still support earlier specs.

There seems to be confusion over the interpretation of 8414 especially in regards to situations where the mcp server hosts the auth server metadata, regardless if it hosts the authorization endpoints itself.

There are 3 main cases that I would like to consider but they all come down fundamentally to the interpretation of this clause:

https://datatracker.ietf.org/doc/html/rfc8414#section-3

Authorization servers supporting metadata MUST make a JSON document
containing metadata as specified in Section 2 available at a path
formed by inserting a well-known URI string into the authorization
server's issuer identifier between the host component and the path
component, if any.

The implementation seems to build this path by assuming the mcp server transport handler url is the issuer. I believe this is incorrect.

const issuer = new URL(serverUrl);
  const protocolVersion = opts?.protocolVersion ?? LATEST_PROTOCOL_VERSION;

  let url: URL;
  if (opts?.metadataUrl) {
    url = new URL(opts.metadataUrl);
  } else {
    // Try path-aware discovery first
    const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);
    url = new URL(wellKnownPath, opts?.metadataServerUrl ?? issuer);
    url.search = issuer.search;
  }

The server URL is the handler of the MCP transport. It's incorrect to treat it as the issue IMO. The issue is that the metadata may not be correctly found even when trying to fallback to the root domain. This seems to have shown up in recent builds of inspector.

The 3 cases that seem common:

  1. MCP server hosts full auth
    1. metadata at /.well-known/oauth-authorization-server
    2. metadata points to local issuer and auth endpoint locally
    3. handler at /mcp
  2. MCP hosts partial auth
    1. metadata at /.well-known/oauth-authorization-server
    2. metadata points to 3rd party issuer and auth endpoint
    3. handler at /mcp
  3. MCP hosts partial auth at non-root context
    1. metadata at /.well-known/oauth-authorization-server
    2. metadata points to 3rd party issuer and auth endpoint
    3. handler at /{appRoot}/mcp

There are plenty of other configurations but the interpretation of these is enough to highlight the issue with how the path portion of 8414 is applied. In all cases without PRM, it's not clear what the issuer is because it's part of the metadata that is attempting to be found. Making any other assumption about the issuer path than root ( /.well-known/oauth-authorization-server) seems incorrect because we can't know where the issuer resides until the metadata is fetched or a PRM is found.

The current code assumes the server URL is the issuer when that cannot be known a priori. I would suggest to use the default well known root url when PRM is not present to keep the code paths simple. If discovery needs to be more complex, I think the handler path needs to be dropped to check whether there's an issuer at the app context.

According to the spec the purpose of the patch component is simply:

Using path components enables supporting multiple issuers per host.

This is the case for MS Entra but it doesn't mean that the MCP server would host the metadata at a path like /.well-known/oauth-authorization-server/mcp. The issuer here contains the Entra tenant id. It seems even in this case Entra doesn't follow the 8414 spec and hosts the metadata at urls like https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configuration. Another issue indicated problems with Keycloak in this area as well.

relates to #545
#744

In short, I think the current approach misinterprets the intent of the path component in 8414 and it seems real world auth servers don't even use it in the way it was intended.

To Reproduce
Steps to reproduce the behavior:

  1. Host 3-26 MCP server (no PRM) at / and listen for s-http transport on /mcp
  2. serve metadata at /.well-known/oauth-authorization-server
  3. try to connect in inspector

Expected behavior
Inspector should find the metadata and complete the auth flow.

Logs
If applicable, add logs to help explain your problem.

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions