[GH-ISSUE #24730] issue: OAuth scopes are missing within authorize_url when using MCP with OAuth2.1 (Static) #91127

Open
opened 2026-05-15 16:24:27 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @abehsu-mu on GitHub (May 14, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/24730

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I have also searched in the CLOSED issues AND CLOSED discussions and found no related items (your issue might already be addressed on the development branch!).
  • I am using the latest version of Open WebUI.

Installation Method

Docker

Open WebUI Version

v0.9.5 (latest)

Ollama Version (if applicable)

no

Operating System

MacOS Sequoia & Linux

Browser (if applicable)

Chrome Version 148.0.7778.97

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

Openwebui should be able to retrieve scopes from .well-known/oauth-protected-resource and include those scopes when generating the authorize endpoint.

Actual Behavior

When openwebui try to generate authorization url, it missing scopes because of this line [1]

Generate URL:

https://login.microsoftonline.com/organizations/v2.0/authorize?response_type=code&client_id=<client_id>&redirect_uri=<server_url>&resource=https%3A%2F%2Fagent365.svc.cloud.microsoft%2Fagents%2Ftenants%2F<tenant>f%2Fservers%2Fmcp_TeamsServer&nonce=<nonce>&code_challenge=<code_challenge>&code_challenge_method=S256
Image

[1] https://github.com/open-webui/open-webui/blob/main/backend/open_webui/utils/oauth.py#L567

Steps to Reproduce

  1. Use docker to setup OpenWebUI without any modification
  2. Open openwebui website from Chrome
  3. Go to Admin Panel -> Settings -> Integrations -> Add -> Change to MCP -> Provide url
    https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer -> select OAuth 2.1 (Static) -> Provide client_id & client_secret
Image
  1. Enable tool
Image
  1. Get Error
Image

Logs & Screenshots

Image

Additional Information

Microsoft WorkIQ MCP server doesn't support dynamic client registry.

This is the example of WorkIQ Team MCP server

  • MCP endpoint:
https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer
  • Their MCP server only have .well-known/oauth-protected-resource endpoint
    endpoint:
https://agent365.svc.cloud.microsoft/.well-known/oauth-protected-resource/agents/tenants/<tenant>/servers/mcp_TeamsServer

Response:

{
  "resource_name": "mcp_TeamsServer",
  "resource": "https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer",
  "authorization_servers": [
    "https://login.microsoftonline.com/organizations/v2.0"
  ],
  "scopes_supported": [
    "https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer/.default",
    "openid",
    "profile",
    "offline_access"
  ],
  "bearer_methods_supported": [
    "header"
  ]
}

Change suggestion

@dataclass
class ProtectedResourceMetadata:
    """RFC 9728 Protected Resource Metadata fields relevant to OAuth flows."""

    resource: str | None = None
    authorization_servers: list[str] = field(default_factory=list)
    scopes_supported: list[str] = field(default_factory=list)

    def get_discovery_urls(self, server_url: str) -> list[str]:
        """Build all candidate OAuth discovery URLs from this metadata and the server URL."""
        urls = []
        for auth_server in self.authorization_servers:
            resolved = _resolve_entra_tenant(auth_server, self.resource)
            urls.extend(_build_well_known_urls(resolved.rstrip('/')))
        urls.extend(_build_well_known_urls(server_url))
        return urls
  • Get supported scopes from oauth-protected-resource endpoint
async def get_protected_resource_metadata(server_url: str) -> ProtectedResourceMetadata:
    """
    Fetch RFC 9728 Protected Resource Metadata from an MCP server.

    https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization

    Returns:
        ProtectedResourceMetadata with the resource indicator (RFC 8707)
        and authorization server URLs discovered from the metadata document.
    """
    authorization_servers = []
    resource = None
    scopes_supported = []
    try:
        async with aiohttp.ClientSession(trust_env=True) as session:
            async with session.post(
                server_url,
                json={'jsonrpc': '2.0', 'method': 'initialize', 'params': {}, 'id': 1},
                headers={'Content-Type': 'application/json'},
                ssl=AIOHTTP_CLIENT_SESSION_SSL,
            ) as response:
                if response.status == 401:
                    resource_metadata_urls = []
                    match = re.search(
                        r'resource_metadata=(?:"([^"]+)"|([^\s,]+))',
                        response.headers.get('WWW-Authenticate', ''),
                    )
                    if match:
                        resource_metadata_urls = [match.group(1) or match.group(2)]
                        log.debug(f'Found resource_metadata URL: {resource_metadata_urls[0]}')
                    else:
                        # Fall back to well-known resource metadata URIs (RFC 9728 §4.2)
                        parsed, base_url = get_parsed_and_base_url(server_url)
                        if parsed.path and parsed.path != '/':
                            path = parsed.path.rstrip('/')
                            resource_metadata_urls.append(
                                urllib.parse.urljoin(base_url, f'/.well-known/oauth-protected-resource{path}')
                            )
                        resource_metadata_urls.append(
                            urllib.parse.urljoin(base_url, '/.well-known/oauth-protected-resource')
                        )
                        log.debug(f'No resource_metadata in header, trying well-known URIs: {resource_metadata_urls}')

                    # Fetch Protected Resource metadata from candidate URLs
                    for resource_metadata_url in resource_metadata_urls:
                        try:
                            async with session.get(
                                resource_metadata_url, ssl=AIOHTTP_CLIENT_SESSION_SSL
                            ) as resource_response:
                                if resource_response.status == 200:
                                    resource_metadata = await resource_response.json()

                                    resource = resource_metadata.get('resource') or None
                                    if resource:
                                        log.debug(f'Discovered resource indicator: {resource}')

                                    # RFC 9728: scopes_supported here is the per-resource
                                    # scope list — what the client should request to access
                                    # THIS resource server. Safe to use directly, unlike the
                                    # IdP-wide catalog from RFC 8414 oauth-authorization-server.
                                    discovered_scopes = resource_metadata.get('scopes_supported') or []
                                    if discovered_scopes:
                                        scopes_supported = discovered_scopes
                                        log.debug(f'Discovered resource scopes: {scopes_supported}')

                                    servers = resource_metadata.get('authorization_servers', [])
                                    if servers:
                                        authorization_servers = servers
                                        log.debug(f'Discovered authorization servers: {servers}')
                                        break
                        except Exception as e:
                            log.debug(f'Failed to fetch resource metadata from {resource_metadata_url}: {e}')
                            continue
    except Exception as e:
        log.debug(f'MCP Protected Resource discovery failed: {e}')

    return ProtectedResourceMetadata(
        resource=resource,
        authorization_servers=authorization_servers,
        scopes_supported=scopes_supported,
    )
  • Allow get_oauth_client_info_with_static_credentials to get scopes from ProtectedResourceMetadata
async def get_oauth_client_info_with_static_credentials(
    request,
    client_id: str,
    oauth_server_url: str,
    oauth_client_id: str,
    oauth_client_secret: str,
) -> OAuthClientInformationFull:
    """
    Build an OAuthClientInformationFull from user-provided static credentials.
    Performs server metadata discovery to resolve authorization/token endpoints,
    but skips dynamic client registration entirely.
    """
    try:
        oauth_server_metadata = None
        oauth_server_metadata_url = None

        redirect_base_url = (str(request.app.state.config.WEBUI_URL or request.base_url)).rstrip('/')
        redirect_uri = f'{redirect_base_url}/oauth/clients/{client_id}/callback'

        # Discover server metadata (authorization endpoint, token endpoint, scopes, etc.)
        resource_metadata = await get_protected_resource_metadata(oauth_server_url)
        resource = resource_metadata.resource
        discovery_urls = resource_metadata.get_discovery_urls(oauth_server_url)
        for url in discovery_urls:
            async with aiohttp.ClientSession(trust_env=True) as session:
                async with session.get(url, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
                    if resp.status == 200:
                        try:
                            oauth_server_metadata = OAuthMetadata.model_validate(await resp.json())
                            oauth_server_metadata_url = url
                            break
                        except Exception as e:
                            log.error(f'Error parsing OAuth metadata from {url}: {e}')
                            continue

        # Use scopes from the Protected Resource Metadata (RFC 9728) when available.
        # Unlike the auth-server's scopes_supported (an IdP-wide catalog of every
        # scope the server *can* grant), the protected-resource document advertises
        # the scopes specifically required to access THIS resource server, so it is
        # safe — and required by providers like Entra v2 — to request them.
        scope = (
            ' '.join(resource_metadata.scopes_supported)
            if resource_metadata.scopes_supported
            else None
        )

        # Determine token_endpoint_auth_method
        token_endpoint_auth_method = 'client_secret_post'
        if (
            oauth_server_metadata
            and oauth_server_metadata.token_endpoint_auth_methods_supported
            and token_endpoint_auth_method not in oauth_server_metadata.token_endpoint_auth_methods_supported
        ):
            token_endpoint_auth_method = oauth_server_metadata.token_endpoint_auth_methods_supported[0]

        oauth_client_info = OAuthClientInformationFull(
            client_id=oauth_client_id,
            client_secret=oauth_client_secret,
            redirect_uris=[redirect_uri],
            grant_types=['authorization_code', 'refresh_token'],
            response_types=['code'],
            scope=scope,
            token_endpoint_auth_method=token_endpoint_auth_method,
            issuer=oauth_server_metadata_url,
            server_metadata=oauth_server_metadata,
            resource=resource,
        )

        log.info(
            f'Static OAuth client info built for {oauth_client_id} using metadata from {oauth_server_metadata_url}'
        )
        return oauth_client_info
    except Exception as e:
        log.error(f'Exception building static OAuth client info: {e}')
        raise e
Originally created by @abehsu-mu on GitHub (May 14, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/24730 ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I have also searched in the CLOSED issues AND CLOSED discussions and found no related items (your issue might already be addressed on the development branch!). - [x] I am using the latest version of Open WebUI. ### Installation Method Docker ### Open WebUI Version v0.9.5 (latest) ### Ollama Version (if applicable) no ### Operating System MacOS Sequoia & Linux ### Browser (if applicable) Chrome Version 148.0.7778.97 ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior Openwebui should be able to retrieve scopes from `.well-known/oauth-protected-resource` and include those scopes when generating the `authorize` endpoint. ### Actual Behavior When openwebui try to generate authorization url, it missing scopes because of this line [1] Generate URL: ``` https://login.microsoftonline.com/organizations/v2.0/authorize?response_type=code&client_id=<client_id>&redirect_uri=<server_url>&resource=https%3A%2F%2Fagent365.svc.cloud.microsoft%2Fagents%2Ftenants%2F<tenant>f%2Fservers%2Fmcp_TeamsServer&nonce=<nonce>&code_challenge=<code_challenge>&code_challenge_method=S256 ``` <img width="1713" height="922" alt="Image" src="https://github.com/user-attachments/assets/3ea5c7f8-0768-424b-803c-4df055122358" /> [1] https://github.com/open-webui/open-webui/blob/main/backend/open_webui/utils/oauth.py#L567 ### Steps to Reproduce 1. Use docker to setup OpenWebUI without any modification 2. Open openwebui website from Chrome 3. Go to Admin Panel -> Settings -> Integrations -> Add -> Change to MCP -> Provide url ```https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer``` -> select OAuth 2.1 (Static) -> Provide client_id & client_secret <img width="469" height="560" alt="Image" src="https://github.com/user-attachments/assets/d7f0015f-8240-464c-b9e8-0a5d648863b7" /> 4. Enable tool <img width="1366" height="945" alt="Image" src="https://github.com/user-attachments/assets/14e0a85a-ac8f-43a5-901f-8bb1f15a7635" /> 5. Get Error <img width="1713" height="922" alt="Image" src="https://github.com/user-attachments/assets/7fec273c-45ed-4a59-ac0e-87432649ce00" /> ### Logs & Screenshots <img width="1713" height="922" alt="Image" src="https://github.com/user-attachments/assets/120feb0a-2b2d-46f0-bf51-994228222c39" /> ### Additional Information Microsoft WorkIQ MCP server doesn't support dynamic client registry. This is the example of WorkIQ Team MCP server - MCP endpoint: ``` https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer ``` - Their MCP server only have `.well-known/oauth-protected-resource` endpoint endpoint: ``` https://agent365.svc.cloud.microsoft/.well-known/oauth-protected-resource/agents/tenants/<tenant>/servers/mcp_TeamsServer ``` Response: ``` { "resource_name": "mcp_TeamsServer", "resource": "https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer", "authorization_servers": [ "https://login.microsoftonline.com/organizations/v2.0" ], "scopes_supported": [ "https://agent365.svc.cloud.microsoft/agents/tenants/<tenant>/servers/mcp_TeamsServer/.default", "openid", "profile", "offline_access" ], "bearer_methods_supported": [ "header" ] } ``` ### Change suggestion - Add scopes_supported within ProtectedResourceMetadata (https://github.com/open-webui/open-webui/blob/main/backend/open_webui/utils/oauth.py#L297) ``` @dataclass class ProtectedResourceMetadata: """RFC 9728 Protected Resource Metadata fields relevant to OAuth flows.""" resource: str | None = None authorization_servers: list[str] = field(default_factory=list) scopes_supported: list[str] = field(default_factory=list) def get_discovery_urls(self, server_url: str) -> list[str]: """Build all candidate OAuth discovery URLs from this metadata and the server URL.""" urls = [] for auth_server in self.authorization_servers: resolved = _resolve_entra_tenant(auth_server, self.resource) urls.extend(_build_well_known_urls(resolved.rstrip('/'))) urls.extend(_build_well_known_urls(server_url)) return urls ``` - Get supported scopes from oauth-protected-resource endpoint ``` async def get_protected_resource_metadata(server_url: str) -> ProtectedResourceMetadata: """ Fetch RFC 9728 Protected Resource Metadata from an MCP server. https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization Returns: ProtectedResourceMetadata with the resource indicator (RFC 8707) and authorization server URLs discovered from the metadata document. """ authorization_servers = [] resource = None scopes_supported = [] try: async with aiohttp.ClientSession(trust_env=True) as session: async with session.post( server_url, json={'jsonrpc': '2.0', 'method': 'initialize', 'params': {}, 'id': 1}, headers={'Content-Type': 'application/json'}, ssl=AIOHTTP_CLIENT_SESSION_SSL, ) as response: if response.status == 401: resource_metadata_urls = [] match = re.search( r'resource_metadata=(?:"([^"]+)"|([^\s,]+))', response.headers.get('WWW-Authenticate', ''), ) if match: resource_metadata_urls = [match.group(1) or match.group(2)] log.debug(f'Found resource_metadata URL: {resource_metadata_urls[0]}') else: # Fall back to well-known resource metadata URIs (RFC 9728 §4.2) parsed, base_url = get_parsed_and_base_url(server_url) if parsed.path and parsed.path != '/': path = parsed.path.rstrip('/') resource_metadata_urls.append( urllib.parse.urljoin(base_url, f'/.well-known/oauth-protected-resource{path}') ) resource_metadata_urls.append( urllib.parse.urljoin(base_url, '/.well-known/oauth-protected-resource') ) log.debug(f'No resource_metadata in header, trying well-known URIs: {resource_metadata_urls}') # Fetch Protected Resource metadata from candidate URLs for resource_metadata_url in resource_metadata_urls: try: async with session.get( resource_metadata_url, ssl=AIOHTTP_CLIENT_SESSION_SSL ) as resource_response: if resource_response.status == 200: resource_metadata = await resource_response.json() resource = resource_metadata.get('resource') or None if resource: log.debug(f'Discovered resource indicator: {resource}') # RFC 9728: scopes_supported here is the per-resource # scope list — what the client should request to access # THIS resource server. Safe to use directly, unlike the # IdP-wide catalog from RFC 8414 oauth-authorization-server. discovered_scopes = resource_metadata.get('scopes_supported') or [] if discovered_scopes: scopes_supported = discovered_scopes log.debug(f'Discovered resource scopes: {scopes_supported}') servers = resource_metadata.get('authorization_servers', []) if servers: authorization_servers = servers log.debug(f'Discovered authorization servers: {servers}') break except Exception as e: log.debug(f'Failed to fetch resource metadata from {resource_metadata_url}: {e}') continue except Exception as e: log.debug(f'MCP Protected Resource discovery failed: {e}') return ProtectedResourceMetadata( resource=resource, authorization_servers=authorization_servers, scopes_supported=scopes_supported, ) ``` - Allow get_oauth_client_info_with_static_credentials to get scopes from ProtectedResourceMetadata ``` async def get_oauth_client_info_with_static_credentials( request, client_id: str, oauth_server_url: str, oauth_client_id: str, oauth_client_secret: str, ) -> OAuthClientInformationFull: """ Build an OAuthClientInformationFull from user-provided static credentials. Performs server metadata discovery to resolve authorization/token endpoints, but skips dynamic client registration entirely. """ try: oauth_server_metadata = None oauth_server_metadata_url = None redirect_base_url = (str(request.app.state.config.WEBUI_URL or request.base_url)).rstrip('/') redirect_uri = f'{redirect_base_url}/oauth/clients/{client_id}/callback' # Discover server metadata (authorization endpoint, token endpoint, scopes, etc.) resource_metadata = await get_protected_resource_metadata(oauth_server_url) resource = resource_metadata.resource discovery_urls = resource_metadata.get_discovery_urls(oauth_server_url) for url in discovery_urls: async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(url, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp: if resp.status == 200: try: oauth_server_metadata = OAuthMetadata.model_validate(await resp.json()) oauth_server_metadata_url = url break except Exception as e: log.error(f'Error parsing OAuth metadata from {url}: {e}') continue # Use scopes from the Protected Resource Metadata (RFC 9728) when available. # Unlike the auth-server's scopes_supported (an IdP-wide catalog of every # scope the server *can* grant), the protected-resource document advertises # the scopes specifically required to access THIS resource server, so it is # safe — and required by providers like Entra v2 — to request them. scope = ( ' '.join(resource_metadata.scopes_supported) if resource_metadata.scopes_supported else None ) # Determine token_endpoint_auth_method token_endpoint_auth_method = 'client_secret_post' if ( oauth_server_metadata and oauth_server_metadata.token_endpoint_auth_methods_supported and token_endpoint_auth_method not in oauth_server_metadata.token_endpoint_auth_methods_supported ): token_endpoint_auth_method = oauth_server_metadata.token_endpoint_auth_methods_supported[0] oauth_client_info = OAuthClientInformationFull( client_id=oauth_client_id, client_secret=oauth_client_secret, redirect_uris=[redirect_uri], grant_types=['authorization_code', 'refresh_token'], response_types=['code'], scope=scope, token_endpoint_auth_method=token_endpoint_auth_method, issuer=oauth_server_metadata_url, server_metadata=oauth_server_metadata, resource=resource, ) log.info( f'Static OAuth client info built for {oauth_client_id} using metadata from {oauth_server_metadata_url}' ) return oauth_client_info except Exception as e: log.error(f'Exception building static OAuth client info: {e}') raise e ```
GiteaMirror added the bug label 2026-05-15 16:24:27 -05:00
Author
Owner

@owui-terminator[bot] commented on GitHub (May 14, 2026):

🔍 Related Issues Found

I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions:

  1. 🟣 #23668 Bug: admin-configured scopes overridden by discovered scopes_supported in static-credential OAuth flow
    This is directly related: it discusses static OAuth flows in get_oauth_client_info_with_static_credentials and how discovered scopes_supported are used to populate the authorization request. Your issue is the same area, but with the missing-scope problem arising from not reading scopes_supported from protected resource metadata.
    by dhruvalgupta2003

  2. 🟣 #19794 MCP OAuth 2.1: Not following WWW-Authenticate → Protected Resource → Authorization Server discovery chain
    This is closely related because it covers the MCP OAuth discovery chain from WWW-Authenticate to Protected Resource Metadata to Authorization Server Metadata. Your issue builds on that same chain, specifically the protected-resource document's scopes_supported field used for building the authorize URL.
    by jamie-dit · bug

  3. 🟣 #21183 Regression: MCP OAuth 2.1 discovery fails when authorization_servers URL path doesn't match well-known endpoint location
    This is related to the same MCP OAuth discovery logic around authorization_servers and well-known metadata lookup. While it focuses on discovery URL path handling rather than scopes, it affects the same static OAuth setup flow and is adjacent to the bug you reported.
    by ashavolian · bug


💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead.

This comment was generated automatically. React with 👍 if helpful, 👎 if not.

<!-- gh-comment-id:4454912470 --> @owui-terminator[bot] commented on GitHub (May 14, 2026): <!-- terminator-bot:related-issues-reply --> 🔍 **Related Issues Found** I found some existing issues that might be related. Please check if any of these are duplicates or contain helpful solutions: 1. 🟣 [#23668](https://github.com/open-webui/open-webui/issues/23668) **Bug: admin-configured scopes overridden by discovered scopes_supported in static-credential OAuth flow** *This is directly related: it discusses static OAuth flows in `get_oauth_client_info_with_static_credentials` and how discovered `scopes_supported` are used to populate the authorization request. Your issue is the same area, but with the missing-scope problem arising from not reading `scopes_supported` from protected resource metadata.* *by dhruvalgupta2003* 2. 🟣 [#19794](https://github.com/open-webui/open-webui/issues/19794) **MCP OAuth 2.1: Not following WWW-Authenticate → Protected Resource → Authorization Server discovery chain** *This is closely related because it covers the MCP OAuth discovery chain from `WWW-Authenticate` to Protected Resource Metadata to Authorization Server Metadata. Your issue builds on that same chain, specifically the protected-resource document's `scopes_supported` field used for building the authorize URL.* *by jamie-dit · `bug`* 3. 🟣 [#21183](https://github.com/open-webui/open-webui/issues/21183) **Regression: MCP OAuth 2.1 discovery fails when authorization_servers URL path doesn't match well-known endpoint location** *This is related to the same MCP OAuth discovery logic around `authorization_servers` and well-known metadata lookup. While it focuses on discovery URL path handling rather than scopes, it affects the same static OAuth setup flow and is adjacent to the bug you reported.* *by ashavolian · `bug`* --- 💡 If your issue is a duplicate, please close it and add any additional details to the existing issue instead. *This comment was generated automatically.* React with 👍 if helpful, 👎 if not.
Author
Owner

@abehsu-mu commented on GitHub (May 14, 2026):

Hi @owui-terminator:
I reviewed the tickets you shared, but neither of them resolved my issue.

<!-- gh-comment-id:4454930946 --> @abehsu-mu commented on GitHub (May 14, 2026): Hi @owui-terminator: I reviewed the tickets you shared, but neither of them resolved my issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#91127