From cdaaaaf427c16d20665e0a7a9cfba3c9decee8ff Mon Sep 17 00:00:00 2001 From: arc53-machine <232052973+arc53-machine@users.noreply.github.com> Date: Mon, 28 Sep 2026 23:20:44 +0100 Subject: [PATCH] Prefer the configured MCP OAuth callback over the page's origin A page opened on a plain-HTTP address registered its own origin as the callback, which servers such as Linear refuse. MCP_OAUTH_REDIRECT_URI now wins when set; the page's value is the fallback. --- docsgpt/agents/tools/mcp_tool.py | 9 ++++++--- tests/agents/tools/test_mcp_tool.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docsgpt/agents/tools/mcp_tool.py b/docsgpt/agents/tools/mcp_tool.py index 6af9ac4d..c1d8a888 100644 --- a/docsgpt/agents/tools/mcp_tool.py +++ b/docsgpt/agents/tools/mcp_tool.py @@ -124,13 +124,16 @@ class MCPTool(Tool): raise ValueError(f"Invalid MCP server URL: {exc}") from exc def _resolve_redirect_uri(self, configured_redirect_uri: Optional[str]) -> str: - if configured_redirect_uri: - return configured_redirect_uri.rstrip("/") - + # The operator's setting wins over the page's own origin: a page opened + # on a plain-HTTP address would otherwise register a callback that + # servers such as Linear refuse. explicit = settings.MCP_OAUTH_REDIRECT_URI if explicit: return explicit.rstrip("/") + if configured_redirect_uri: + return configured_redirect_uri.rstrip("/") + connector_base = settings.CONNECTOR_REDIRECT_BASE_URI if connector_base: parsed = urlparse(connector_base) diff --git a/tests/agents/tools/test_mcp_tool.py b/tests/agents/tools/test_mcp_tool.py index d24da614..5eb30465 100644 --- a/tests/agents/tools/test_mcp_tool.py +++ b/tests/agents/tools/test_mcp_tool.py @@ -1277,6 +1277,30 @@ class TestResolveRedirectUriExtended: }) assert tool.redirect_uri == "https://custom.redirect/callback" + def test_setting_wins_over_the_redirect_the_page_sends(self, monkeypatch): + from docsgpt.core.settings import settings + + # A page opened on a plain-HTTP address sends its own origin; the + # operator's HTTPS callback is the one servers accept. + monkeypatch.setattr(settings, "MCP_OAUTH_REDIRECT_URI", "https://docs.example.com/api/mcp_server/callback") + tool = _make_tool({ + "server_url": "https://mcp.example.com", + "auth_type": "none", + "redirect_uri": "http://10.0.0.5:7091/api/mcp_server/callback", + }) + assert tool.redirect_uri == "https://docs.example.com/api/mcp_server/callback" + + def test_page_redirect_used_without_the_setting(self, monkeypatch): + from docsgpt.core.settings import settings + + monkeypatch.setattr(settings, "MCP_OAUTH_REDIRECT_URI", None, raising=False) + tool = _make_tool({ + "server_url": "https://mcp.example.com", + "auth_type": "none", + "redirect_uri": "https://app.example.com/api/mcp_server/callback/", + }) + assert tool.redirect_uri == "https://app.example.com/api/mcp_server/callback" + def test_connector_redirect_base_uri_setting(self, monkeypatch): from docsgpt.core.settings import settings