[PR #19795] [CLOSED] fix: MCP OAuth discovery via Protected Resource metadata flow #25347

Closed
opened 2026-04-20 05:53:50 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/19795
Author: @jamie-dit
Created: 12/7/2025
Status: Closed

Base: mainHead: fix/mcp-oauth-protected-resource-discovery


📝 Commits (1)

  • b766a23 fix: MCP OAuth discovery via Protected Resource metadata flow

📊 Changes

1 file changed (+77 additions, -2 deletions)

View changed files

📝 backend/open_webui/utils/oauth.py (+77 -2)

📄 Description

Summary

This PR fixes MCP OAuth 2.1 client registration failing when the OAuth authorization server is on a different domain than the MCP server (e.g., Todoist MCP at ai.todoist.net with OAuth at todoist.com).

Problem

Currently, Open WebUI only looks for OAuth metadata at:

{MCP_SERVER_URL}/.well-known/oauth-authorization-server

But according to the MCP Authorization spec, clients should follow the Protected Resource discovery flow when the OAuth server is on a different domain.

Solution

Implements the full MCP Protected Resource discovery flow:

  1. Make unauthenticated request to MCP endpoint → receives 401 with WWW-Authenticate header
  2. Parse resource_metadata URL from the header
  3. Fetch Protected Resource metadata → contains authorization_servers array
  4. Use discovered servers for OAuth metadata discovery

Example flow for Todoist:

POST ai.todoist.net/mcp (no auth)
    ↓ 401 + WWW-Authenticate: Bearer resource_metadata="https://ai.todoist.net/.well-known/oauth-protected-resource/mcp"

GET ai.todoist.net/.well-known/oauth-protected-resource/mcp
    ↓ { "authorization_servers": ["https://todoist.com"] }

GET todoist.com/.well-known/oauth-authorization-server
    ↓ { "registration_endpoint": "https://todoist.com/oauth/register", ... }

POST todoist.com/oauth/register (DCR)
    ↓ { "client_id": "...", "client_secret": "..." } ✅

Changes

  • Added discover_authorization_server_from_mcp() function that implements the Protected Resource discovery flow
  • Modified get_oauth_client_info_with_dynamic_client_registration() to:
    1. First try MCP Protected Resource discovery
    2. Build discovery URLs from discovered authorization servers
    3. Fall back to existing behaviour if discovery fails

Backwards Compatibility

The fix is fully backwards-compatible. If Protected Resource discovery fails (no WWW-Authenticate header, network error, etc.), it falls back to the existing discovery behavior.

Testing

Tested with:

  • Todoist MCP server (https://ai.todoist.net/mcp) - previously failing, now works
  • Should continue to work with MCP servers where OAuth is on the same domain

Fixes #19794

Checklist

  • Code follows project style guidelines
  • Changes are backwards-compatible
  • No breaking changes to existing functionality

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/open-webui/open-webui/pull/19795 **Author:** [@jamie-dit](https://github.com/jamie-dit) **Created:** 12/7/2025 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/mcp-oauth-protected-resource-discovery` --- ### 📝 Commits (1) - [`b766a23`](https://github.com/open-webui/open-webui/commit/b766a23e36062e52c852a849beba64e67de9d0c8) fix: MCP OAuth discovery via Protected Resource metadata flow ### 📊 Changes **1 file changed** (+77 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `backend/open_webui/utils/oauth.py` (+77 -2) </details> ### 📄 Description ## Summary This PR fixes MCP OAuth 2.1 client registration failing when the OAuth authorization server is on a different domain than the MCP server (e.g., Todoist MCP at `ai.todoist.net` with OAuth at `todoist.com`). ## Problem Currently, Open WebUI only looks for OAuth metadata at: ``` {MCP_SERVER_URL}/.well-known/oauth-authorization-server ``` But according to the [MCP Authorization spec](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization), clients should follow the Protected Resource discovery flow when the OAuth server is on a different domain. ## Solution Implements the full MCP Protected Resource discovery flow: 1. **Make unauthenticated request** to MCP endpoint → receives 401 with `WWW-Authenticate` header 2. **Parse `resource_metadata` URL** from the header 3. **Fetch Protected Resource metadata** → contains `authorization_servers` array 4. **Use discovered servers** for OAuth metadata discovery ### Example flow for Todoist: ``` POST ai.todoist.net/mcp (no auth) ↓ 401 + WWW-Authenticate: Bearer resource_metadata="https://ai.todoist.net/.well-known/oauth-protected-resource/mcp" GET ai.todoist.net/.well-known/oauth-protected-resource/mcp ↓ { "authorization_servers": ["https://todoist.com"] } GET todoist.com/.well-known/oauth-authorization-server ↓ { "registration_endpoint": "https://todoist.com/oauth/register", ... } POST todoist.com/oauth/register (DCR) ↓ { "client_id": "...", "client_secret": "..." } ✅ ``` ## Changes - Added `discover_authorization_server_from_mcp()` function that implements the Protected Resource discovery flow - Modified `get_oauth_client_info_with_dynamic_client_registration()` to: 1. First try MCP Protected Resource discovery 2. Build discovery URLs from discovered authorization servers 3. Fall back to existing behaviour if discovery fails ## Backwards Compatibility The fix is fully backwards-compatible. If Protected Resource discovery fails (no `WWW-Authenticate` header, network error, etc.), it falls back to the existing discovery behavior. ## Testing Tested with: - Todoist MCP server (`https://ai.todoist.net/mcp`) - previously failing, now works - Should continue to work with MCP servers where OAuth is on the same domain ## Related Issues Fixes #19794 ## Checklist - [x] Code follows project style guidelines - [x] Changes are backwards-compatible - [x] No breaking changes to existing functionality --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-20 05:53:50 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#25347