issue: OAuth authentication with static client metadata #126

Open
opened 2026-02-15 21:15:00 -05:00 by yindo · 1 comment
Owner

Originally created by @bpellens on GitHub (Nov 21, 2025).

Check Existing Issues

  • I have searched the existing issues and discussions.
  • I am using the latest version of mcpo.

mcpo Version

0.0.19

Open WebUI Version (if applicable)

No response

Operating System

macOS Sequoia

Browser (if applicable)

No response

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both MCPO and Open WebUI.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have listed steps to reproduce the bug in detail.

Expected Behavior

A web browser would open initiating the OAuth flow.

Actual Behavior

Still a dynamic client registration seems to be performed. No OAuth flow is started.

Steps to Reproduce

  1. Configure mcpo using the following static client metadata (as Google does not support dynamic client registration)

{ "mcpServers": { "toolbox-mcp": { "type": "streamable-http", "url": "http://127.0.0.1:5000/mcp", "oauth": { "server_url": "https://accounts.google.com", "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth", "token_endpoint": "https://oauth2.googleapis.com/token", "storage_type": "file", "use_loopback": true, "callback_port": 3030, "client_metadata": { "client_name": "MySampleApp", "client_id": "101******.apps.googleusercontent.com", "client_secret": "GO******", "redirect_uris": ["http://localhost:3030/callback"], "scope": "openid email profile" } } } } }

  1. Launch the mcpo procy, using the above configuration, via: uvx mcpo@0.0.19 --config mcpoconfig.json

  2. Add the tool to Open WebUI

Image
  1. Trigger the tool.

Logs & Screenshots

