Python ADK + MCP Gemini
A practical implementation demonstrating ADK (Agent Development Kit) as an MCP (Model Context Protocol) client for flight search capabilities. This project showcases asynchronous integration between ADK's LlmAgent and an external MCP server, featuring dynamic tool discovery, stateful session management, and structured function calling. Powered by Google's Gemini model, it implements proper resource handling and event-driven architecture for a robust, extensible assistant.
- Introduction to ADK and MCP
- Architecture
- Features
- Core Concepts
- Implementation Steps
- Getting Started Guide
- Project Structure
- Key Considerations for Integration
- Troubleshooting
- Official Documentation References
- Repository
- Author
This project showcases the integration of two powerful Google technologies:
- Agent Development Kit (ADK): An open-source, code-first Python toolkit for building intelligent AI agents
- Model Context Protocol (MCP): A standardized protocol for AI models to interact with external tools
In this implementation, ADK acts as the MCP Client, connecting to an MCP Server that provides flight search capabilities.
The Flight Search Assistant follows a streamlined request flow that combines the power of Google Gemini, ADK, and MCP to process user queries and provide intelligent responses.
- Google Gemini 2 as LLM
- Agent Development Kit (ADK) as Agent
- Model Context Protocol (MCP)
- SerpAPI for Search
- Python 3.8+
- Google Gemini 2
Powers conversational AI and context-aware interactions. - Agent Development Kit (ADK)
Manages conversation flow and tool orchestration. - Model Context Protocol (MCP)
Handles secure tool operations and external API calls. - SerpAPI
Provides access to real-time flight data.
- ADK as MCP Client Integration - Seamless connection between ADK agent and MCP server using
MCPToolset
- Dynamic Tool Discovery - Automatic detection and integration of MCP server capabilities
- Asynchronous Event Processing - Event-driven architecture with ADK's Runner for non-blocking operations
- Stateful Sessions - Conversation context management with
InMemorySessionService
- Structured Tool Invocation - Type-safe function calling through MCP protocol
- Clean Resource Management - Proper connection lifecycle handling with exit stacks
Agent Development Kit (ADK) is an open-source, code-first Python toolkit for building, evaluating, and deploying intelligent AI agents. ADK enables developers to create agentic workflows β from simple single-agent tasks to complex multi-agent orchestration β all within a modular and extensible framework.
An Agent is an autonomous, self-contained execution unit designed to achieve specific goals. Agents can:
- Perform tasks
- Interact with users
- Leverage external tools
- Collaborate with other agents to complete complex workflows
ADK offers three primary agent types:
-
LLM Agents (e.g., LlmAgent, Agent):
- Use LLMs to understand, reason, plan, and act
- Ideal for dynamic, language-driven tasks
-
Workflow Agents (e.g., SequentialAgent, ParallelAgent, LoopAgent):
- Orchestrate other agents in predictable patterns
- Don't rely on an LLM for flow control
- Best for structured, repeatable processes
-
Custom Agents:
- Built by extending BaseAgent
- Enable custom logic, specialized workflows, or unique tool integrations
- Perfect for advanced, tailor-made solutions
In this project, we're using LLM Agents with MCPTools.
A Tool represents a specific capability granted to an AI agent, allowing it to perform actions and interact with the external world beyond basic text generation and reasoning. A tool is usually a modular code component β such as a Python function, class method, or even another agent β designed to carry out a defined task.
Agents dynamically leverage tools through function-calling mechanisms, where the LLM:
- Reasons over context
- Selects and invokes the appropriate tool with generated inputs
- Observes the result
- Integrates the output into its next action or response
ADK supports several types of tools:
-
Function Tools: Custom tools built specifically for your application's unique logic
- Functions/Methods: Standard synchronous Python functions or class methods
- Agents-as-Tools: Specialized agents as callable tools within a parent agent
- Long-Running Function Tools: Tools for asynchronous or time-intensive operations
-
Built-in Tools: Predefined tools included in the framework (web search, code execution, RAG)
-
Third-Party Tools: Integrations from popular ecosystems like LangChain or CrewAI
In this project, ADK serves as an MCP Client that connects to an MCP Server (mcp-flight-search
). This connection allows the ADK agent to discover and use tools exposed by the MCP server to search for flights.
- Python 3.8+ installed
- Google Gemini Generative AI access via API key
- A valid SerpAPI key (used to fetch live flight data)
# Setup virtual environment (Mac or Unix)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install google-adk # Agent Development Kit
pip install mcp-flight-search # MCP server
pip install google-generativeai python-dotenv # GenAI Python SDK
Set Environment variables:
# Note: ADK uses GOOGLE_API_KEY instead of GEMINI_API_KEY
export GOOGLE_API_KEY="your-google-api-key"
export SERP_API_KEY="your-serpapi-key"
To enable Gemini to interact with real-world APIs, we use an MCP-compliant server. For this project, we use mcp-flight-search β a lightweight MCP Server built using FastMCP which exposes a tool that searches real-time flight data using SerpAPI.
Verify that the MCP server is properly installed:
pip show mcp-flight-search
# --- Step 1: Get tools from MCP server ---
async def get_tools_async():
"""Gets tools from the Flight Search MCP Server."""
print("Attempting to connect to MCP Flight Search server...")
server_params = StdioServerParameters(
command="mcp-flight-search",
args=["--connection_type", "stdio"],
env={"SERP_API_KEY": os.getenv("SERP_API_KEY")},
)
tools, exit_stack = await MCPToolset.from_server(
connection_params=server_params
)
print("MCP Toolset created successfully.")
return tools, exit_stack
# --- Step 2: Define ADK Agent Creation ---
async def get_agent_async():
"""Creates an ADK Agent equipped with tools from the MCP Server."""
tools, exit_stack = await get_tools_async()
print(f"Fetched {len(tools)} tools from MCP server.")
# Create the LlmAgent
root_agent = LlmAgent(
model=os.getenv("GEMINI_MODEL", "gemini-2.5-pro-preview-03-25"),
name='flight_search_assistant',
instruction='Help user to search for flights using available tools based on prompt. If return date not specified, use an empty string for one-way trips.',
tools=tools,
)
return root_agent, exit_stack
async def async_main():
# Create services
session_service = InMemorySessionService()
# Create a session
session = session_service.create_session(
state={}, app_name='flight_search_app', user_id='user_flights'
)
# Define the user prompt
query = "Find flights from Atlanta to Las Vegas 2025-05-05"
print(f"User Query: '{query}'")
# Format input as types.Content
content = types.Content(role='user', parts=[types.Part(text=query)])
# Get agent and exit_stack
root_agent, exit_stack = await get_agent_async()
# Create Runner
runner = Runner(
app_name='flight_search_app',
agent=root_agent,
session_service=session_service,
)
print("Running agent...")
events_async = runner.run_async(
session_id=session.id,
user_id=session.user_id,
new_message=content
)
# Process events
async for event in events_async:
print(f"Event received: {event}")
# Always clean up resources
print("Closing MCP server connection...")
await exit_stack.aclose()
print("Cleanup complete.")
Example user query:
"Find flights from Atlanta to Las Vegas 2025-05-05"
Here's a demonstration of the flight search assistant in action:
git clone https://github.com/arjunprabhulal/adk-python-mcp-client.git
cd adk-python-mcp-client
Set up a Python virtual environment and install dependencies:
# Setup virtual environment (Mac or Unix)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install all dependencies from requirements.txt
pip install -r requirements.txt
Create and configure your environment variables:
# Copy the example environment file
cp .env.example .env
# Edit the .env file with your actual API keys
# Replace placeholders with your actual keys:
# GOOGLE_API_KEY=your-actual-google-api-key
# SERP_API_KEY=your-actual-serpapi-key
Run the client script to start the application:
python client.py
The application will:
- Connect to the MCP Flight Search server
- Initialize the ADK agent with your Gemini API key
- Process the default flight query or your custom query
- Display the conversation events and final results
adk-python-mcp-client/
βββ Images/
β βββ adk-mcp-client-log.gif # Standard logging demo animation
β βββ adk-mcp-client-debug.gif # Debug mode demo animation
β βββ image.png # Architecture diagram
βββ client.py # ADK client implementation
βββ README.md # Project documentation
βββ requirements.txt # Dependencies
βββ .env.example # Environment variables template
βββ .env # Environment variables (not tracked by Git)
-
MCP vs. ADK
- MCP is an open protocol that standardizes how AI models interact with external tools and data sources
- ADK is a Python-based framework for building and deploying AI agents
- MCPToolset bridges MCP and ADK by enabling ADK agents to consume tools exposed by MCP servers
-
Tool Types and Integration
- ADK Tools: Python objects designed for direct use within ADK agents
- MCP Tools: Capabilities exposed by MCP servers, adapted by MCPToolset for use within ADK agents
- Third-Party Tools: Libraries like LangChain and CrewAI offer tools that can be integrated
-
Asynchronous Architecture
- Both ADK and the MCP Python library are built on Python's asyncio framework
- Tool implementations and server handlers should be asynchronous (async def) to ensure non-blocking operations
-
Stateful Sessions in MCP
- MCP establishes persistent, stateful connections between clients and servers
- This statefulness allows for context retention across interactions but requires careful session management
-
Deployment Considerations
- The persistent nature of MCP connections can pose challenges for scaling and deployment
- Infrastructure considerations include load balancing and session affinity
-
Managing MCP Connections in ADK
- MCPToolset manages the lifecycle of MCP connections within ADK
- Using an exit_stack ensures connections are properly terminated when execution completes
-
API Key Issues:
- ADK expects
GOOGLE_API_KEY
instead ofGEMINI_API_KEY
- If you encounter
ValueError: Missing key inputs argument!
, check that you're using the correct environment variable - Error message:
ValueError: Missing key inputs argument! To use the Google AI API, provide (api_key) arguments. To use the Google Cloud API, provide (vertexai, project & location) arguments.
- ADK expects
-
Rate Limiting:
- You may encounter 429 rate-limit errors:
google.genai.errors.ClientError: 429 RESOURCE_EXHAUSTED
- Consider implementing retries with exponential backoff
- You may encounter 429 rate-limit errors:
-
MCP Connection Issues:
- Ensure the MCP server is properly installed and accessible
- Check that your SerpAPI key is correctly configured
-
Internal Server Errors:
- You may occasionally see 500 internal server errors from the Gemini API
- These can often be resolved by retrying the request after a short delay
For more detailed information about ADK and MCP, refer to the official documentation:
-
Agent Development Kit (ADK) Documentation - Complete guide to the open-source AI agent framework integrated with Gemini and Google.
-
LLM Agents in ADK - Detailed documentation on implementing LLM Agents, including defining identity, instructions, tools, and advanced configuration.
-
MCP Tools with ADK - Specific guidance on using ADK as an MCP client to connect to MCP servers.
This project is available on GitHub at arjunprabhulal/adk-python-mcp-client.
Created by Arjun Prabhulal. For more articles on AI/ML and Generative AI, follow Arjun Prabhulal on Medium.