The primary goal of this project is to deepen my understanding of Agent Development principles, the application of the Model Context Protocol in practice, and how to integrate its tools and services into an AI Agent for enhanced abilities beyond the training data.
This project is largely inspired by Santiago Valdarrama's tutorial on YouTube:
- Key Technologies
- Project Structure
- Project Setup and Installation
- Screenshots & Usage
- Code Deep Dive (
agent.py
) - Video Demonstration
- Author
- License
The Google Agent Development Kit (ADK) is a Python framework designed to simplify the development of AI Agents powered by LLMs. It provides access to tools, memory, agent orchestration and LLMs from providers like OpenAI, Anthropic, Cohere and many others through integration with the LiteLlm
library. The ADK also includes a web UI for interacting with and debugging agents.
Opik is an open-source observability solution for LLM applications, built by Comet. It allows you to trace, visualize, and debug the interactions within your AI Agents, including LLM calls, tool usage, and other operations. In this project, Opik is configured to send traces to CometML, providing a rich UI to inspect agent behavior.
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to LLMs and connect them to different data sources and tools. It defines a schema for tool descriptions, invocations, and responses. This allows for interoperability between different LLM systems and tool providers.
The Google Maps MCP Server is a Node.js application that exposes Google Maps Platform APIs as MCP tools. This allows an ADK Agent to easily leverage Google Maps features to deliver more relevant, context-aware responses.
- How it runs: The ADK's
MCPToolset
can automatically start this server usingnpx
if it's not already running, as configured in this project. - Main Tools Exposed:
maps_directions
: Get driving, walking, or cycling directions.maps_geocode
: Convert addresses to geographic coordinates.maps_reverse_geocode
: Convert geographic coordinates to addresses.maps_elevation
: Get elevation for a given coordinate.maps_search_places
: Search for places (e.g., restaurants, landmarks).maps_place_details
: Get detailed information about a specific place.maps_distance_matrix
: Calculate travel time and distance between multiple origins and destinations.
.
├── assets
│ └── screenshots
│ ├── interface.png
│ ├── maps_direction_tool_input_output.png
│ ├── maps_direction_tool_opik.png
│ ├── maps_direction_tool.png
│ ├── maps_directions_tool_events.png
│ ├── maps_elevation_tool.png
│ ├── maps_place_details_event.png
│ ├── maps_reverse_geocode_event.png
│ ├── opik_overall_input_output.png
| ├── adk.png
| ├── mcp.png
│ └── opik_traces.png
├── examples
│ └── agent_conversation.yaml
├── LICENSE
├── mcp_agent
│ ├── __init__.py
│ └── agent.py
├── pyproject.toml
├── README.md
└── uv.lock
- Python 3.11
- uv (Python package and virtual environment manager)
- Node.js and npm / npx (required to run the Google Maps MCP Server, which the ADK will start via
npx
) - A Google Maps Platform API Key?
- An OpenAI API Key.
- CometML API Key, Project ID, and Workspace.
-
Clone the repository:
git clone https://github.com/luuisotorres/mcp-ai-agent.git cd mcp-ai-agent
-
Create and sync the virtual environment using UV:
uv venv # Create a virtual environment (e.g., .venv) uv sync # Install dependencies from pyproject.toml source .venv/bin/activate # Or `.\.venv\Scripts\activate` on Windows
-
Set up environment variables: Copy the example environment file and fill in your credentials:
cp .env.example .env
Then, edit
.env
with your actual API keys.
GOOGLE_MAPS_PLATFORM_API_KEY="your-google-maps-api-key"
OPENAI_API_KEY="your-openai-api-key"
COMET_API_KEY="your-comet-api-key"
COMET_WORKSPACE="your-comet-workspace"
COMET_PROJECT_NAME="your-comet-project-name"
The .env
file should contain:
GOOGLE_MAPS_PLATFORM_API_KEY
: Your Google Maps Platform API key.- Purpose: Allows the Google Maps MCP Server to make requests to Google Maps APIs.
OPENAI_API_KEY
: Your OpenAI API key.- Purpose: Allows the
LiteLlm
model to use OpenAI's GPT models.
- Purpose: Allows the
COMET_API_KEY
: Your CometML API Key.- Purpose: For Opik to send traces to your CometML project.
COMET_WORKSPACE
: Your CometML workspace.COMET_PROJECT_NAME
: The CometML project name where traces will be stored.
Once the setup is complete, run the ADK web UI:
uv run adk web
This command will:
- Start a FastAPI server.
- Provide a web interface at
http://127.0.0.1:8000
to interact with your agent. - The
MCPToolset
inagent.py
is configured to start the Google Maps MCP server vianpx
automatically when the agent needs to use its tools.
Upon running uv run adk web
and navigating to http://127.0.0.1:8000
(or the port shown in your terminal), you'll see the ADK Web UI. You can select your Agent, in this case mcp_agent
, and start a conversation.
(Screenshot 1: The initial ADK Web UI screen with the chat input.)
Caption: The main interface of the ADK Web UI where you can type messages to your agent.
The agent can understand requests for directions, place details, elevation, and more, using the tools from the Google Maps MCP Server.
Example: Getting Directions The agent responds to "How do I drive from São Paulo to Campinas?" with turn-by-turn directions.
(Screenshot 2: Agent using the maps_directions
tool.)
Caption: The agent successfully uses the
maps_directions
tool to provide driving directions in the chat interface.
Example: Getting Place Details The agent can fetch reviews and other information for landmarks.
(Screenshot 3: Agent using maps_place_details
for Eiffel Tower reviews.)
Caption: Agent fetching and displaying reviews for the Eiffel Tower, showcasing the
maps_place_details
tool usage and output.
Example: Getting Elevation The agent can provide elevation for given coordinates.
(Screenshot 4: Agent using maps_elevation
tool.)
Caption: Agent providing the elevation for specified coordinates using the
maps_elevation
tool.
The ADK Web UI provides an "Events" (or "Trace") tab where you can inspect the flow of the conversation. This includes the function calls made by the agent and the responses received from tools.
Example: maps_reverse_geocode
Event
Shows the agent invoking the maps_reverse_geocode
tool.
(Screenshot 5: Event view for maps_reverse_geocode
.)
Caption: Event view detailing a
functionCall
for maps_reverse_geocode
with args
and Metadata.
Example: maps_directions
Event Flow
Illustrates the sequence of events when the maps_directions
tool is called.
(Screenshot 6: Event view for maps_directions
tool.)
Caption: The "Events" tab in the ADK UI, showing the invocation details for the
maps_directions
tool.
Opik integrates with CometML to provide detailed traces of your agent's execution, offering insights into LLM calls, tool usage, and overall performance.
Overall Traces in Opik A list of all captured interactions for the project.
(Screenshot 7: Overview of traces in CometML for the mcp-ai-agent
project.)
Caption: The CometML UI showing a list of traces captured by Opik for different agent interactions.
Detailed Opik Trace for maps_direction_tool
A specific trace showing the LLM call and the maps_direction_tool
invocation.
(Screenshot 8: Detailed view of a single trace involving the maps_directions
tool.)
Caption: A detailed view of an Opik trace in CometML, showing the sequence of operations for a
maps_directions
request, including the LLM call and tool interaction.
Input/Output YAML in Opik Detailed request and response data for LLM calls and tool interactions, presented in YAML.
(Screenshot 9: Input/Output details for the maps_direction
tool call in Opik.)
Caption: The Input/Output tab within an Opik trace in CometML, displaying the request and response of the entire conversation in YAML format.
These traces are invaluable for debugging, understanding agent behavior, and optimizing performance.
Note: You can find the entire YAML file for this conversation at examples/agent_conversation.yaml
We begin by importing the required packages for ADK, environment configuration, and observability:
from google.adk.agents import LlmAgent
from google.adk.models.lite_llm import LiteLlm
from google.adk.tools.mcp_tool.mcp_toolset import (
MCPToolset,
StdioServerParameters
)
import os
from dotenv import load_dotenv
import opik
from opik.integrations.adk import OpikTracer
This sets the foundation for the agent logic.
Here we load API keys and configure observability:
load_dotenv()
opik.configure(use_local=False)
tracer = OpikTracer()
GOOGLE_MAPS_API_KEY = os.getenv("GOOGLE_MAPS_PLATFORM_API_KEY")
We initialize an ADK Agent with LlmAgent
using OpenAI's GPT-4o model and the LiteLlm
library for ADK <> OpenAI integration:
root_agent = LlmAgent(
model=LiteLlm(model="openai/gpt-4o"),
name="openai_agent",
description="An intelligent mapping assistant that provides driving, walking, and public transportation directions...",
instruction="When the user asks for routes, travel times, or directions between locations..."
This is where we define the integration with the Google Maps MCP Server:
tools=[
MCPToolset(
connection_params=StdioServerParameters(
command="npx",
args=[
"-y",
"@modelcontextprotocol/server-google-maps"
],
env={
"GOOGLE_MAPS_API_KEY": GOOGLE_MAPS_API_KEY
},
),
)
],
This tells the agent to launch the MCP server using npx
, making all Google Maps tools available for our Agent.
Finally, we attach Opik tracing callbacks to capture the full agent lifecycle:
before_agent_callback=tracer.before_agent_callback,
after_agent_callback=tracer.after_agent_callback,
before_model_callback=tracer.before_model_callback,
after_model_callback=tracer.after_model_callback,
before_tool_callback=tracer.before_tool_callback,
after_tool_callback=tracer.after_tool_callback,
)
This enables deep visibility into every interaction handled by the agent.
Check out the video on YouTube where I walk through the project:
This project is licensed under the MIT License. See the LICENSE file for details.