Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

MCP x ADK - Engineering Agents That Execute, Not Just Predict

laxmih
Staff

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.

A Quick Refresher: MCP Core Concepts

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 :

  • Host: The AI application or agent environment (e.g., an IDE, a desktop AI app, or an ADK agent) that orchestrates interactions, manages clients, and enforces security policies.
  • Client: Resides within the Host and maintains a dedicated, one-to-one connection with an MCP server, mediating communication.
  • Server: A lightweight program exposing specific functionalities (data, tools, or prompts) via MCP primitives, connecting to local systems or remote services.

MCP Servers primarily expose three types of primitives :

  • Tools: Server-exposed, executable functions that large language models (LLMs) can invoke to interact with external systems. These tools enable LLMs to perform actions such as querying databases, calling APIs, or executing computations, thereby extending their capabilities beyond static data retrieval. Each tool is uniquely identified and includes metadata describing its schema, facilitating seamless integration and dynamic operations.
  • Resources: Read-only, addressable content entities that provide structured, contextual data to the AI model for reasoning, like log files or configuration data.
  • Prompts: Reusable templates that servers expose to clients, enabling standardized interactions with LLM. These prompts can accept dynamic arguments, incorporate contextual data from resources, and guide specific workflows, facilitating consistent and efficient LLM operations.

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.

TL;DR

laxmih_0-1749075912754.png

Use Case: The Automated Financial Advisory

Imagine a financial advisor or an individual investor aiming to:

  • Retrieve real-time stock prices and historical data.
  • Access a company’s income statements, balance sheets, and cash flow statements.
  • Perform quick financial calculations, like debt-to-equity ratios or return on investment.
  • Stay updated on market news.

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:

  • Retrieve income statements, balance sheets, and cash flow statements for companies.
  • Obtain current and historical stock prices.
  • Access company news.
  • and many others …

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.

Pattern 1: Equipping the Financial Advisor Agent with Market Data (ADK as an MCP Client)

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.

Setting Up the Financial MCP Server

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
 Set Up Your Python Environment & Install Dependencies

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
Configure Environment Variables

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
Start the Server

Run the MCP server:

python server.py
Testing the MCP Financial Data Server

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.

Create an Agent to Connect to the Financial Data Server

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

  • .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.

  • Add the necessary variables. In this tutorial we are using Gemini 2.0. Get a key for free from https://aistudio.google.com/apikey. If you are using Vertex AI on GCP, get the project name and location.
#.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

  • __init__py

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!

laxmih_1-1749076801040.png

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

Pattern 2: Exposing ADK Tools via a Custom MCP Server

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().

Step 0: Environment Setup and Configurations
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.

Create an Agent to Connect to the Unit Converter Server

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.

  • Add the necessary variables. In this tutorial we are using Gemini 2.0. Get a key for free from https://aistudio.google.com/apikey. If you are using Vertex AI on GCP, get the project name and location.
#.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!

laxmih_2-1749077326851.png

Security Considerations for MCP-Connected AI Agents

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.

Common Risk Areas in Tool-Integrated Agent Systems
  • Tool Poisoning
    Malicious content embedded in tool descriptions or response formats can influence model behavior, potentially causing incorrect or harmful actions.
  • Sensitive Data Exposure
    Tools may accidentally access or leak private information if not properly scoped or isolated — especially in multi-tenant or shared memory environments.
  • Unauthorized Access
    Without authentication controls, any process or user may connect to a local MCP server, potentially accessing privileged tools or data.
  • Local Server Vulnerabilities
    Stdio-based servers can inherit user-level access. Without sandboxing, they may unintentionally expose local files or network resources.
Recommended Mitigation Strategies
  • Principle of Least Privilege
    Limit what each agent, tool, and server can access. Only expose what is strictly required for the task.
  • Authentication & Authorization
    Use token-based systems (like OAuth or signed API keys) to control who can initiate MCP connections or access tools.
  • Input Validation
    Sanitize all tool inputs — especially those coming from untrusted sources — to guard against prompt injection or code manipulation.
  • Secrets Management
    Never hardcode API keys or tokens in code. Use environment variables or secure vault systems to manage credentials safely.
  • Secure Communication
    For remote connections, always use TLS to encrypt traffic between agents and MCP servers. Validate connection origins.
  • Logging & Monitoring
    Maintain detailed logs of all agent-tool interactions. This is essential for traceability, debugging, and detecting abuse or anomalies.

TL;DR

laxmih_3-1749077718326.png

Looking Ahead: Beyond the Single-Agent Use Case

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 

0 0 155
Authors