[PR #231] [MERGED] feat: OAuth Support for Streamable HTTP with Dynamic Client Registration #217

Closed
opened 2026-10-18 21:12:46 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/mcpo/pull/231
Author: @taylorwilsdon
Created: 8/12/2025
Status: ✅ Merged
Merged: 8/12/2025
Merged by: @tjbck

Base: dev ← Head: oauth_support


📝 Commits (8)

  • c67dcb6 chore: publish action
  • 44ce6d0 Update publish.yaml
  • 0c6b408 Merge branch 'main' of github.com:open-webui/mcpo into dev
  • 8dd71b7 init oauth support
  • bf4f79b working oauth implementation for mcpo servers supporting dynamic client registration
  • 141d62b add oauth guide
  • 05911d5 clean up callback
  • 282e7e5 pretty callbacks

📊 Changes

8 files changed (+768 additions, -9 deletions)

View changed files

➕ .github/workflows/publish.yaml (+38 -0)
➕ OAUTH_GUIDE.md (+204 -0)
📝 README.md (+58 -0)
📝 pyproject.toml (+2 -2)
📝 src/mcpo/main.py (+33 -1)
➕ src/mcpo/utils/oauth.py (+294 -0)
➕ src/mcpo/utils/oauth_callback.html (+133 -0)
📝 uv.lock (+6 -6)

📄 Description

@tjbck I think you'll like this one ;) Opens some very interesting doors.

https://github.com/user-attachments/assets/36755a94-9c09-4569-a25e-24da71a1fd54

Pull Request Checklist

Before submitting, make sure you've checked the following:

  • Target branch: Please verify that the pull request targets the dev branch.
  • Description: Provide a concise description of the changes made in this pull request.
  • Changelog: Ensure a changelog entry following the format of Keep a Changelog is added at the bottom of the PR description.
  • Dependencies: Are there any new dependencies? Have you updated the dependency versions in the documentation? (No new dependencies added - uses existing MCP SDK OAuth components)
  • Testing: Have you written and run sufficient tests to validate the changes? (OAuth implementation tests written and validated)
  • Code review: Have you performed a self-review of your code, addressing any coding standard issues and ensuring adherence to the project's coding standards?
  • Prefix: To clearly categorize this pull request, prefix the pull request title using one of the following:
    • feat: Introduces a new feature or enhancement to the codebase

Changelog Entry

Description

feat: Add OAuth 2.1 client-to-server authentication support for MCP servers

This PR implements comprehensive OAuth 2.1 authentication support for MCPO, enabling secure client-to-server authentication with MCP servers that require OAuth. The implementation follows OAuth 2.1 best practices with dynamic client registration as the default approach and minimal configuration requirements.

Added

  • OAuth 2.1 Authentication Framework: Complete OAuth 2.1 Authorization Code flow with refresh token support
  • Dynamic Client Registration: Automatic client registration with OAuth servers that support it
  • Token Storage System: Both file-based persistent storage (~/.mcpo/tokens/) and in-memory session storage
  • Automatic Token Refresh: Transparent token refresh when access tokens expire
  • Browser-Based Authorization Flow: Automatic browser opening with local callback server
  • Per-Server OAuth Configuration: Independent OAuth sessions for each MCP server
  • OAuth Utilities Module (src/mcpo/utils/oauth.py): Core OAuth implementation with token storage and callback handling
  • Comprehensive Documentation:
    • Updated README.md with OAuth configuration examples
    • Complete OAUTH_GUIDE.md with detailed implementation guide
    • Example configuration files demonstrating usage patterns

Changed

  • Server Connection Logic: Updated lifespan function in main.py to integrate OAuth providers
  • Server Configuration: Extended server config validation to support optional oauth field
  • Transport Integration: Modified streamable-http client initialization to accept OAuth providers
  • Configuration Examples: Updated to emphasize dynamic registration over static configuration

Security

  • Secure Token Storage: File-based tokens stored with per-server isolation using server name hashing
  • PKCE Support: Automatic PKCE (Proof Key for Code Exchange) handling when required by servers
  • Callback Server Security: Local-only callback server with automatic cleanup
  • Token Isolation: Each server maintains independent OAuth sessions preventing token leakage

Breaking Changes

  • No breaking changes: OAuth support is entirely opt-in via configuration

Additional Information

  • Implementation Approach: Uses the Python MCP SDK's built-in OAuthClientProvider for standards compliance
  • Minimal Code Footprint: ~200 lines of new code with maximum leverage of existing MCP SDK components
  • Server Support: Currently supports streamable-http servers; sse and stdio servers log appropriate warnings
  • Configuration Philosophy: Defaults to dynamic client registration to minimize required configuration
  • Storage Strategy: File-based storage uses hashed server names to avoid filesystem conflicts
  • Testing: Comprehensive test suite validates token storage, provider creation, and configuration validation

Screenshots or Videos

  • [Video demonstration will be attached showing OAuth flow functionality]

Key Configuration Examples:

Minimal (Dynamic Registration):

{
  "mcpServers": {
    "oauth-server": {
      "type": "streamable-http",
      "url": "http://localhost:8000/mcp",
      "oauth": {
        "server_url": "http://localhost:8000"
      }
    }
  }
}

Legacy (Static Registration):

{
  "mcpServers": {
    "legacy-server": {
      "type": "streamable-http",
      "url": "http://localhost:8000/mcp",
      "oauth": {
        "server_url": "http://localhost:8000",
        "client_metadata": {
          "client_name": "My MCPO Client",
          "redirect_uris": ["http://localhost:3030/callback"]
        }
      }
    }
  }
}

🔄 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/mcpo/pull/231 **Author:** [@taylorwilsdon](https://github.com/taylorwilsdon) **Created:** 8/12/2025 **Status:** ✅ Merged **Merged:** 8/12/2025 **Merged by:** [@tjbck](https://github.com/tjbck) **Base:** `dev` ← **Head:** `oauth_support` --- ### 📝 Commits (8) - [`c67dcb6`](https://github.com/open-webui/mcpo/commit/c67dcb65e7215f651397ad61c748671174e3e526) chore: publish action - [`44ce6d0`](https://github.com/open-webui/mcpo/commit/44ce6d05b0392231c359c2d86228835001942851) Update publish.yaml - [`0c6b408`](https://github.com/open-webui/mcpo/commit/0c6b408a91135bdbd5f63d1b1f8fc1da1b0963f4) Merge branch 'main' of github.com:open-webui/mcpo into dev - [`8dd71b7`](https://github.com/open-webui/mcpo/commit/8dd71b73fb4b3a8f5a3496b1f3827e861fd4652e) init oauth support - [`bf4f79b`](https://github.com/open-webui/mcpo/commit/bf4f79ba4468cf7e5f3611ed114d188ac1f232a1) working oauth implementation for mcpo servers supporting dynamic client registration - [`141d62b`](https://github.com/open-webui/mcpo/commit/141d62bf8e368539a2d9a35c4bc9f40d5ce6c166) add oauth guide - [`05911d5`](https://github.com/open-webui/mcpo/commit/05911d5e7c27b03b900d25aa8a387a9aa6f26f98) clean up callback - [`282e7e5`](https://github.com/open-webui/mcpo/commit/282e7e5dc9619a2227bb04959b1e8dc0d5d03aef) pretty callbacks ### 📊 Changes **8 files changed** (+768 additions, -9 deletions) <details> <summary>View changed files</summary> ➕ `.github/workflows/publish.yaml` (+38 -0) ➕ `OAUTH_GUIDE.md` (+204 -0) 📝 `README.md` (+58 -0) 📝 `pyproject.toml` (+2 -2) 📝 `src/mcpo/main.py` (+33 -1) ➕ `src/mcpo/utils/oauth.py` (+294 -0) ➕ `src/mcpo/utils/oauth_callback.html` (+133 -0) 📝 `uv.lock` (+6 -6) </details> ### 📄 Description @tjbck I think you'll like this one ;) Opens some very interesting doors. https://github.com/user-attachments/assets/36755a94-9c09-4569-a25e-24da71a1fd54 # Pull Request Checklist **Before submitting, make sure you've checked the following:** - [x] **Target branch:** Please verify that the pull request targets the `dev` branch. - [x] **Description:** Provide a concise description of the changes made in this pull request. - [x] **Changelog:** Ensure a changelog entry following the format of [Keep a Changelog](https://keepachangelog.com/) is added at the bottom of the PR description. - [x] **Dependencies:** Are there any new dependencies? Have you updated the dependency versions in the documentation? *(No new dependencies added - uses existing MCP SDK OAuth components)* - [x] **Testing:** Have you written and run sufficient tests to validate the changes? *(OAuth implementation tests written and validated)* - [x] **Code review:** Have you performed a self-review of your code, addressing any coding standard issues and ensuring adherence to the project's coding standards? - [x] **Prefix:** To clearly categorize this pull request, prefix the pull request title using one of the following: - **feat**: Introduces a new feature or enhancement to the codebase # Changelog Entry ### Description **feat**: Add OAuth 2.1 client-to-server authentication support for MCP servers This PR implements comprehensive OAuth 2.1 authentication support for MCPO, enabling secure client-to-server authentication with MCP servers that require OAuth. The implementation follows OAuth 2.1 best practices with dynamic client registration as the default approach and minimal configuration requirements. ### Added - **OAuth 2.1 Authentication Framework**: Complete OAuth 2.1 Authorization Code flow with refresh token support - **Dynamic Client Registration**: Automatic client registration with OAuth servers that support it - **Token Storage System**: Both file-based persistent storage (`~/.mcpo/tokens/`) and in-memory session storage - **Automatic Token Refresh**: Transparent token refresh when access tokens expire - **Browser-Based Authorization Flow**: Automatic browser opening with local callback server - **Per-Server OAuth Configuration**: Independent OAuth sessions for each MCP server - **OAuth Utilities Module** (`src/mcpo/utils/oauth.py`): Core OAuth implementation with token storage and callback handling - **Comprehensive Documentation**: - Updated README.md with OAuth configuration examples - Complete OAUTH_GUIDE.md with detailed implementation guide - Example configuration files demonstrating usage patterns ### Changed - **Server Connection Logic**: Updated `lifespan` function in `main.py` to integrate OAuth providers - **Server Configuration**: Extended server config validation to support optional `oauth` field - **Transport Integration**: Modified streamable-http client initialization to accept OAuth providers - **Configuration Examples**: Updated to emphasize dynamic registration over static configuration ### Security - **Secure Token Storage**: File-based tokens stored with per-server isolation using server name hashing - **PKCE Support**: Automatic PKCE (Proof Key for Code Exchange) handling when required by servers - **Callback Server Security**: Local-only callback server with automatic cleanup - **Token Isolation**: Each server maintains independent OAuth sessions preventing token leakage ### Breaking Changes - **No breaking changes**: OAuth support is entirely opt-in via configuration --- ### Additional Information - **Implementation Approach**: Uses the Python MCP SDK's built-in `OAuthClientProvider` for standards compliance - **Minimal Code Footprint**: ~200 lines of new code with maximum leverage of existing MCP SDK components - **Server Support**: Currently supports `streamable-http` servers; `sse` and `stdio` servers log appropriate warnings - **Configuration Philosophy**: Defaults to dynamic client registration to minimize required configuration - **Storage Strategy**: File-based storage uses hashed server names to avoid filesystem conflicts - **Testing**: Comprehensive test suite validates token storage, provider creation, and configuration validation ### Screenshots or Videos - [Video demonstration will be attached showing OAuth flow functionality] **Key Configuration Examples:** **Minimal (Dynamic Registration):** ```json { "mcpServers": { "oauth-server": { "type": "streamable-http", "url": "http://localhost:8000/mcp", "oauth": { "server_url": "http://localhost:8000" } } } } ``` **Legacy (Static Registration):** ```json { "mcpServers": { "legacy-server": { "type": "streamable-http", "url": "http://localhost:8000/mcp", "oauth": { "server_url": "http://localhost:8000", "client_metadata": { "client_name": "My MCPO Client", "redirect_uris": ["http://localhost:3030/callback"] } } } } } ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-18 21:12:46 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
open-webui/mcpo#217
No description provided.