Summary
LibreChat's MCP OAuth client already implements RFC 9728 (Protected Resource Metadata discovery, see packages/api/src/mcp/oauth/detectOAuth.ts) and forwards resource per RFC 8707 on /authorize (see handler.ts ~line 726). However, MCP servers whose authorization server is Auth0 (and, by extension, AWS Cognito and similar providers) cannot complete the OAuth flow today, because those providers don't honor RFC 8707 resource — they only mint API-scoped access tokens when the request advertises their pre-RFC-8707 audience parameter.
Reproduction (generic, vendor-agnostic)
Any MCP server whose WWW-Authenticate: Bearer response includes a resource_metadata URL, whose Protected Resource Metadata document advertises an Auth0-tenant authorization_servers entry, and whose backing Auth0 tenant requires audience to issue API tokens. Concretely:
POST <mcp-url> → 401 WWW-Authenticate: Bearer resource_metadata="https://<mcp-host>/.well-known/oauth-protected-resource"
- Protected Resource Metadata returns:
{
"resource": "https://<mcp-host>/mcp",
"authorization_servers": ["https://<tenant>.auth0.com/"],
"scopes_supported": ["..."]
}
- LibreChat's DCR succeeds against Auth0's
/oidc/register.
/authorize is called with client_id, redirect_uri, scope, code_challenge, state, resource=<canonical resource> — i.e. RFC 8707 compliant.
- Auth0 ignores
resource and issues a token without the API audience.
- The next MCP call fails:
{"detail":"OAuth bearer token required for ..."}.
Observed log trace
[MCP][<server>] OAuth Required: true
[MCP][<server>] Establishing new connection
[MCP][<server>] Access token missing and no refresh token available — re-authentication required
[MCPOAuth] Failed to initiate OAuth flow
[MCP][<server>] OAuth handling failed: OAuth initiation failed
[MCP][<server>] Connection failed: Streamable HTTP error: Error POSTing to endpoint: {"detail":"OAuth bearer token required for ..."}
(Detection logs show protected-resource-metadata discovery succeeds; the failure is downstream, in the authorize/token exchange.)
Why not resource alone
RFC 8707 resource is the correct standards-conformant approach. Auth0's documented behavior, however, is to ignore resource and require audience for API-token issuance (Auth0 docs). AWS Cognito has analogous behavior for resource servers vs. plain OIDC. Providers that follow RFC 8707 strictly (Keycloak, Authentik, recent Microsoft Entra setups with API audiences declared) are unaffected.
Standards / references
- MCP Authorization Spec 2025-06-18
- RFC 9728 (OAuth 2.0 Protected Resource Metadata)
- RFC 8707 (Resource Indicators)
- Auth0 documentation on
audience
- AWS Cognito custom-scopes / resource-server docs
Prior art in this repository
Proposed fix
Add an optional audience field to mcpServers.<name>.oauth and forward it on both /authorize and /token (including the refresh_token grant). resource (RFC 8707) is left untouched; the two are independent. Operators choose which their authorization server expects.
Configuration example after the fix:
mcpServers:
my-auth0-backed-server:
type: streamable-http
url: https://api.example.com/mcp
oauth:
scope: "knowledge:read offline_access"
audience: "https://api.example.com/mcp" # new
(Pre-configured authorization_url / token_url / client_id are not required when the server advertises RFC 9728 metadata — DCR handles it.)
PR with code + schema tests follows.
Issue drafted with Claude's help. Manually validated against a live Auth0-backed MCP server where the patched build now completes the OAuth flow end-to-end; the unmodified build hangs on OAuth initiation failed.
Summary
LibreChat's MCP OAuth client already implements RFC 9728 (Protected Resource Metadata discovery, see
packages/api/src/mcp/oauth/detectOAuth.ts) and forwardsresourceper RFC 8707 on/authorize(seehandler.ts~line 726). However, MCP servers whose authorization server is Auth0 (and, by extension, AWS Cognito and similar providers) cannot complete the OAuth flow today, because those providers don't honor RFC 8707resource— they only mint API-scoped access tokens when the request advertises their pre-RFC-8707audienceparameter.Reproduction (generic, vendor-agnostic)
Any MCP server whose
WWW-Authenticate: Bearerresponse includes aresource_metadataURL, whose Protected Resource Metadata document advertises an Auth0-tenantauthorization_serversentry, and whose backing Auth0 tenant requiresaudienceto issue API tokens. Concretely:POST <mcp-url>→401 WWW-Authenticate: Bearer resource_metadata="https://<mcp-host>/.well-known/oauth-protected-resource"{ "resource": "https://<mcp-host>/mcp", "authorization_servers": ["https://<tenant>.auth0.com/"], "scopes_supported": ["..."] }/oidc/register./authorizeis called withclient_id,redirect_uri,scope,code_challenge,state,resource=<canonical resource>— i.e. RFC 8707 compliant.resourceand issues a token without the API audience.{"detail":"OAuth bearer token required for ..."}.Observed log trace
(Detection logs show
protected-resource-metadatadiscovery succeeds; the failure is downstream, in the authorize/token exchange.)Why not
resourcealoneRFC 8707
resourceis the correct standards-conformant approach. Auth0's documented behavior, however, is to ignoreresourceand requireaudiencefor API-token issuance (Auth0 docs). AWS Cognito has analogous behavior for resource servers vs. plain OIDC. Providers that follow RFC 8707 strictly (Keycloak, Authentik, recent Microsoft Entra setups with API audiences declared) are unaffected.Standards / references
audiencePrior art in this repository
audiencesupport for the OpenID user-login refresh path (OPENID_REFRESH_AUDIENCE). Different code path, same conceptual gap.audience. Again different code path, same concept.promptparameter for Microsoft Graph). Sibling issue, different parameter.audiencesupport — OBO is a different grant type and Entra-specific.Proposed fix
Add an optional
audiencefield tomcpServers.<name>.oauthand forward it on both/authorizeand/token(including therefresh_tokengrant).resource(RFC 8707) is left untouched; the two are independent. Operators choose which their authorization server expects.Configuration example after the fix:
(Pre-configured
authorization_url/token_url/client_idare not required when the server advertises RFC 9728 metadata — DCR handles it.)PR with code + schema tests follows.
Issue drafted with Claude's help. Manually validated against a live Auth0-backed MCP server where the patched build now completes the OAuth flow end-to-end; the unmodified build hangs on
OAuth initiation failed.