Starting MCP OpenAPI Proxy with config file: mcpoconfig.json
2025-11-21 09:42:51,101 - INFO - Starting MCPO Server...
2025-11-21 09:42:51,101 - INFO - Name: MCP OpenAPI Proxy
2025-11-21 09:42:51,101 - INFO - Version: 1.0
2025-11-21 09:42:51,101 - INFO - Description: Automatically generated API from MCP Tool Schemas
2025-11-21 09:42:51,101 - INFO - Hostname: ******.local
2025-11-21 09:42:51,101 - INFO - Port: 8000
2025-11-21 09:42:51,101 - INFO - API Key: Not Provided
2025-11-21 09:42:51,101 - INFO - CORS Allowed Origins: ['
']
2025-11-21 09:42:51,102 - INFO - Path Prefix: /
2025-11-21 09:42:51,102 - INFO - Root Path:
2025-11-21 09:42:51,102 - INFO - Loading MCP server configurations from: mcpoconfig.json
2025-11-21 09:42:51,102 - INFO - Configuring MCP Servers:
2025-11-21 09:42:51,102 - INFO - Uvicorn server starting...
INFO: Started server process [22387]
INFO: Waiting for application startup.
2025-11-21 09:42:51,109 - INFO - Initiating connection for server: 'toolbox-mcp'...
2025-11-21 09:42:51,109 - INFO - OAuth configuration detected for server: toolbox-mcp
2025-11-21 09:42:51,112 - INFO - OAuth provider created for server: toolbox-mcp
2025-11-21 09:42:51,129 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 200 OK"
2025-11-21 09:42:51,129 - INFO - Negotiated protocol version: 2025-06-18
2025-11-21 09:42:51,130 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 202 Accepted"
2025-11-21 09:42:51,131 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 200 OK"
2025-11-21 09:42:51,132 - INFO - Successfully connected to 'toolbox-mcp'.
2025-11-21 09:42:51,132 - INFO -
--- Server Startup Summary ---
2025-11-21 09:42:51,132 - INFO - Successfully connected to:
2025-11-21 09:42:51,132 - INFO - - toolbox-mcp
2025-11-21 09:42:51,132 - INFO - --------------------------

INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 127.0.0.1:59644 - "OPTIONS /toolbox-mcp/openapi.json HTTP/1.1" 200 OK
INFO: 127.0.0.1:59644 - "GET /toolbox-mcp/openapi.json HTTP/1.1" 200 OK
INFO: 127.0.0.1:59644 - "GET /toolbox-mcp/openapi.json HTTP/1.1" 200 OK
INFO: 127.0.0.1:59644 - "GET /toolbox-mcp/openapi.json HTTP/1.1" 200 OK
INFO: 127.0.0.1:59696 - "OPTIONS /toolbox-mcp/find-profiles-by-skill HTTP/1.1" 200 OK
2025-11-21 09:51:35,787 - INFO - Calling endpoint: find-profiles-by-skill, with args: {'skillName': 'C#'}
2025-11-21 09:51:35,794 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 401 Unauthorized"
2025-11-21 09:51:35,909 - INFO - HTTP Request: GET https://accounts.google.com/.well-known/oauth-protected-resource "HTTP/1.1 404 Not Found"
2025-11-21 09:51:35,931 - INFO - HTTP Request: GET https://accounts.google.com/.well-known/oauth-authorization-server "HTTP/1.1 200 OK"
2025-11-21 09:51:35,961 - INFO - HTTP Request: POST https://accounts.google.com/register "HTTP/1.1 400 Bad Request"
2025-11-21 09:51:35,962 - ERROR - OAuth flow error
Traceback (most recent call last):
File "/Users//.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/oauth2.py", line 522, in async_auth_flow
client_information = await handle_registration_response(registration_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/
/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/utils.py", line 234, in handle_registration_response
raise OAuthRegistrationError(f"Registration failed: {response.status_code} {response.text}")
mcp.client.auth.exceptions.OAuthRegistrationError: Registration failed: 400 <html lang="nl" dir=ltr><style nonce="jrmkwMbw87vCPldJ4EGIvQ">{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{color:#222;text-align:unset;margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px;} > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}pre{white-space:pre-wrap;}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}</style>

400. That’s an error.

The server cannot process the request because it is malformed. It should not be retried. That’s all we know.


2025-11-21 09:51:35,969 - ERROR - Failed to connect to MCP server 'Toolbox': ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)

  • Exception Group Traceback (most recent call last):
    | File "/Users//.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcpo/main.py", line 567, in lifespan
    | async with client_context as (reader, writer, _):
    | ^^^^^^^^^^^^^^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in aexit
    | await self.gen.athrow(value)
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 480, in streamablehttp_client
    | async with anyio.create_task_group() as tg:
    | ~~~~~~~~~~~~~~~~~~~~~~~^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 781, in aexit
    | raise BaseExceptionGroup(
    | "unhandled errors in a TaskGroup", self._exceptions
    | ) from None
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 411, in handle_request_async
    | await self._handle_post_request(ctx)
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 262, in _handle_post_request
    | async with ctx.client.stream(
    | ~~~~~~~~~~~~~~~~~^
    | "POST",
    | ^^^^^^^
    | ...<2 lines>...
    | headers=headers,
    | ^^^^^^^^^^^^^^^^
    | ) as response:
    | ^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 214, in aenter
    | return await anext(self.gen)
    | ^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1583, in stream
    | response = await self.send(
    | ^^^^^^^^^^^^^^^^
    | ...<4 lines>...
    | )
    | ^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1629, in send
    | response = await self._send_handling_auth(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | ...<4 lines>...
    | )
    | ^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1675, in _send_handling_auth
    | raise exc
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1664, in _send_handling_auth
    | next_request = await auth_flow.asend(response)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/oauth2.py", line 522, in async_auth_flow
    | client_information = await handle_registration_response(registration_response)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/utils.py", line 234, in handle_registration_response
    | raise OAuthRegistrationError(f"Registration failed: {response.status_code} {response.text}")
    | mcp.client.auth.exceptions.OAuthRegistrationError: Registration failed: 400 <html lang="nl" dir=ltr><style nonce="jrmkwMbw87vCPldJ4EGIvQ">
    {margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{color:#222;text-align:unset;margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px;}
    > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}pre{white-space:pre-wrap;}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}</style>

    400. That’s an error.

    The server cannot process the request because it is malformed. It should not be retried. That’s all we know.


    +------------------------------------
    ERROR: + Exception Group Traceback (most recent call last):
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/starlette/routing.py", line 694, in lifespan
    | async with self.lifespan_context(app) as maybe_state:
    | ~~~~~~~~~~~~~~~~~~~~~^^^^^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in aexit
    | await self.gen.athrow(value)
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcpo/main.py", line 438, in lifespan
    | async with AsyncExitStack() as stack:
    | ~~~~~~~~~~~~~~^^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 768, in aexit
    | raise exc
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 751, in aexit
    | cb_suppress = await cb(exc_details)
    | ^^^^^^^^^^^^^^^^^^^^^^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in aexit
    | await self.gen.athrow(value)
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcpo/main.py", line 567, in lifespan
    | async with client_context as (reader, writer, _):
    | ^^^^^^^^^^^^^^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in aexit
    | await self.gen.athrow(value)
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 480, in streamablehttp_client
    | async with anyio.create_task_group() as tg:
    | ~~~~~~~~~~~~~~~~~~~~~~~^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 781, in aexit
    | raise BaseExceptionGroup(
    | "unhandled errors in a TaskGroup", self._exceptions
    | ) from None
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 411, in handle_request_async
    | await self._handle_post_request(ctx)
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 262, in _handle_post_request
    | async with ctx.client.stream(
    | ~~~~~~~~~~~~~~~~~^
    | "POST",
    | ^^^^^^^
    | ...<2 lines>...
    | headers=headers,
    | ^^^^^^^^^^^^^^^^
    | ) as response:
    | ^
    | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 214, in aenter
    | return await anext(self.gen)
    | ^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1583, in stream
    | response = await self.send(
    | ^^^^^^^^^^^^^^^^
    | ...<4 lines>...
    | )
    | ^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1629, in send
    | response = await self._send_handling_auth(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | ...<4 lines>...
    | )
    | ^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1675, in _send_handling_auth
    | raise exc
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1664, in _send_handling_auth
    | next_request = await auth_flow.asend(response)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/
    /.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/oauth2.py", line 522, in async_auth_flow
    | client_information = await handle_registration_response(registration_response)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/
    */.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/utils.py", line 234, in handle_registration_response
    | raise OAuthRegistrationError(f"Registration failed: {response.status_code} {response.text}")
    | mcp.client.auth.exceptions.OAuthRegistrationError: Registration failed: 400 <html lang="nl" dir=ltr><style nonce="jrmkwMbw87vCPldJ4EGIvQ">
    {margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{color:#222;text-align:unset;margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px;}
    > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}pre{white-space:pre-wrap;}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}</style>

    400. That’s an error.

    The server cannot process the request because it is malformed. It should not be retried. That’s all we know.


    +------------------------------------

Additional Information

My objective is to expose my MCP server, which is created with the MCP Toolbox for Databases (https://googleapis.github.io/genai-toolbox), as a tool in my Open WebUI via the mcpo proxy. The MCP server is configured with a BigQuery source and tool. I would like to pass the user context to the tool, executing the query on my BigQuery dataset.

As Google does not seem to support dynamic OAuth client registration, I would like to configure the mcpo proxy using static client metadata. I expected with this configuration that a browser based OAuth flow would be initiated. However, if I understand correctly, the mcpo still tries to initiate a dynamic client registration and consequently fails.

Is it possible to setup the mcpo proxy in such a way that a user-based OAuth flow is triggered and the access token resulting from the OAuth flow is passed to the MCP server?
(My apologies if this question, or similar has been raised elsewhere).

Originally created by @bpellens on GitHub (Nov 21, 2025). ### Check Existing Issues - [x] I have searched the existing issues and discussions. - [x] I am using the latest version of mcpo. ### mcpo Version 0.0.19 ### Open WebUI Version (if applicable) _No response_ ### Operating System macOS Sequoia ### Browser (if applicable) _No response_ ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** MCPO and Open WebUI. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have listed steps to reproduce the bug in detail. ### Expected Behavior A web browser would open initiating the OAuth flow. ### Actual Behavior Still a dynamic client registration seems to be performed. No OAuth flow is started. ### Steps to Reproduce 1. Configure mcpo using the following static client metadata (as Google does not support dynamic client registration) `{ "mcpServers": { "toolbox-mcp": { "type": "streamable-http", "url": "http://127.0.0.1:5000/mcp", "oauth": { "server_url": "https://accounts.google.com", "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth", "token_endpoint": "https://oauth2.googleapis.com/token", "storage_type": "file", "use_loopback": true, "callback_port": 3030, "client_metadata": { "client_name": "MySampleApp", "client_id": "101******.apps.googleusercontent.com", "client_secret": "GO******", "redirect_uris": ["http://localhost:3030/callback"], "scope": "openid email profile" } } } } }` 2. Launch the mcpo procy, using the above configuration, via: uvx mcpo@0.0.19 --config mcpoconfig.json 3. Add the tool to Open WebUI <img width="1094" height="627" alt="Image" src="https://github.com/user-attachments/assets/2f696ac6-454d-432d-b708-8e7070f5a393" /> 4. Trigger the tool. ### Logs & Screenshots Starting MCP OpenAPI Proxy with config file: mcpoconfig.json 2025-11-21 09:42:51,101 - INFO - Starting MCPO Server... 2025-11-21 09:42:51,101 - INFO - Name: MCP OpenAPI Proxy 2025-11-21 09:42:51,101 - INFO - Version: 1.0 2025-11-21 09:42:51,101 - INFO - Description: Automatically generated API from MCP Tool Schemas 2025-11-21 09:42:51,101 - INFO - Hostname: *******.local 2025-11-21 09:42:51,101 - INFO - Port: 8000 2025-11-21 09:42:51,101 - INFO - API Key: Not Provided 2025-11-21 09:42:51,101 - INFO - CORS Allowed Origins: ['*'] 2025-11-21 09:42:51,102 - INFO - Path Prefix: / 2025-11-21 09:42:51,102 - INFO - Root Path: 2025-11-21 09:42:51,102 - INFO - Loading MCP server configurations from: mcpoconfig.json 2025-11-21 09:42:51,102 - INFO - Configuring MCP Servers: 2025-11-21 09:42:51,102 - INFO - Uvicorn server starting... INFO: Started server process [22387] INFO: Waiting for application startup. 2025-11-21 09:42:51,109 - INFO - Initiating connection for server: 'toolbox-mcp'... 2025-11-21 09:42:51,109 - INFO - OAuth configuration detected for server: toolbox-mcp 2025-11-21 09:42:51,112 - INFO - OAuth provider created for server: toolbox-mcp 2025-11-21 09:42:51,129 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 200 OK" 2025-11-21 09:42:51,129 - INFO - Negotiated protocol version: 2025-06-18 2025-11-21 09:42:51,130 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 202 Accepted" 2025-11-21 09:42:51,131 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 200 OK" 2025-11-21 09:42:51,132 - INFO - Successfully connected to 'toolbox-mcp'. 2025-11-21 09:42:51,132 - INFO - --- Server Startup Summary --- 2025-11-21 09:42:51,132 - INFO - Successfully connected to: 2025-11-21 09:42:51,132 - INFO - - toolbox-mcp 2025-11-21 09:42:51,132 - INFO - -------------------------- INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) INFO: 127.0.0.1:59644 - "OPTIONS /toolbox-mcp/openapi.json HTTP/1.1" 200 OK INFO: 127.0.0.1:59644 - "GET /toolbox-mcp/openapi.json HTTP/1.1" 200 OK INFO: 127.0.0.1:59644 - "GET /toolbox-mcp/openapi.json HTTP/1.1" 200 OK INFO: 127.0.0.1:59644 - "GET /toolbox-mcp/openapi.json HTTP/1.1" 200 OK INFO: 127.0.0.1:59696 - "OPTIONS /toolbox-mcp/find-profiles-by-skill HTTP/1.1" 200 OK 2025-11-21 09:51:35,787 - INFO - Calling endpoint: find-profiles-by-skill, with args: {'skillName': 'C#'} 2025-11-21 09:51:35,794 - INFO - HTTP Request: POST http://127.0.0.1:5000/mcp "HTTP/1.1 401 Unauthorized" 2025-11-21 09:51:35,909 - INFO - HTTP Request: GET https://accounts.google.com/.well-known/oauth-protected-resource "HTTP/1.1 404 Not Found" 2025-11-21 09:51:35,931 - INFO - HTTP Request: GET https://accounts.google.com/.well-known/oauth-authorization-server "HTTP/1.1 200 OK" 2025-11-21 09:51:35,961 - INFO - HTTP Request: POST https://accounts.google.com/register "HTTP/1.1 400 Bad Request" 2025-11-21 09:51:35,962 - ERROR - OAuth flow error Traceback (most recent call last): File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/oauth2.py", line 522, in async_auth_flow client_information = await handle_registration_response(registration_response) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/utils.py", line 234, in handle_registration_response raise OAuthRegistrationError(f"Registration failed: {response.status_code} {response.text}") mcp.client.auth.exceptions.OAuthRegistrationError: Registration failed: 400 <html lang="nl" dir=ltr><meta charset=utf-8><meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"><title>Error 400 (Bad Request)!!1</title><style nonce="jrmkwMbw87vCPldJ4EGIvQ">*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{color:#222;text-align:unset;margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px;}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}pre{white-space:pre-wrap;}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}</style><main id="af-error-container" role="main"><a href=//www.google.com><span id=logo aria-label=Google role=img></span></a><p><b>400.</b> <ins>That’s an error.</ins><p>The server cannot process the request because it is malformed. It should not be retried. <ins>That’s all we know.</ins></main> 2025-11-21 09:51:35,969 - ERROR - Failed to connect to MCP server 'Toolbox': ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) + Exception Group Traceback (most recent call last): | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcpo/main.py", line 567, in lifespan | async with client_context as (reader, writer, *_): | ^^^^^^^^^^^^^^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in __aexit__ | await self.gen.athrow(value) | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 480, in streamablehttp_client | async with anyio.create_task_group() as tg: | ~~~~~~~~~~~~~~~~~~~~~~~^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 781, in __aexit__ | raise BaseExceptionGroup( | "unhandled errors in a TaskGroup", self._exceptions | ) from None | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 411, in handle_request_async | await self._handle_post_request(ctx) | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 262, in _handle_post_request | async with ctx.client.stream( | ~~~~~~~~~~~~~~~~~^ | "POST", | ^^^^^^^ | ...<2 lines>... | headers=headers, | ^^^^^^^^^^^^^^^^ | ) as response: | ^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 214, in __aenter__ | return await anext(self.gen) | ^^^^^^^^^^^^^^^^^^^^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1583, in stream | response = await self.send( | ^^^^^^^^^^^^^^^^ | ...<4 lines>... | ) | ^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1629, in send | response = await self._send_handling_auth( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ...<4 lines>... | ) | ^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1675, in _send_handling_auth | raise exc | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1664, in _send_handling_auth | next_request = await auth_flow.asend(response) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/oauth2.py", line 522, in async_auth_flow | client_information = await handle_registration_response(registration_response) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/utils.py", line 234, in handle_registration_response | raise OAuthRegistrationError(f"Registration failed: {response.status_code} {response.text}") | mcp.client.auth.exceptions.OAuthRegistrationError: Registration failed: 400 <html lang="nl" dir=ltr><meta charset=utf-8><meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"><title>Error 400 (Bad Request)!!1</title><style nonce="jrmkwMbw87vCPldJ4EGIvQ">*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{color:#222;text-align:unset;margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px;}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}pre{white-space:pre-wrap;}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}</style><main id="af-error-container" role="main"><a href=//www.google.com><span id=logo aria-label=Google role=img></span></a><p><b>400.</b> <ins>That’s an error.</ins><p>The server cannot process the request because it is malformed. It should not be retried. <ins>That’s all we know.</ins></main> +------------------------------------ ERROR: + Exception Group Traceback (most recent call last): | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/starlette/routing.py", line 694, in lifespan | async with self.lifespan_context(app) as maybe_state: | ~~~~~~~~~~~~~~~~~~~~~^^^^^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in __aexit__ | await self.gen.athrow(value) | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcpo/main.py", line 438, in lifespan | async with AsyncExitStack() as stack: | ~~~~~~~~~~~~~~^^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 768, in __aexit__ | raise exc | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 751, in __aexit__ | cb_suppress = await cb(*exc_details) | ^^^^^^^^^^^^^^^^^^^^^^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in __aexit__ | await self.gen.athrow(value) | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcpo/main.py", line 567, in lifespan | async with client_context as (reader, writer, *_): | ^^^^^^^^^^^^^^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 235, in __aexit__ | await self.gen.athrow(value) | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 480, in streamablehttp_client | async with anyio.create_task_group() as tg: | ~~~~~~~~~~~~~~~~~~~~~~~^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 781, in __aexit__ | raise BaseExceptionGroup( | "unhandled errors in a TaskGroup", self._exceptions | ) from None | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 411, in handle_request_async | await self._handle_post_request(ctx) | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 262, in _handle_post_request | async with ctx.client.stream( | ~~~~~~~~~~~~~~~~~^ | "POST", | ^^^^^^^ | ...<2 lines>... | headers=headers, | ^^^^^^^^^^^^^^^^ | ) as response: | ^ | File "/opt/homebrew/Cellar/python@3.13/3.13.9_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py", line 214, in __aenter__ | return await anext(self.gen) | ^^^^^^^^^^^^^^^^^^^^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1583, in stream | response = await self.send( | ^^^^^^^^^^^^^^^^ | ...<4 lines>... | ) | ^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1629, in send | response = await self._send_handling_auth( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ...<4 lines>... | ) | ^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1675, in _send_handling_auth | raise exc | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/httpx/_client.py", line 1664, in _send_handling_auth | next_request = await auth_flow.asend(response) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/oauth2.py", line 522, in async_auth_flow | client_information = await handle_registration_response(registration_response) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/Users/*************/.cache/uv/archive-v0/LCGc1p2kkXKfMqNpTMiyL/lib/python3.13/site-packages/mcp/client/auth/utils.py", line 234, in handle_registration_response | raise OAuthRegistrationError(f"Registration failed: {response.status_code} {response.text}") | mcp.client.auth.exceptions.OAuthRegistrationError: Registration failed: 400 <html lang="nl" dir=ltr><meta charset=utf-8><meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"><title>Error 400 (Bad Request)!!1</title><style nonce="jrmkwMbw87vCPldJ4EGIvQ">*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{color:#222;text-align:unset;margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px;}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}pre{white-space:pre-wrap;}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}</style><main id="af-error-container" role="main"><a href=//www.google.com><span id=logo aria-label=Google role=img></span></a><p><b>400.</b> <ins>That’s an error.</ins><p>The server cannot process the request because it is malformed. It should not be retried. <ins>That’s all we know.</ins></main> +------------------------------------ ### Additional Information My objective is to expose my MCP server, which is created with the MCP Toolbox for Databases (https://googleapis.github.io/genai-toolbox), as a tool in my Open WebUI via the mcpo proxy. The MCP server is configured with a BigQuery source and tool. I would like to pass the user context to the tool, executing the query on my BigQuery dataset. As Google does not seem to support dynamic OAuth client registration, I would like to configure the mcpo proxy using static client metadata. I expected with this configuration that a browser based OAuth flow would be initiated. However, if I understand correctly, the mcpo still tries to initiate a dynamic client registration and consequently fails. Is it possible to setup the mcpo proxy in such a way that a user-based OAuth flow is triggered and the access token resulting from the OAuth flow is passed to the MCP server? (My apologies if this question, or similar has been raised elsewhere).
yindo added the bug label 2026-02-15 21:15:00 -05:00
Author
Owner

@sonmaximum commented on GitHub (Jan 20, 2026):

Hi, I'm not involved in this project directly, but I was seemingly able to get the static registration to work locally at least by putting registration info in the file ~/.mcpo/tokens/<hash>_client.json where {hash} is the first eight hex digits of the MD5 of the connection name (so seemingly 8b7dc71c from toolbox-mcp in your case)

my {hash}_client.json file looks like

{
    "client_id": "<id>"
    "token_endpoint_auth_method": "none",
    "redirect_uris":  [
        "<uri>"
    ],
    "grant_types":  [
        "authorization_code",
        "refresh_code",
    ],
    "response_types":  [
        "code"
    ]
}

Dunno if this will help or not but maybe it will at least give you a place to follow up on?

@sonmaximum commented on GitHub (Jan 20, 2026): Hi, I'm not involved in this project directly, but I was seemingly able to get the static registration to work locally at least by putting registration info in the file `~/.mcpo/tokens/<hash>_client.json` where {hash} is the first eight hex digits of the MD5 of the connection name (so seemingly `8b7dc71c` from `toolbox-mcp` in your case) my {hash}_client.json file looks like ```json { "client_id": "<id>" "token_endpoint_auth_method": "none", "redirect_uris": [ "<uri>" ], "grant_types": [ "authorization_code", "refresh_code", ], "response_types": [ "code" ] } ``` Dunno if this will help or not but maybe it will at least give you a place to follow up on?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: open-webui/mcpo#126