Building AI Agents with Google ADK and MCP: A Complete Guide
1. What is ADK & MCP?
Agent Development Kit (ADK)
ADK is Google's open-source framework designed to simplify the development and deployment of AI agents. Think of it as a toolkit that makes building intelligent agents feel more like traditional software development.
Key Features:
- Model-Agnostic: Works with Gemini, GPT, Claude, and other LLMs
- Deployment-Agnostic: Deploy locally, on Cloud Run, Kubernetes, or Vertex AI
- Built-in Tools: Supports web search, code execution, and custom tools
- Production-Ready: v1.0.0 stable release for Python (Java v0.1.0 also available)
- Agent Orchestration: Built-in support for multi-agent systems
- Session Management: State management across interactions
Model Context Protocol (MCP)
MCP is an open standard created by Anthropic that standardizes how AI models interact with external tools, data sources, and systems. It's a universal interface that eliminates the need for custom integrations.
Architecture:
- Client-Server Model: MCP Clients (AI agents) communicate with MCP Servers (tool providers)
- Three Core Components:
- Resources: Data sources and information
- Prompts: Interactive templates
- Tools: Actionable functions
Key Differences:
- MCP: A protocol specification (communication rules)
- ADK: A Python framework/library (development toolkit)
- MCPToolset: Bridges MCP and ADK by implementing the client side within ADK
2. MCP Example: Building a Currency Exchange Server
Let's create a simple MCP server that provides currency exchange rates.
from fastmcp import FastMCP
import httpx
# Create MCP server
mcp = FastMCP("Currency Exchange Server")
@mcp.tool()
async def get_exchange_rate(
from_currency: str,
to_currency: str,
amount: float = 1.0
) -> dict:
"""
Get current exchange rate between two currencies.
Args:
from_currency: Source currency code (e.g., USD)
to_currency: Target currency code (e.g., EUR)
amount: Amount to convert (default: 1.0)
"""
# Call Frankfurter API for real exchange rates
async with httpx.AsyncClient() as client:
response = await client.get(
f"https://api.frankfurter.app/latest",
params={
"from": from_currency,
"to": to_currency,
"amount": amount
}
)
data = response.json()
return {
"from": from_currency,
"to": to_currency,
"amount": amount,
"converted": data["rates"][to_currency],
"rate": data["rates"][to_currency] / amount
}
# Run the server
if __name__ == "__main__":
mcp.run()
3. Agent Example: Building a Simple Weather Agent
Here's how to create a basic ADK agent with built-in tools:
from google.adk.agents import LlmAgent
from google.adk.tools import FunctionTool
from google.adk.models.lite_llm import LiteLlm
# Define a custom tool
def get_weather(city: str) -> dict:
"""
Get weather information for a city.
Args:
city: Name of the city
"""
# Simulated weather data
return {
"city": city,
"temperature": "22°C",
"condition": "Sunny",
"humidity": "65%"
}
# Create the agent
weather_agent = LlmAgent(
name="WeatherBot",
description="A helpful weather assistant",
model=LiteLlm(model_id="gemini/gemini-2.0-flash-exp"),
instructions="""
You are a friendly weather assistant. When users ask about weather,
use the get_weather tool to fetch information and present it in a
helpful, conversational manner.
""",
tools=[FunctionTool(get_weather)]
)
# Export for ADK CLI
root_agent = weather_agent
4. MCP & ADK Combined: YouTube Search Agent
This example shows ADK acting as an MCP client to use external tools:
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import MCPToolset, StdioServerParameters
from google.adk.models.lite_llm import LiteLlm
import os
# Create MCP toolset connecting to YouTube search server
mcp_tools = MCPToolset.from_server(
connection_params=StdioServerParameters(
command="npx",
args=["-y", "mcp-youtube-search"],
env={
"YOUTUBE_API_KEY": os.getenv("YOUTUBE_API_KEY")
}
)
)
# Create agent with MCP tools
youtube_agent = LlmAgent(
name="YouTubeAssistant",
description="Search and find YouTube videos",
model=LiteLlm(model_id="gemini/gemini-2.0-flash-exp"),
instructions="""
You help users find relevant YouTube videos. Use the search tool
to find videos based on user queries, and present the results
in an organized, helpful manner.
""",
tools=[mcp_tools]
)
root_agent = youtube_agent
5. Tools in ADK
ADK supports multiple types of tools to extend agent capabilities:
Built-in Tools
- Web Search: Search the web for information
- Code Execution: Execute Python code safely
- RAG Tools: Retrieval-Augmented Generation
Custom Tools
- FunctionTool: Wrap Python functions
- AgentTool: Use another agent as a tool
- LongRunningFunctionTool: For async operations
Third-Party Integration
- LangchainTool: Wrap LangChain tools
- CrewaiTool: Integrate CrewAI tools
- MCPToolset: Connect to any MCP server
MCP Toolbox for Databases
Special mention to MCP Toolbox for Databases, which provides secure access to:
- BigQuery: SQL execution, schema discovery, forecasting
- AlloyDB: PostgreSQL queries, natural language queries
- Cloud SQL: MySQL, PostgreSQL, SQL Server support
- Spanner: Distributed database access
6. Agent-to-Agent Communication (A2A)
The Agent2Agent (A2A) Protocol is an open standard enabling agents to communicate across different frameworks and platforms.
Key Concepts
Agent Card: Metadata describing an agent's capabilities
from google.adk.a2a import AgentCard, AgentSkill
agent_card = AgentCard(
name="DataAnalyzer",
url="http://localhost:8001",
version="1.0.0",
skills=[
AgentSkill(
id="analyze_data",
name="Data Analysis",
description="Analyze datasets and provide insights",
examples=["Analyze sales data", "Find trends in user behavior"]
)
]
)
A2A Example: Travel Planning System
from google.adk.agents import LlmAgent
from google.adk.tools.agent_tool import RemoteA2aAgent
from google.adk.models.lite_llm import LiteLlm
# Define specialized agents
flight_agent = RemoteA2aAgent(
name="FlightAgent",
url="http://localhost:8001"
)
hotel_agent = RemoteA2aAgent(
name="HotelAgent",
url="http://localhost:8002"
)
# Create orchestrator agent
travel_planner = LlmAgent(
name="TravelOrchestrator",
description="Coordinates travel planning",
model=LiteLlm(model_id="gemini/gemini-2.0-flash-exp"),
instructions="""
You are a travel planning coordinator. Use the FlightAgent to find
flights and HotelAgent to book hotels. Coordinate between them to
create complete travel plans.
""",
tools=[flight_agent, hotel_agent]
)
root_agent = travel_planner
A2A Architecture
7. Orchestrating Agents: Multi-Agent Systems
Agent orchestration involves coordinating multiple specialized agents to solve complex problems.
Orchestration Patterns
1. Sequential Workflow
2. Parallel Processing
3. Conditional Routing
Complete Orchestration Example: InstaVibe Social Platform
from google.adk.agents import LlmAgent
from google.adk.tools.agent_tool import RemoteA2aAgent
from google.adk.tools.mcp_tool import MCPToolset, StdioServerParameters
from google.adk.models.lite_llm import LiteLlm
# Define remote A2A agents
social_profiling_agent = RemoteA2aAgent(
name="SocialProfiler",
url="http://localhost:8001"
)
event_planning_agent = RemoteA2aAgent(
name="EventPlanner",
url="http://localhost:8002"
)
# MCP tool for platform interaction
platform_mcp_tools = MCPToolset.from_server(
connection_params=StdioServerParameters(
command="node",
args=["instavibe-mcp-server.js"]
)
)
# Create orchestrator
orchestrator = LlmAgent(
name="InstaVibeOrchestrator",
description="Coordinates social activity planning",
model=LiteLlm(model_id="gemini/gemini-2.5-pro-exp"),
instructions="""
You orchestrate a multi-agent system for social planning:
1. Use SocialProfiler to analyze user interests and connections
2. Use EventPlanner to find suitable activities
3. Use platform MCP tools to interact with InstaVibe API
Coordinate these agents to create personalized social experiences.
""",
tools=[
social_profiling_agent,
event_planning_agent,
platform_mcp_tools
]
)
root_agent = orchestrator
Multi-Agent Workflow
Advanced Orchestration: Loops and Conditionals
orchestrator = LlmAgent(
name="SmartOrchestrator",
instructions="""
Orchestrate agents with complex logic:
WHILE task not complete:
IF needs_research:
Use research_agent
ELIF needs_analysis:
Use data_analyst_agent
ELIF needs_execution:
Use action_agent
Evaluate result
Adjust strategy if needed
Return comprehensive solution
""",
tools=[research_agent, analyst_agent, action_agent]
)
Deployment Architecture
Understanding the Complete Workflow
Agent Lifecycle
Learning Path: From Simple to Complex
Level 1: Single Agent with Function Tools
What You Learn:
- Basic agent structure
- Function tool creation
- Prompt engineering
- Tool invocation
Level 2: Agent with MCP Tools
What You Learn:
- MCP protocol basics
- Client-server architecture
- External tool integration
- Async operations
Level 3: Multi-Agent with A2A
What You Learn:
- Agent orchestration
- A2A protocol
- Distributed systems
- Complex workflows
How Data Flows Through the System
MCP Communication Deep Dive
A2A Agent Discovery and Communication
Core Concepts Explained
1. Agent Instructions: The Brain
Instructions are how you program agent behavior:
instructions="""
You are a data analyst assistant.
PROCESS:
1. Understand the user's analytical question
2. Determine what data is needed
3. Use available tools to gather data
4. Analyze the results
5. Present findings clearly with visualizations when helpful
RULES:
- Always validate data before analysis
- If data is insufficient, ask for clarification
- Provide context with your numbers
- Use tools when you need current information
"""
Key Principles:
- Clear Identity: Who is the agent?
- Process Flow: How should it think?
- Rules & Constraints: What are the boundaries?
- Tool Usage Guidelines: When to use what?
2. Tool Execution Flow
3. Session Management
4. Orchestration Decision Making
Best Practices for Learning
1. Start Simple
# First: Single function tool
agent = LlmAgent(
name="Calculator",
tools=[FunctionTool(add), FunctionTool(multiply)]
)
2. Progress Gradually
# Then: MCP integration
agent = LlmAgent(
name="WebSearcher",
tools=[MCPToolset.from_server(...)]
)
3. Build Complexity
# Finally: Multi-agent orchestration
orchestrator = LlmAgent(
name="Orchestrator",
tools=[
RemoteA2aAgent(name="Agent1", url="..."),
RemoteA2aAgent(name="Agent2", url="..."),
MCPToolset.from_server(...)
]
)
4. Debug Effectively
# Use ADK's built-in UI for testing
adk web
# Monitor tool execution
# Enable verbose logging
# Test each component independently
5. Understand State
- Sessions maintain conversation context
- State can be shared between tools
- Each agent can have its own state
- Orchestrators coordinate stateful interactions
Conclusion
Google's ADK combined with MCP and A2A protocols provides a comprehensive ecosystem for building intelligent, collaborative AI agents. Key takeaways:
-ADK simplifies agent development with intuitive Python code
-MCP standardizes how agents connect to external tools and data
-A2A enables agents to communicate across different frameworks
-Orchestration allows complex multi-agent workflows
-Production-Ready with Vertex AI integration and enterprise features
The future of AI is not just intelligent agents, but intelligent agents working together.