From 135b4c8b351cda70da89868b9bc1a78bbbb8cf33 Mon Sep 17 00:00:00 2001 From: vominh1919 Date: Sun, 26 Apr 2026 19:52:03 +0700 Subject: [PATCH] fix(mcp): decouple AnyUrl import from mcp dependency AnyUrl was imported inside the same try block as mcp.client.auth, so when the mcp package was not installed, AnyUrl was undefined and _build_client_metadata raised NameError at runtime. Moved the AnyUrl import to its own try/except block so it's available whenever pydantic is installed (which is a core dependency), regardless of whether the mcp SDK is present. Also added pytest.importorskip('mcp') to the three test_build_client_metadata tests that exercise _build_client_metadata, since that function depends on OAuthClientMetadata from the mcp package. --- tests/tools/test_mcp_oauth.py | 3 +++ tools/mcp_oauth.py | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/tools/test_mcp_oauth.py b/tests/tools/test_mcp_oauth.py index db0342e993..319620e412 100644 --- a/tests/tools/test_mcp_oauth.py +++ b/tests/tools/test_mcp_oauth.py @@ -440,6 +440,7 @@ class TestBuildOAuthAuthNonInteractive: def test_build_client_metadata_basic(): """_build_client_metadata returns metadata with expected defaults.""" + pytest.importorskip("mcp") from tools.mcp_oauth import _build_client_metadata, _configure_callback_port cfg = {"client_name": "Test Client"} @@ -453,6 +454,7 @@ def test_build_client_metadata_basic(): def test_build_client_metadata_without_secret_is_public(): """Without client_secret, token endpoint auth is 'none' (public client).""" + pytest.importorskip("mcp") from tools.mcp_oauth import _build_client_metadata, _configure_callback_port cfg = {} @@ -463,6 +465,7 @@ def test_build_client_metadata_without_secret_is_public(): def test_build_client_metadata_with_secret_is_confidential(): """With client_secret, token endpoint auth is 'client_secret_post'.""" + pytest.importorskip("mcp") from tools.mcp_oauth import _build_client_metadata, _configure_callback_port cfg = {"client_secret": "shh"} diff --git a/tools/mcp_oauth.py b/tools/mcp_oauth.py index 51e243c6c1..80dacdc420 100644 --- a/tools/mcp_oauth.py +++ b/tools/mcp_oauth.py @@ -53,7 +53,7 @@ logger = logging.getLogger(__name__) # Lazy imports -- MCP SDK with OAuth support is optional # --------------------------------------------------------------------------- -_OAUTH_AVAILABLE = False +_OAUTH_AVAILABLE=False try: from mcp.client.auth import OAuthClientProvider from mcp.shared.auth import ( @@ -61,12 +61,16 @@ try: OAuthClientMetadata, OAuthToken, ) - from pydantic import AnyUrl - _OAUTH_AVAILABLE = True + _OAUTH_AVAILABLE=True except ImportError: logger.debug("MCP OAuth types not available -- OAuth MCP auth disabled") +try: + from pydantic import AnyUrl +except ImportError: + AnyUrl = None # type: ignore[assignment, misc] + # --------------------------------------------------------------------------- # Exceptions