/ adk-sock-shop / agents / tools.py
tools.py
 1  from collections import defaultdict
 2  import os
 3  import socket
 4  from typing import List, Sequence, Union
 5  from urllib.parse import urlparse
 6  
 7  from google.adk.tools.base_toolset import BaseToolset
 8  from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams
 9  from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
10  from mcp.client.stdio import StdioServerParameters
11  
12  
13  def _tcp_check(host: str, port: int) -> None:
14      """Fail fast if the MCP gateway is unreachable."""
15      try:
16          with socket.create_connection((host, port), timeout=5):
17              pass
18      except OSError as e:
19          raise RuntimeError(f"cannot reach {host}:{port}: {e}") from e
20  
21  
22  def create_mcp_toolsets(
23      tools_cfg: Sequence[str],
24  ) -> List[BaseToolset]:
25      """Return MCPToolset objects - let ADK handle async initialization naturally."""
26      if not tools_cfg:
27          return []
28  
29      tools_by_server: defaultdict[str, list[str]] = defaultdict(list)
30      for raw in tools_cfg:
31          if not raw.startswith("mcp/") or ":" not in raw:
32              raise ValueError(f"Bad MCP spec: {raw}")
33          server, tool = raw[4:].split(":", 1)
34          # Use just the tool name, not server:tool format
35          tools_by_server[server].append(tool)
36  
37      endpoint = os.environ["MCPGATEWAY_ENDPOINT"]
38      conn_params: Union[SseConnectionParams, StdioServerParameters]
39      if endpoint.startswith(("http://", "https://")):
40          parsed = urlparse(endpoint)
41          if not parsed.hostname:
42              raise ValueError("invalid MCP gateway URL")
43          host, port = parsed.hostname, parsed.port or 80
44          _tcp_check(host, port)
45          conn_params = SseConnectionParams(url=endpoint)
46      else:
47          host, port_str = endpoint.split(":")
48          _tcp_check(host, int(port_str))
49          conn_params = StdioServerParameters(
50              command="socat",
51              args=["STDIO", f"TCP:{endpoint}"],
52          )
53  
54      result: list[BaseToolset] = []
55      for tool_list in tools_by_server.values():
56          toolset = MCPToolset(connection_params=conn_params, tool_filter=tool_list)
57          result.append(toolset)
58  
59      return result