| [ Web Proxy ] |
| Viewing: https://adk.dev/integrations/../../live/../tutorials/../../live/../../../../tools-custom/mcp-tools/ | [Back] [Original] |
[logo]
The Model Context Protocol (MCP) is an open standard for connecting generative AI models to external data sources, tools, and systems. Think of it as a universal connection mechanism that simplifies how LLMs obtain context, execute actions, and interact with various systems.
MCP follows a client-server architecture, defining how data or resources, interactive templates or prompts, and actionable functions or tools are exposed by an MCP server and consumed by an MCP client, which could be an LLM host application or an AI agent. In ADK, you use the McpToolset class as an interface between MCP Servers and ADK agents. It is also possible to configure an ADK server as an MCP server for use by other client systems.
sequenceDiagram
autonumber
participant Agent as ADK LlmAgent (Client)
participant Toolset as McpToolset
participant Server as MCP Server
Agent->>Toolset: Initialize connection
Toolset->>Server: Protocol Handshake & Tool Discovery (list_tools)
Server-->>Toolset: Available Tool Schemas
Toolset-->>Agent: Adapted ADK Tools
Agent->>Toolset: Call Tool (arguments)
Toolset->>Server: Execute Tool (call_tool via Stdio/HTTP)
Server-->>Toolset: Execution Result (Text/JSON)
Toolset-->>Agent: Result returned to LLM
Before you begin, ensure you have the following set up:
pip install "google-adk[mcp]".npx (Python/TS only): Required to run npm-packaged community MCP servers.adk and npx are in your PATH in the activated virtual environment:Deployment rule
Agents deployed to production must define McpToolset synchronously in agent.py. Dynamic asynchronous agent initialization is only supported for local debugging or custom standalone runners.
There are three main integration patterns. The direct integration is covered in this page and the other implementations are covered in their specific pages.
McpToolset.to_mcp_server.AgentTool.When you start building with the Model Context Protocol (MCP) and ADK, these key architectural differences will help you design more stable and efficient agents. The following table works as a comparative guide to help you construct those agents.
| Dimension | Direct MCP Tool Integration (McpToolset) |
Agent-Exposed MCP Server (to_mcp_server) |
Specialized Sub-Agent Delegation (AgentTool) |
|---|---|---|---|
| Architecture | External server process or remote service providing deterministic endpoints adapted into the primary LlmAgent tool list. |
An autonomous ADK agent compiled into an MCP server, callable by external clients (Claude Code, IDEs, external hosts). | In-process, hierarchical agent encapsulation where a parent agent invokes a child LlmAgent as a callable tool. |
| Context Window Impact | High Context Bloat: Every tool definition and raw output, for example: database rows or file blobs, enters the primary agent's history. | Isolated: The external caller only receives the final aggregated response text/blocks. | Zero Context Bloat: Intermediate exploratory reasoning, failed tool calls, and large raw outputs remain isolated in the sub-agent loop. |
| AI Model Load and Tiering | Single model must understand all tool schemas, validation constraints, and workflow state simultaneously. | Independent model reasoning dedicated solely to the wrapped task. | Enables model tiering, for example: gemini-2.5-pro for orchestrator, and gemini-2.5-flash for sub-agent tool execution with dedicated system instructions. |
| Latency & Token Cost | Lower Cost & Predictable Latency: 1 LLM turn + 1 deterministic tool invocation + 1 response generation turn. | Client-driven; latency depends on internal agent execution depth. | Higher Cost & Variable Latency: Multiple LLM calls, sub-agent reasoning turns before returning to parent. |
| Ideal Use Cases |
|
|
|
State restoration
While ADK agents preserve session state during lifecycle events, they do not automatically re-establish active MCP connections upon restoration. Agents re-initialize connections as needed.
The McpToolset class can be directly added to your agent's tools list; this class enables seamless connection to an MCP server, discovery of its tools, and making them available for your agent to use. On initialization, McpToolset establishes and manages the connection to the MCP server. It also handles graceful connection shutdown when the agent or process terminates.
Use McpToolset to import tools from an external MCP server into your ADK LlmAgent.
This example sets up an ADK agent that connects to a local MCP file system server; it instantiates the McpToolset directly within the agent's tools list to enable file management capabilities.
Step 1. Define your agent with McpToolset:
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from mcp import StdioServerParameters
TARGET_FOLDER = os.path.abspath("./accessible_files")
root_agent = LlmAgent(
model="gemini-flash-latest",
name="filesystem_assistant",
instruction="Help users manage local files.",
tools=[
McpToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", TARGET_FOLDER],
),
),
# Optional: Select specific tools exposed to the agent
tool_filter=["list_directory", "read_file"],
)
],
)
Step 2: Package and Run your Agent to make your agent discoverable to ADK and start interacting with it, follow this workflow:
__init__.py file in the same directory as your agent.py. This step is required for ADK to recognize your agent.Launch the Web Interface:
Interact with the Agent: select filesystem_assistant from the drop-down menu and prompt the Agent with commands: List files in the current directory or What is the content of another_file.md?
import { LlmAgent, MCPToolset } from "@google/adk";
import path from "path";
const TARGET_FOLDER = path.resolve("./accessible_files");
export const rootAgent = new LlmAgent({
model: "gemini-flash-latest",
name: "filesystem_assistant",
instruction: "Help users manage local files.",
tools: [
new MCPToolset({
type: "StdioConnectionParams",
serverParams: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", TARGET_FOLDER],
},
}, ["list_directory", "read_file"]) // Optional tool filter array
],
});
package agents;
import com.google.adk.agents.LlmAgent;
import com.google.adk.tools.mcp.McpToolset;
import com.google.adk.tools.mcp.StdioServerParameters;
import java.util.List;
public class FileSystemAgentCreator {
public static void main(String[] args) throws Exception {
StdioServerParameters serverParams = StdioServerParameters.builder()
.command("npx")
.args(List.of("-y", "@modelcontextprotocol/server-filesystem", "/absolute/path/to/folder"))
.build();
try (McpToolset toolset = new McpToolset(serverParams.toServerParameters())) {
LlmAgent agent = LlmAgent.builder()
.model("gemini-flash-latest")
.name("filesystem_assistant")
.instruction("Help users access their file systems.")
.tools(toolset)
.build();
System.out.println("Agent initialized: " + agent.name());
}
}
}
package main
import (
"context"
"fmt"
"os/exec"
"github.com/modelcontextprotocol/go-sdk/mcp"
"google.golang.org/adk/v2/agent"
"google.golang.org/adk/v2/agent/llmagent"
"google.golang.org/adk/v2/model/gemini"
"google.golang.org/adk/v2/tool"
"google.golang.org/adk/v2/tool/mcptoolset"
)
func createFilesystemAgent(ctx context.Context) (agent.Agent, error) {
// 1. Initialize MCP Toolset with CommandTransport and AllowedToolsPredicate
mcpTools, err := mcptoolset.New(mcptoolset.Config{
Transport: &mcp.CommandTransport{
Command: exec.Command("npx", "-y", "@modelcontextprotocol/server-filesystem", "./accessible_files"),
},
ToolFilter: tool.AllowedToolsPredicate([]string{"list_directory", "read_file"}),
})
if err != nil {
return nil, fmt.Errorf("failed to create mcp toolset: %w", err)
}
// 2. Initialize Gemini model.LLM instance
llm, err := gemini.NewModel(ctx, "gemini-2.0-flash", nil)
if err != nil {
return nil, fmt.Errorf("failed to create gemini model: %w", err)
}
// 3. Create the LLM agent returning agent.Agent
return llmagent.New(llmagent.Config{
Name: "filesystem_assistant",
Model: llm,
Instruction: "Help users manage local files.",
Toolsets: []tool.Toolset{mcpTools},
})
}
func main() {
ctx := context.Background()
ag, err := createFilesystemAgent(ctx)
if err != nil {
panic(err)
}
fmt.Printf("Successfully created agent: %s\n", ag.Name())
}
Before starting, follow the instructions for Google Maps Grounding Lite to enable the service on your Google Cloud project and generate your Maps Platform API Key. Unlike the previous local process example, this pattern connects your agent to a remote, cloud-hosted MCP server using Server-Sent Events (SSE). It uses the Google Maps Grounding Lite service to demonstrate how to pass authentication headers, such as an API key, to a scalable endpoint.
Step 1: Define your agent with McpToolset.
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
API_KEY = os.getenv("GOOGLE_MAPS_API_KEY")
root_agent = LlmAgent(
model="gemini-flash-latest",
name="travel_planner",
instruction="Plan travel routes and search locations using Google Maps.",
tools=[
McpToolset(
connection_params=StreamableHTTPConnectionParams(
url="https://mapstools.googleapis.com/mcp",
headers={
"X-Goog-Api-Key": API_KEY,
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
},
timeout=5,
sse_read_timeout=300
)
)
],
)
adk web, set you Google API key in your terminal
Step 3: Run adk web: Navigate to the parent directory of mcp_agent and launch the web Interface.
Step 4: Interact with the UI:
- Select travel_planner from the drop-down.
- Try prompts such as: I will be in San Francisco tomorrow. What's the weather like or Find coffee shops near Golden Gate Park
```typescript import { LlmAgent, MCPToolset } from "@google/adk";
export const rootAgent = new LlmAgent({ model: "gemini-flash-latest", name: "travel_planner", instruction: "Plan travel routes and search locations using Google Maps.", tools: [ new MCPToolset({ type: "StreamableHTTPConnectionParams", url: "https://mapstools.googleapis.com/mcp", transportOptions: { requestInit: { headers: { "X-Goog-Api-Key": process.env.GOOGLE_MAPS_API_KEY!, "Content-Type": "application/json", "Accept": "application/json, text/event-stream", }, }, }, timeout: 5, sseReadTimeout: 300, }), ], }); ```
This section shows you how to connect to remote MCP servers using authentication and how to read data Resources exposed by an MCP server. When an MCP server requires authentication, such as over Server-Sent Events SseConnectionParams or Streamable HTTP, McpToolset handles credential injection and token management automatically.
| Parameter | Type | Description |
|---|---|---|
auth_scheme |
AuthScheme |
The authentication strategy (e.g., Bearer, Basic, APIKey, OAuth2). |
auth_credential |
AuthCredential |
The secret credential payload, for example, API token, OAuth access token, username/password. |
ADK automatically constructs the required Authorization HTTP headers and manages OAuth 2.0 token refreshes during client requests.
When an MCP server requires authentication, McpToolset handles credential injection and token management automatically. Use the native auth_scheme and auth_credential parameters rather than manually injecting HTTP headers.
For general ADK authentication patterns, see our Custom Tools Authentication Guide
import os
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams
# Configure Bearer Token Authentication via headers
toolset = McpToolset(
connection_params=SseConnectionParams(
url="https://mcp-server.example.com/sse",
headers={"Authorization": f"Bearer {os.getenv('MCP_AUTH_TOKEN')}"},
timeout=5,
)
)
import { MCPToolset } from "@google/adk";
// Configure Bearer Token Authentication via headers
const toolset = new MCPToolset({
type: "StreamableHTTPConnectionParams",
url: "https://mcp-server.example.com/sse",
transportOptions: {
requestInit: {
headers: {
"Authorization": `Bearer ${process.env.MCP_AUTH_TOKEN}`,
},
},
},
timeout: 5,
});
In addition to executable Tools, MCP servers can expose Resources data files, database records, or API context blobs.
McpToolset provides two core methods to discover and read these data resources:
list_resources(): Returns a list of all available data resources exposed by the MCP server.read_resource(name): Retrieves the raw content blocks, text or binary data, for a specific resource by its name or URI.use_mcp_resources=True (Configuration): When initializing McpToolset, setting this flag automatically equips the LLM agent with the LoadMcpResourceTool. This allows the agent to dynamically discover and read resources on its own without requiring manual programmatic fetching. import asyncio
async def fetch_mcp_data(toolset):
# 1. Discover available resources on the server
resources = await toolset.list_resources()
print("Available Resources:", resources)
# 2. Read content from a specific resource
if resources:
resource_name = resources[0]
content_blocks = await toolset.read_resource(name=resource_name)
print(f"Content of {resource_name}:", content_blocks)
async function fetchMcpData(toolset: any) {
// 1. Discover available resources
const resources = await toolset.listResources();
console.log("Available Resources:", resources);
// 2. Read a specific resource
if (resources.length > 0) {
const content = await toolset.readResource(resources[0]);
console.log(`Content of ${resources[0]}:`, content);
}
}
tool_filter=[...] in McpToolset to expose only necessary actions to your LLM.StdioConnectionParams(timeout=5) to prevent hanging subprocesses.adk web runners, invoke await toolset.close() or use async context managers to gracefully shutdown subprocesses.K_SERVICE for Cloud Run vs Stdio for local dev.import os
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import (
StdioConnectionParams,
StreamableHTTPConnectionParams,
)
from mcp import StdioServerParameters
if os.getenv("K_SERVICE"):
# Running in Production (Cloud Run)
# Uses Streamable HTTP for stateless scalability and bearer auth headers
mcp_toolset = McpToolset(
connection_params=StreamableHTTPConnectionParams(
url=os.getenv("REMOTE_MCP_URL"),
headers={"Authorization": f"Bearer {os.getenv('MCP_AUTH_TOKEN')}"},
timeout=5,
sse_read_timeout=300,
)
)
else:
# Running in Local Development
# Uses Stdio Subprocess IPC for zero-network latency testing
mcp_toolset = McpToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
),
timeout=5,
)
)
Once you understand the basics, explore Advanced use cases for complex implementations and custom integrations.
| Web Proxy Viewer | New URL | Original Page |