Article #3 of Navigating the AI Agent Landscape: A Developer’s Guide to A2A, ADK, and MCP
This article marks the third episode in our series exploring the foundational protocols shaping the AI agent ecosystem. Our previous discussions introduced the Agent-to-Agent (A2A) protocol for seamless inter-agent communication and clarified the distinct yet complementary roles of A2A, the Model Context Protocol (MCP), and the Agent Development Kit (ADK)This article explores the MCP, demonstrating how it empowers individual AI agents to interact with the external world of tools and data.
This article provides a code-centric guide for developers looking to integrate MCP capabilities within agents built using Agent Development Kit (ADK). Our exploration is anchored around a practical use case: building a Financial Advisory Agent that connects to an MCP server to access real-time market data — all within a structured, agent-driven workflow.
MCP is an open protocol that standardizes how applications pass contextual information to large language models (LLMs). Similar to how USB-C offers a unified interface for connecting hardware across devices, MCP provides a consistent, interoperable interface for integrating LLMs with various data sources, APIs, and tools — simplifying context injection and reducing integration complexity.
MCP operates on a client-host-server architecture :
MCP Servers primarily expose three types of primitives :
Communication within MCP uses JSON-RPC 2.0 messages over various transport mechanisms, including standard input/output (stdio) for local processes and HTTP with Server-Sent Events (SSE) for remote connections.
Imagine a financial advisor or an individual investor aiming to:
Manually gathering and analyzing this information can be time-consuming and prone to error. Our Automated Financial Advisory Agent aims to streamline these operations by providing an AI agent capable of interacting directly with financial data sources and performing calculations. This agent, built with Google’s Agent Development Kit (ADK), leverages the Model Context Protocol (MCP) to access these capabilities.
Specifically, it integrates with the Financial Datasets MCP Server, which provides tools to:
This use case is particularly powerful because it lays the groundwork for future multi-agent collaboration. Once our Financial Advisory Agent can access and process financial data, it can then collaborate with other specialized agents via Agent-to-Agent (A2A) communication to tackle more complex financial planning workflows.
A common pattern when integrating the Model Context Protocol (MCP) with Google’s Agent Development Kit (ADK)is to configure your ADK agent as an MCP client — consuming capabilities exposed by external MCP-compliant servers. For our Automated Financial Advisory Agent, this setup enables seamless access to structured financial data, such as stock prices, financial statements, and market news.
To get started, clone the official financial-datasets/mcp-server
repository
mkdir articles
cd articles
mkdir article3
cd article3
mkdir mcp-pattern1
cd mcp-pattern1
git clone https://github.com/financial-datasets/mcp-server
cd mcp-server
Create and activate a virtual environment:
cd articles/article3
python3 -m venv .venv # Create a virtual environment named .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install required packages:
pip install "mcp[cli]" httpx
Copy the .env.example file to .env file. Add the API key (Sign up and get a free API key from https://www.financialdatasets.ai/ for free) to the .env file
FINANCIAL_DATASETS_API_KEY=your-financial-datasets-api-key
Run the MCP server:
python server.py
Once the server is running, you should see a message like:
financial-datasets-mcp - INFO - Starting Financial Datasets MCP Server...
This means the server is ready to accept JSON-RPC requests from any MCP-compatible client, including your ADK agent.
Now, here’s how to set up the ADK agent (agent.py) to connect to this financial data server. You can either run the code is from Github or follow along in this notebook.
Step 0: Prerequisites
Open a new terminal (leave the mcp-server running on the first terminal). Create a separate folder for the client code and activate the virtual env
cd articles/article3/mcp-pattern1
source mcp-server/.venv/bin/activate
mkdir mcp-client
Install ADK
pip install google-adk
GCP Project: If you are using VertexAI on GCP, make sure to set up a project in GCP and install gcloud
pip install gcloud
Step 1: Configurations
Create a .env file (Or copy .env.example available in the Github repo to .env). This is critical for API Keys and configuration.
#.env content
GOOGLE_API_KEY=YOUR_GEMINI_API_KEY
GOOGLE_GENAI_USE_VERTEXAI = SET THIS TO FALSE IF YOU ARE USING API KEY AND TRUE OTHERWISE
GOOGLE_CLOUD_PROJECT=YOUR_GCP_PROJECT_ID
GOOGLE_CLOUD_LOCATION=YOUR_GCP_PROJECT_LOCATION
Add .env to your .gitignore file immediately! Never commit secrets
Create the file __init__.py in the folder mcp-client with contents:
from . import agent
Step 2: Import Required Libraries and Tools
Import all necessary modules including ADK’s LlmAgent
, MCPToolset
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
Step 3: Define the External Financial Server Path
Set the path to your financial data server script and define how the agent will launch it.
Note: We will be running this code from mcp-pattern1 folder and hence the provided folder structure.
FINANCIAL_SERVER_SCRIPT_PATH = os.path.abspath("mcp-server/server.py")
print(f"Financial Advisory Agent connecting to: {FINANCIAL_SERVER_SCRIPT_PATH}")
MCP_COMMAND = 'python' # Assumes the server is a Python script
MCP_ARGS = [
FINANCIAL_SERVER_SCRIPT_PATH
]
Step 4: Create the Root Agent and Attach the MCP Tool
Define an LlmAgent
and attach a filtered MCPToolset
that only allows specific tools to be used by the agent.
root_agent = LlmAgent(
model='gemini-2.0-flash',
name='financial_advisor_agent',
instruction=(
'You are an automated financial advisor. '
'You can retrieve real-time stock prices, historical financial statements, and company news. '
'Use the available tools to answer questions about financial markets and companies.'
),
tools=[
MCPToolset(
connection_params=StdioServerParameters(
command=MCP_COMMAND,
args=MCP_ARGS,
),
tool_filter=['get_current_stock_price', 'get_company_news'] # Expose only specific tools
)
]
)
Note: The tool_filter
lets you explicitly specify which tools the agent is allowed to use. This is a subset of all tools exposed by the server and provides a layer of control — perfect for limiting capabilities
Step 5: Run the Agent
Once your agent is defined, you can run it and verify that it connects successfully to the external financial data server.
If you are running on VertexAI in GCP, authenticate to gcloud before running the script
cd articles/article3/mcp-pattern1
gcloud auth login --update-adc
gcloud config set project <YOUR-PROJECT_ID>
gcloud auth application-default set-quota-project <YOUR-PROJECT_ID>
Now run the script
adk run mcp-client
Sample output
/articles/article3/mcp-pattern1$ adk run mcp-client/
Log setup complete: /tmp/agents_log/agent.20250527_022609.log
To access latest log: tail -F /tmp/agents_log/agent.latest.log
Financial Advisory Agent connecting to: articles/article3/mcp-pattern1/mcp-server/server.py
Running agent financial_advisor_agent, type exit to exit.
[user]: what is the price of MSFT
2025-05-27 02:26:17,574 - financial-datasets-mcp - INFO - Starting Financial Datasets MCP Server...
2025-05-27 02:26:17,591 - mcp.server.lowlevel.server - INFO - Processing request of type ListToolsRequest
2025-05-27 02:26:17,602 - financial-datasets-mcp - INFO - Starting Financial Datasets MCP Server...
2025-05-27 02:26:19,370 - mcp.server.lowlevel.server - INFO - Processing request of type CallToolRequest
2025-05-27 02:26:20,161 - httpx - INFO - HTTP Request: GET https://api.financialdatasets.ai/prices/snapshot/?ticker=MSFT "HTTP/1.1 200 OK"
2025-05-27 02:26:20,167 - mcp.server.lowlevel.server - INFO - Processing request of type ListToolsRequest
[financial_advisor_agent]: The current price of MSFT is 450.18.
Let’s make sure the values are right!
Let’s get some company news, this time, that of Google!
[user]: What is the news for GOOGL?
2025-05-27 02:35:07,491 - mcp.server.lowlevel.server - INFO - Processing request of type ListToolsRequest
2025-05-27 02:35:09,230 - mcp.server.lowlevel.server - INFO - Processing request of type CallToolRequest
2025-05-27 02:35:09,715 - httpx - INFO - HTTP Request: GET https://api.financialdatasets.ai/news/?ticker=GOOGL "HTTP/1.1 200 OK"
2025-05-27 02:35:09,862 - mcp.server.lowlevel.server - INFO - Processing request of type ListToolsRequest
[financial_advisor_agent]: Here's the latest news about GOOGL:
* **Alphabet Gets Vote of Confidence After Google I/O**
* **Why Alphabet Stock Was Rising Again Today**
* **Renaissance Hedge Fund’s Biggest Q1 Buys Revealed**
* **The Rise of Multimodal AI Market: A $4.5 billion Industry Dominated by Tech Giants - Google (US), Microsoft (US), OpenAI (US) | MarketsandMarkets™**
* **Google Just Won the AI Race. Here's Everything Investors Should Know About the Recent Announcements.**
[user]: exit
In this pattern, we transform a standalone ADK tool — like a Celsius-to-Fahrenheit converter — into a reusable, network-accessible tool. Rather than embedding the tool within a specific agent, we expose it through a custom MCP server
This setup allows the ADK tool to be accessed by any MCP-compatible agent or application, promoting interoperability, modularity, and clean separation of concerns. The MCP server handles tool discovery and execution via standard methods like list_tools()
and call_tool()
.
cd articles/article3
source .venv/bin/activate
mkdir mcp-pattern2
cd mcp-pattern2
mkdir mcp-server
Install required packages:
pip install mcp
Step 1: Import Required Libraries
Import all the necessary modules from both the MCP SDK and the ADK in the file unit_converter_server.py
import asyncio
import json
import os
# MCP Server Imports
from mcp import types as mcp_types
from mcp.server.lowlevel import Server, NotificationOptions
from mcp.server.models import InitializationOptions
import mcp.server.stdio
# ADK Tool Imports
from google.adk.tools.function_tool import FunctionTool
# ADK <-> MCP Conversion Utility
from google.adk.tools.mcp_tool.conversion_utils import adk_to_mcp_tool_type
from typing import Dict, Any, List
Step 2: Define the ADK Tool to Be Exposed
We’ll define a simple convert_celsius_to_fahrenheit
function and wrap it using ADK’s FunctionTool
.
# --- Define the custom unit conversion tool ---
async def convert_celsius_to_fahrenheit(celsius: float) -> str:
"""
Converts a temperature from Celsius to Fahrenheit.
Args:
celsius: The temperature in Celsius.
Returns:
The temperature in Fahrenheit as a formatted string.
"""
fahrenheit = (celsius * 9/5) + 32
return f"{celsius}C is {fahrenheit:.2f}F."
# Wrap with FunctionTool
print("Initializing ADK 'convert_celsius_to_fahrenheit' tool...")
adk_tool_to_expose = FunctionTool(convert_celsius_to_fahrenheit)
print(f"ADK tool '{adk_tool_to_expose.name}' initialized and ready to be exposed via MCP.")
Step 3: Create the MCP Server and Register Tool Handlers
Set up the MCP server and implement handlers to list and call the tool via the MCP interface.
# Create MCP Server instance
print("Creating MCP Server instance...")
app = Server("adk-unit-conversion-mcp-server")
# Handler to list tools
@app.list_tools()
async def list_mcp_tools() -> list[mcp_types.Tool]:
print("MCP Server: Received list_tools request.")
mcp_tool_schema = adk_to_mcp_tool_type(adk_tool_to_expose)
return [mcp_tool_schema]
# Handler to call a tool
@app.call_tool()
async def call_mcp_tool(name: str, arguments: dict) -> list[mcp_types.TextContent]:
print(f"MCP Server: Received call_tool request for '{name}' with args: {arguments}")
if name == adk_tool_to_expose.name:
try:
response = await adk_tool_to_expose.run_async(tool_context=None, args=arguments)
return [mcp_types.TextContent(type="text", text=response)]
except Exception as e:
return [mcp_types.TextContent(type="text", text=f"Failed to execute tool '{name}': {str(e)}")]
else:
return [mcp_types.TextContent(type="text", text=f"Tool '{name}' not implemented by this server.")]
Step 4: Start the MCP Server over StdIO
Use stdio_server()
to run the server locally and listen for requests over standard input/output.
async def run_mcp_stdio_server():
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
print("MCP Stdio Server: Starting handshake with client...")
await app.run(
read_stream,
write_stream,
InitializationOptions(
server_name=app.name,
server_version="0.1.0",
capabilities=app.get_capabilities(
notification_options=NotificationOptions(),
experimental_capabilities={},
),
),
)
Step 5: Launch the Server
Add an if __name__ == "__main__"
block to start the server when the script is executed.
if __name__ == "__main__":
print("Launching MCP Server to expose ADK tools via stdio...")
try:
asyncio.run(run_mcp_stdio_server())
except KeyboardInterrupt:
print("\nMCP Server (stdio) stopped by user.")
except Exception as e:
print(f"MCP Server (stdio) encountered an error: {e}")
finally:
print("MCP Server (stdio) process exiting.")
Step 6: Start the Server
python unit_converter_server.py
Once the server is running, you should see a message like:
Initializing ADK 'convert_celsius_to_fahrenheit' tool...
ADK tool 'convert_celsius_to_fahrenheit' initialized and ready to be exposed via MCP.
Creating MCP Server instance...
Launching MCP Server to expose ADK tools via stdio...
MCP Stdio Server: Starting handshake with client...
This means the server is ready to accept JSON-RPC requests from any MCP-compatible client, including your ADK agent.
Once your MCP server is running and exposing the tool, any other ADK agent (or compatible client) can access it using the MCPToolset
. You can either run the code from Github or follow along in this notebook.
Prerequisites
Open a new terminal (leave the unit_converter_server running on the first terminal). Create a separate folder for the client code.
cd articles/article3/
source .venv/bin/activate
cd mcp-pattern2
mkdir mcp-client
GCP Project: If you are using VertexAI on GCP, make sure to set up a project in GCP and install gcloud
pip install gcloud
Create .env file
Create a .env file (Or copy .env.example available in the Github repo to .env). This is critical for API Keys and configuration.
#.env content
GOOGLE_API_KEY=YOUR_GEMINI_API_KEY
GOOGLE_GENAI_USE_VERTEXAI = SET THIS TO FALSE IF YOU ARE USING API KEY AND TRUE OTHERWISE
GOOGLE_CLOUD_PROJECT=YOUR_GCP_PROJECT_ID
GOOGLE_CLOUD_LOCATION=YOUR_GCP_PROJECT_LOCATION
Add .env to your .gitignore file immediately! Never commit secrets
Create __init__py
Create the file __init__.py in the folder mcp-client with contents:
from . import agent
Define the Client Agent
You’ll use LlmAgent
and configure it with MCPToolset
to connect to the tool hosted on your custom MCP server.
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
# Set path to the script running your custom MCP server
UNIT_CONVERTER_SERVER_PATH = os.path.abspath("mcp-server/unit_converter_server.py")
print(f"Unit Converter Agent connecting to: {UNIT_CONVERTER_SERVER_PATH}")
# Configure how to launch the server
MCP_COMMAND = 'python' # Command to run the Python server script
MCP_ARGS = [
UNIT_CONVERTER_SERVER_PATH
]
# Set up the ADK agent that will use the external tool
root_agent = LlmAgent(
model='gemini-2.0-flash',
name='unit_conversion_agent',
instruction=(
'You are a helpful unit conversion assistant. '
'You can convert temperatures from Celsius to Fahrenheit. '
'Use the available tools to perform unit conversions.'
),
tools=[
MCPToolset(
connection_params=StdioServerParameters(
command=MCP_COMMAND,
args=MCP_ARGS,
),
tool_filter=['convert_celsius_to_fahrenheit']
)
]
)
Run the Agent
Once your agent is defined, you can run it and verify that it connects successfully to the unit_converter_server
If you are running on VertexAI in GCP, authenticate to gcloud before running the script
cd articles/article3/mcp-pattern2
gcloud auth login --update-adc
gcloud config set project YOUR_GCP_PROJECT_ID
gcloud auth application-default set-quota-project YOUR_GCP_PROJECT_ID
Now run the script
adk run mcp-client
Sample output
Log setup complete: /tmp/agents_log/agent.20250527_054459.log
To access latest log: tail -F /tmp/agents_log/agent.latest.log
Unit Converter Agent connecting to: articles/article3/mcp-pattern2/mcp-server/unit_converter_server.py
Running agent unit_conversion_agent, type exit to exit.
[user]: what is 34 degree celsius in Farenheit
[unit_conversion_agent]: 34 degrees Celsius is 93.20 degrees Fahrenheit.
This is what Google Search says!
When building AI agents that interface with external tools, APIs, or data sources — especially via MCP — security is a critical concern. MCP is intentionally lightweight and protocol-agnostic, meaning it does not include built-in security enforcement. It’s entirely up to developers to implement protections at the agent, host, and tool levels.
In this article, we focused on extending a single ADK agent’s capabilities — connecting it to external tools via MCP and exposing custom ADK-built functionality through an MCP server. These patterns lay the foundation for scalable, interoperable AI systems.
But in real-world deployments, agents often need to collaborate, not just integrate.
They need to share context, negotiate responsibilities, and adapt to dynamic workflows — not as isolated components, but as intelligent participants in a larger system.
And Thank you for reading! Feel free to connect and reach out on LinkedIn to share feedback, questions and what you build with ADK and A2A