[GH-ISSUE #19794] MCP OAuth 2.1: Not following WWW-Authenticate → Protected Resource → Authorization Server discovery chain #18996

Closed
opened 2026-04-20 01:17:20 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @jamie-dit on GitHub (Dec 7, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/19794

Bug Description

When adding a Todoist MCP server (https://ai.todoist.net/mcp) with OAuth 2.1 authentication, clicking "Register Client" fails with a 400 Bad Request error. However, Todoist's OAuth infrastructure is correctly configured according to the MCP specification.

Steps to Reproduce

  1. Go to Admin Settings → External Tools → Add Server
  2. Set Type to MCP (Streamable HTTP)
  3. Enter URL: https://ai.todoist.net/mcp
  4. Set Auth to OAuth 2.1
  5. Click Register Client
  6. Registration fails with 400 Bad Request

Root Cause Analysis

The MCP OAuth 2.1 specification requires clients to follow a discovery chain. Todoist implements this correctly:

1. MCP Server returns 401 with WWW-Authenticate header

$ curl -s -D - https://ai.todoist.net/mcp -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}'

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://ai.todoist.net/.well-known/oauth-protected-resource/mcp"

2. Protected Resource Metadata points to Authorization Server

$ curl -s https://ai.todoist.net/.well-known/oauth-protected-resource/mcp

{
  "resource": "https://ai.todoist.net/mcp",
  "authorization_servers": ["https://todoist.com"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["data:read_write"]
}

3. Authorization Server has OAuth metadata with DCR endpoint

$ curl -s https://todoist.com/.well-known/oauth-authorization-server

{
  "issuer": "https://todoist.com",
  "registration_endpoint": "https://todoist.com/oauth/register",
  "authorization_endpoint": "https://todoist.com/oauth/authorize",
  "token_endpoint": "https://todoist.com/oauth/access_token",
  "code_challenge_methods_supported": ["S256"],
  ...
}

4. DCR endpoint works correctly

$ curl -s https://todoist.com/oauth/register -X POST -H "Content-Type: application/json" \
  -d '{"redirect_uris":["https://example.com/callback"],"client_name":"Test"}'

{
  "client_id": "tdd_xxxxx",
  "client_secret": "xxxxx",
  ...
}

The Problem

Open WebUI appears to look for OAuth metadata directly at {MCP_SERVER_URL}/.well-known/oauth-authorization-server (which returns 404 for ai.todoist.net), instead of:

  1. Making an unauthenticated request to the MCP endpoint
  2. Parsing the WWW-Authenticate header to get the Protected Resource metadata URL
  3. Fetching the Protected Resource metadata to get the Authorization Server URL
  4. Fetching the Authorization Server metadata to get the DCR registration endpoint

Expected Behavior

Open WebUI should follow the full MCP OAuth discovery chain as specified in the MCP Authorization spec.

Environment

  • Open WebUI Version: Latest (as of Dec 2025)
  • MCP Server: https://ai.todoist.net/mcp (Todoist official)
  • Browser: Chrome

Workaround

Using Bearer token authentication via the Headers field works:

{"Authorization": "Bearer <TODOIST_API_TOKEN>"}
  • #18010 - MCP OAuth 2.1 flow doesn't match standard
  • #19116 - MCP OAuth 2.1 client registration fails with empty URIs
  • mcpo#272 - OAuth authentication with static client metadata
Originally created by @jamie-dit on GitHub (Dec 7, 2025). Original GitHub issue: https://github.com/open-webui/open-webui/issues/19794 ## Bug Description When adding a Todoist MCP server (`https://ai.todoist.net/mcp`) with OAuth 2.1 authentication, clicking "Register Client" fails with a 400 Bad Request error. However, Todoist's OAuth infrastructure is correctly configured according to the MCP specification. ## Steps to Reproduce 1. Go to **Admin Settings → External Tools → Add Server** 2. Set Type to **MCP (Streamable HTTP)** 3. Enter URL: `https://ai.todoist.net/mcp` 4. Set Auth to **OAuth 2.1** 5. Click **Register Client** 6. Registration fails with 400 Bad Request ## Root Cause Analysis The MCP OAuth 2.1 specification requires clients to follow a discovery chain. Todoist implements this correctly: ### 1. MCP Server returns 401 with WWW-Authenticate header ```bash $ curl -s -D - https://ai.todoist.net/mcp -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer resource_metadata="https://ai.todoist.net/.well-known/oauth-protected-resource/mcp" ``` ### 2. Protected Resource Metadata points to Authorization Server ```bash $ curl -s https://ai.todoist.net/.well-known/oauth-protected-resource/mcp { "resource": "https://ai.todoist.net/mcp", "authorization_servers": ["https://todoist.com"], "bearer_methods_supported": ["header"], "scopes_supported": ["data:read_write"] } ``` ### 3. Authorization Server has OAuth metadata with DCR endpoint ```bash $ curl -s https://todoist.com/.well-known/oauth-authorization-server { "issuer": "https://todoist.com", "registration_endpoint": "https://todoist.com/oauth/register", "authorization_endpoint": "https://todoist.com/oauth/authorize", "token_endpoint": "https://todoist.com/oauth/access_token", "code_challenge_methods_supported": ["S256"], ... } ``` ### 4. DCR endpoint works correctly ```bash $ curl -s https://todoist.com/oauth/register -X POST -H "Content-Type: application/json" \ -d '{"redirect_uris":["https://example.com/callback"],"client_name":"Test"}' { "client_id": "tdd_xxxxx", "client_secret": "xxxxx", ... } ``` ## The Problem Open WebUI appears to look for OAuth metadata directly at `{MCP_SERVER_URL}/.well-known/oauth-authorization-server` (which returns 404 for `ai.todoist.net`), instead of: 1. Making an unauthenticated request to the MCP endpoint 2. Parsing the `WWW-Authenticate` header to get the Protected Resource metadata URL 3. Fetching the Protected Resource metadata to get the Authorization Server URL 4. Fetching the Authorization Server metadata to get the DCR registration endpoint ## Expected Behavior Open WebUI should follow the full MCP OAuth discovery chain as specified in the [MCP Authorization spec](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). ## Environment - Open WebUI Version: Latest (as of Dec 2025) - MCP Server: `https://ai.todoist.net/mcp` (Todoist official) - Browser: Chrome ## Workaround Using Bearer token authentication via the Headers field works: ```json {"Authorization": "Bearer <TODOIST_API_TOKEN>"} ``` ## Related Issues - #18010 - MCP OAuth 2.1 flow doesn't match standard - #19116 - MCP OAuth 2.1 client registration fails with empty URIs - mcpo#272 - OAuth authentication with static client metadata
GiteaMirror added the bug label 2026-04-20 01:17:20 -05:00
Author
Owner

@owui-terminator[bot] commented on GitHub (Dec 7, 2025):

🔍 Similar Issues Found

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

  1. #18010 issue: MCP OAuth 2.1 flow doesn't match standard (missing code_challenge and resource_url)
    by hsuyuming • Oct 02, 2025 • bug

  2. #14119 feat: Enable per-user authentication in MCP for personalized tool access or consider implementing a proper MCP Client
    by florianchappaz • May 21, 2025

  3. #19778 issue: Streamable HTTP Notion MCP server doesn't stay enabled after authorizing
    by Sam-Horry • Dec 05, 2025 • bug


💡 Tips:

  • If this is a duplicate, please consider closing this issue and adding any additional details to the existing one
  • If you found a solution in any of these issues, please share it here to help others

This comment was generated automatically by a bot. Please react with a 👍 if this comment was helpful, or a 👎 if it was not.

<!-- gh-comment-id:3621476002 --> @owui-terminator[bot] commented on GitHub (Dec 7, 2025): 🔍 **Similar Issues Found** I found some existing issues that might be related to this one. Please check if any of these are duplicates or contain helpful solutions: 1. [#18010](https://github.com/open-webui/open-webui/issues/18010) **issue: MCP OAuth 2.1 flow doesn't match standard (missing code_challenge and resource_url)** *by hsuyuming • Oct 02, 2025 • `bug`* 2. [#14119](https://github.com/open-webui/open-webui/issues/14119) **feat: Enable per-user authentication in MCP for personalized tool access or consider implementing a proper MCP Client** *by florianchappaz • May 21, 2025* 3. [#19778](https://github.com/open-webui/open-webui/issues/19778) **issue: Streamable HTTP Notion MCP server doesn't stay enabled after authorizing** *by Sam-Horry • Dec 05, 2025 • `bug`* --- 💡 **Tips:** - If this is a duplicate, please consider closing this issue and adding any additional details to the existing one - If you found a solution in any of these issues, please share it here to help others *This comment was generated automatically by a bot.* Please react with a 👍 if this comment was helpful, or a 👎 if it was not.
Author
Owner

@jamie-dit commented on GitHub (Dec 7, 2025):

Update: Fix submitted

I've identified the root cause and submitted a fix in PR #19795.

Root Cause

The current implementation only looks for OAuth metadata at {MCP_SERVER_URL}/.well-known/oauth-authorization-server, but according to the MCP spec, when the OAuth server is on a different domain, clients should follow the Protected Resource discovery flow:

  1. POST ai.todoist.net/mcp → 401 + WWW-Authenticate: Bearer resource_metadata="https://ai.todoist.net/.well-known/oauth-protected-resource/mcp"
  2. GET ai.todoist.net/.well-known/oauth-protected-resource/mcp{"authorization_servers": ["https://todoist.com"]}
  3. GET todoist.com/.well-known/oauth-authorization-server{"registration_endpoint": "https://todoist.com/oauth/register", ...}
  4. POST todoist.com/oauth/register DCR works

Verification

I've tested the fix on a live Open WebUI instance and confirmed Todoist OAuth registration now works correctly.

Workaround

Until the PR is merged, you can use Bearer token authentication instead:

  1. Get your API token from Todoist Settings → Integrations → Developer
  2. In Open WebUI, add this header: {"Authorization": "Bearer YOUR_TOKEN"}
<!-- gh-comment-id:3621481783 --> @jamie-dit commented on GitHub (Dec 7, 2025): ## Update: Fix submitted I've identified the root cause and submitted a fix in PR #19795. ### Root Cause The current implementation only looks for OAuth metadata at `{MCP_SERVER_URL}/.well-known/oauth-authorization-server`, but according to the MCP spec, when the OAuth server is on a different domain, clients should follow the **Protected Resource discovery flow**: 1. `POST ai.todoist.net/mcp` → 401 + `WWW-Authenticate: Bearer resource_metadata="https://ai.todoist.net/.well-known/oauth-protected-resource/mcp"` 2. `GET ai.todoist.net/.well-known/oauth-protected-resource/mcp` → `{"authorization_servers": ["https://todoist.com"]}` 3. `GET todoist.com/.well-known/oauth-authorization-server` → `{"registration_endpoint": "https://todoist.com/oauth/register", ...}` 4. `POST todoist.com/oauth/register` → ✅ DCR works ### Verification I've tested the fix on a live Open WebUI instance and confirmed Todoist OAuth registration now works correctly. ### Workaround Until the PR is merged, you can use Bearer token authentication instead: 1. Get your API token from Todoist Settings → Integrations → Developer 2. In Open WebUI, add this header: `{"Authorization": "Bearer YOUR_TOKEN"}`
Author
Owner

@jamie-dit commented on GitHub (Dec 7, 2025):

Updated: PR #19795 was closed (wrong base branch). New PR targeting dev: #19796

<!-- gh-comment-id:3621485011 --> @jamie-dit commented on GitHub (Dec 7, 2025): Updated: PR #19795 was closed (wrong base branch). New PR targeting `dev`: #19796
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#18996