From 64bffadf2d4ce00d151425a80bcc76d4c9700f1b Mon Sep 17 00:00:00 2001 From: White-Mouse <15983334+White-Mouse@users.noreply.github.com> Date: Wed, 10 Jun 2026 01:05:03 +0800 Subject: [PATCH] fix(mcp): preserve Google auth token-sharing policy --- src/google/adk/tools/mcp_tool/mcp_tool.py | 10 ------- src/google/adk/tools/mcp_tool/mcp_toolset.py | 10 ------- .../unittests/tools/mcp_tool/test_mcp_tool.py | 27 +++++++++++++++++-- .../tools/mcp_tool/test_mcp_toolset.py | 23 +++++++++++++++- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/google/adk/tools/mcp_tool/mcp_tool.py b/src/google/adk/tools/mcp_tool/mcp_tool.py index 4acc4ff847..359cded357 100644 --- a/src/google/adk/tools/mcp_tool/mcp_tool.py +++ b/src/google/adk/tools/mcp_tool/mcp_tool.py @@ -18,7 +18,6 @@ import base64 import inspect import logging -import os from typing import Any from typing import Callable from typing import Dict @@ -179,15 +178,6 @@ def __init__( ValueError: If mcp_tool or mcp_session_manager is None. """ - # --- BEGIN BOUND TOKEN PATCH --- - # Set GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES to false - # to disable bound token sharing. Tracking on - # https://github.com/google/adk-python/issues/5361 - os.environ["GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES"] = ( - "false" - ) - # --- END BOUND TOKEN PATCH --- - super().__init__( name=mcp_tool.name, description=mcp_tool.description if mcp_tool.description else "", diff --git a/src/google/adk/tools/mcp_tool/mcp_toolset.py b/src/google/adk/tools/mcp_tool/mcp_toolset.py index 6d3ccf7c65..faf615c7d0 100644 --- a/src/google/adk/tools/mcp_tool/mcp_toolset.py +++ b/src/google/adk/tools/mcp_tool/mcp_toolset.py @@ -17,7 +17,6 @@ import asyncio import base64 import logging -import os import sys from typing import Any from typing import Awaitable @@ -161,15 +160,6 @@ def __init__( in a credential service. Used with auth_scheme. """ - # --- BEGIN BOUND TOKEN PATCH --- - # Set GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES to false - # to disable bound token sharing. Tracking on - # https://github.com/google/adk-python/issues/5361 - os.environ["GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES"] = ( - "false" - ) - # --- END BOUND TOKEN PATCH --- - super().__init__(tool_filter=tool_filter, tool_name_prefix=tool_name_prefix) self._sampling_callback = sampling_callback diff --git a/tests/unittests/tools/mcp_tool/test_mcp_tool.py b/tests/unittests/tools/mcp_tool/test_mcp_tool.py index 6643547df9..01898782f2 100644 --- a/tests/unittests/tools/mcp_tool/test_mcp_tool.py +++ b/tests/unittests/tools/mcp_tool/test_mcp_tool.py @@ -12,12 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import inspect +import os from unittest.mock import AsyncMock from unittest.mock import create_autospec from unittest.mock import Mock from unittest.mock import patch +from google.auth import _agent_identity_utils from google.adk.agents.context import Context from google.adk.auth.auth_credential import AuthCredential from google.adk.auth.auth_credential import AuthCredentialTypes @@ -32,7 +33,6 @@ from google.adk.tools.mcp_tool.mcp_tool import MCPTool from google.adk.tools.tool_context import ToolContext from google.genai.types import FunctionDeclaration -from google.genai.types import Type from mcp.types import CallToolResult from mcp.types import TextContent import pytest @@ -204,6 +204,29 @@ def test_init_basic(self): assert tool._mcp_tool == self.mock_mcp_tool assert tool._mcp_session_manager == self.mock_session_manager + def test_init_preserves_agent_identity_bound_token_opt_in( + self, monkeypatch + ): + """MCPTool construction should not disable process-wide bound tokens.""" + env_name = "GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES" + fake_cert = object() + monkeypatch.setenv(env_name, "true") + monkeypatch.setattr( + _agent_identity_utils, + "_is_agent_identity_certificate", + lambda cert: True, + ) + + assert _agent_identity_utils.should_request_bound_token(fake_cert) + + MCPTool( + mcp_tool=self.mock_mcp_tool, + mcp_session_manager=self.mock_session_manager, + ) + + assert os.environ[env_name] == "true" + assert _agent_identity_utils.should_request_bound_token(fake_cert) + def test_init_with_auth(self): """Test initialization with authentication.""" # Create real auth scheme instances instead of mocks diff --git a/tests/unittests/tools/mcp_tool/test_mcp_toolset.py b/tests/unittests/tools/mcp_tool/test_mcp_toolset.py index 20ec612e8c..3878203e9c 100644 --- a/tests/unittests/tools/mcp_tool/test_mcp_toolset.py +++ b/tests/unittests/tools/mcp_tool/test_mcp_toolset.py @@ -14,7 +14,7 @@ import asyncio import base64 -from io import StringIO +import os import pickle import sys from unittest.mock import AsyncMock @@ -22,6 +22,7 @@ from unittest.mock import Mock from fastapi.openapi.models import OAuth2 +from google.auth import _agent_identity_utils from google.adk.agents.readonly_context import ReadonlyContext from google.adk.auth.auth_credential import AuthCredential from google.adk.auth.auth_credential import AuthCredentialTypes @@ -89,6 +90,26 @@ def test_init_basic(self): assert toolset._auth_credential is None assert toolset._use_mcp_resources is False + def test_init_preserves_agent_identity_bound_token_opt_in( + self, monkeypatch + ): + """McpToolset construction should not disable process-wide bound tokens.""" + env_name = "GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES" + fake_cert = object() + monkeypatch.setenv(env_name, "true") + monkeypatch.setattr( + _agent_identity_utils, + "_is_agent_identity_certificate", + lambda cert: True, + ) + + assert _agent_identity_utils.should_request_bound_token(fake_cert) + + McpToolset(connection_params=self.mock_stdio_params) + + assert os.environ[env_name] == "true" + assert _agent_identity_utils.should_request_bound_token(fake_cert) + def test_init_with_use_mcp_resources(self): """Test initialization with use_mcp_resources.""" toolset = McpToolset(