diff --git a/.changeset/fix-resource-metadata-extraction.md b/.changeset/fix-resource-metadata-extraction.md new file mode 100644 index 000000000..6b47d0611 --- /dev/null +++ b/.changeset/fix-resource-metadata-extraction.md @@ -0,0 +1,11 @@ +--- +'@modelcontextprotocol/client': patch +--- + +Fix resource metadata URL extraction during initial OAuth connection + +Previously, when connecting to MCP servers using OAuth with separate authorization servers (like AWS Cognito, Auth0, Okta), the SDK would fail during token exchange with an "Invalid api path" error. This was because the `resourceMetadataUrl` from the WWW-Authenticate header was not being extracted during the initial connection attempt. + +The fix ensures that both `StreamableHTTPClientTransport` and `SSEClientTransport` extract the resource metadata URL and scope from the WWW-Authenticate header when receiving a 401 response during the initial connection. This allows `finishAuth()` to correctly discover the authorization server's token endpoint. + +This resolves issues with OAuth flows that use RFC 9728 Protected Resource Metadata and separate authorization servers. diff --git a/packages/client/src/client/streamableHttp.ts b/packages/client/src/client/streamableHttp.ts index 22cd417bd..f335dd83d 100644 --- a/packages/client/src/client/streamableHttp.ts +++ b/packages/client/src/client/streamableHttp.ts @@ -231,6 +231,11 @@ export class StreamableHTTPClientTransport implements Transport { await response.text?.().catch(() => {}); if (response.status === 401 && this._authProvider) { + // Extract resource metadata URL from WWW-Authenticate header before starting auth flow + const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response); + this._resourceMetadataUrl = resourceMetadataUrl; + this._scope = scope; + // Need to authenticate return await this._authThenStart(); }