Many agent frameworks overlook communication. While AI agents can reason, plan, and handle complex tasks, they often struggle with everyday communication tools that people rely on. Email is still the internet’s universal protocol, and now your Google ADK agents can use it too.
Today, we’re excited to introduce our integration with Google’s Agent Development Kit (ADK), one of the most promising new agent frameworks. It offers multi-agent orchestration, built-in MCP support, and works with more than just Gemini models. Now, your ADK agents can send, receive, and manage emails on their own using the AgentMail MCP server.
This guide shows you how to build an intelligent email assistant using a multi-agent architecture.
No SMTP config, no OAuth rabbit hole, no inbox wiring. The agent sends email. Done.
What is Google ADK?
Google’s Agent Development Kit is an open-source framework for building AI agents. It’s designed to make agent development feel like traditional software development rather than experimental AI work.
Key features of Google ADK:
- Multi-language support: Build agents in Python, TypeScript, Go, or Java
- Model agnostic: Works with Gemini, Claude, Vertex AI, Ollama, and other LLMs
- Multi-agent orchestration: Create hierarchical agent systems with specialized sub-agents
- Rich tool ecosystem: Pre-built tools, custom functions, and MCP server integrations
- Deployment ready: Container support for Cloud Run, GKE, or local execution.
ADK provides three ways for agents to coordinate:
- Shared session state: Agents read and write to a common context
- LLM-driven delegation: Agents dynamically route tasks using function calls
- Explicit invocation: Agents call other agents as tools
Thanks to this flexibility, ADK works well for both simple single-agent tasks and more complex multi-agent workflows.
The AgentMail + Google ADK Integration
The AgentMail MCP server gives your Google ADK agents full email capabilities:
Inbox Management
- Create new inboxes programmatically.
- List and retrieve existing inboxes.
- Delete inboxes when no longer needed.
Message Operations
- Send emails to any recipient.
- Receive and read incoming messages.
- Reply to messages within threads.
- Forward emails to other addresses.
Thread and Attachment Handling
- Access full conversation threads.
- Download and process attachments.
- Update message properties (read/unread status)
Your agent now handles email independently, with no need for manual inbox setup, OAuth flows, or token refreshes, just simple API calls. This provides a plug-and-play email solution, unique among agent frameworks, that lets you deploy human-like communication in minutes.
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.
Step-by-Step Guide to Building Multi-Agent Email Applications
Let’s get started building an intelligent email assistant using Google ADK and AgentMail. We’ll walk through setting up your environment, structuring your agent, adding core features, and orchestrating multiple agents.
Prerequisites
Before starting, you’ll need:
- Python 3.10+ (or TypeScript/Node.js for the TypeScript version)
- An AgentMail account: Sign up at agentmail.to
- An AgentMail API key: Generate one from your dashboard
- A Google AI Studio API key or Vertex AI credentials for Gemini access
Let's set up your intelligent email assistant using Google ADK and AgentMail. We'll cover environment setup, configuring your agent, adding features, and multi-agent orchestration.
Step 1: Setting Up Your ADK Project Environment
ADK projects follow a specific directory structure. For our email assistant, we’ll use this structure:
email-agent/
├── .env # API keys
├── agent.py # Main agent application
└── email_assistant/ # Agent package (optional, for ADK web UI)
├── __init__.py
└── multi_agent.py
Setting Up the Environment
Make sure Python 3.10+ is installed. MCP won’t work on older versions:
python3 --version
# If you need a newer version on macOS with Homebrew:
# brew install python@3.12
Create a new project directory and virtual environment:
mkdir email-agent && cd email-agent
# Create virtual environment with Python 3.10+
python3 -m venv .venv
# On macOS, you may need to specify the version explicitly:
# /opt/homebrew/bin/python3.12 -m venv .venv
# Activate the environment
source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install the required packages:
pip install google-adk python-dotenv litellm
Create a .env file with your API keys:
# Gemini API Key - get from https://aistudio.google.com/apikey
GEMINI_API_KEY=your_gemini_api_key
# AgentMail API Key - get from https://console.agentmail.to
AGENTMAIL_API_KEY=your_agentmail_api_key
Why does this structure matter?
This directory structure isn’t just a convention; it’s how ADK finds and loads your agents. Separating configuration (.env), application logic (agent.py), and agent definitions helps with the following:
- Modularity: Each component can be developed and tested independently
- Security: API keys stay in .env, never committed to version control
- Deployment flexibility: The same structure works for local development and cloud deployment
Step 2: Configuring the AgentMail MCP Server
The AgentMail MCP server runs as a subprocess that your ADK agent communicates with. Create the file agent.py:
import os
from dotenv import load_dotenv
from google.adk.agents import Agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from google.genai.types import Content, Part
from mcp import StdioServerParameters
load_dotenv()
# Configure the AgentMail MCP server
agentmail_mcp = McpToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="npx",
args=["-y", "agentmail-mcp"],
env={"AGENTMAIL_API_KEY": os.getenv("AGENTMAIL_API_KEY")}
),
timeout=30 # Allow time for npx to download package on first run
)
)
This configuration:
- Uses npx to run the AgentMail MCP server (automatically downloads on first use)
- Passes your API key through environment variables
- Sets a 30-second timeout to allow for initial package download
- Establishes a stdio connection for communication between ADK and the MCP server
How MCP connections work
MCP uses a client-server architecture in which your ADK agent is the client, and AgentMail’s MCP server provides the tools. The StdioConnectionParams establishes communication over standard input/output streams, which is:
- Secure: No network ports exposed
- Simple: Works the same locally and in containers.
- Reliable: Process lifecycle managed by ADK
The McpToolset automatically finds all available tools from the MCP server and makes them accessible to your agent. You don’t have to define each email operation yourself, since the MCP server provides them all.
Step 3: Creating the Email Agent
Now define your agent with the AgentMail tools. Add this to your agent.py:
# Create the email agent
email_agent = Agent(
name="email_assistant",
model="gemini-2.5-flash",
description="An AI assistant that can send, receive, and manage emails.",
instruction="""You are an email assistant with access to email tools.
You can:
- Create new email inboxes
- Send emails to any recipient
- Check for new messages in inboxes
- Reply to emails within threads
- Forward messages to other addresses
- List and manage existing inboxes
When asked to perform email tasks:
1. First check if an inbox exists or create one if needed
2. Use the appropriate email tool for the task
3. Confirm the action was completed
4. Provide relevant details (message ID, inbox address, etc.)
Always be helpful and confirm actions clearly.
If you need more information to complete a task, ask for it.""",
tools=[agentmail_mcp],
)
Let’s break down the key components:
- name: Unique identifier for this agent
- model: The LLM powering the agent’s reasoning (Gemini 2.5 Flash)
- description: Brief summary of the agent’s purpose
- instruction: Detailed guidance for the agent’s behavior
- tools: List of tool providers (our AgentMail MCP toolset)
Agent instructions as system prompts
The instruction field is critical—it defines your agent’s personality, capabilities, and decision-making process. Well-crafted instructions:
- Set boundaries: What the agent can and cannot do
- Establish workflow: The sequence of actions for common tasks.
- Handle edge cases: What to do when information is missing.
- Define tone: How the agent communicates with users.
You can think of instructions as programming in plain language. The clearer and more structured your instructions are, the more reliable and helpful your agent will be.
Step 4: Building a Multi-Agent System
For more complex workflows, you can create specialized agents that work together. Here’s an example with three agents: a classifier, a responder, and a coordinator:
from google.adk.agents import Agent
# Agent 1: Email Classifier
classifier_agent = Agent(
name="email_classifier",
model="gemini-2.5-flash",
description="Classifies incoming emails by type and priority",
instruction="""You classify emails into categories and priorities.
Categories:
- "support": Customer questions, bug reports, help requests
- "sales": Pricing inquiries, demos, partnerships
- "spam": Unwanted emails, promotions, newsletters
- "internal": Team communications, updates, announcements
Priorities:
- "urgent": Needs response within hours
- "normal": Needs response within 1-2 days
- "low": Can wait or may not need response
For each email, output JSON:
{
"category": "...",
"priority": "...",
"summary": "one sentence summary",
"suggested_action": "what should be done"
}
""",
tools=[agentmail_mcp],
)
# Agent 2: Email Responder
responder_agent = Agent(
name="email_responder",
model="gemini-2.5-flash",
description="Drafts and sends email responses",
instruction="""You draft and send professional email responses.
Guidelines:
- Be helpful and professional
- Keep responses concise but complete
- Include relevant details from the original email
- Ask clarifying questions if needed
- Sign off appropriately
For support emails: Acknowledge the issue, provide help or escalate
For sales emails: Thank them, provide requested info or schedule follow-up
For internal emails: Respond appropriately to the context
Always use the appropriate inbox to send from.""",
tools=[agentmail_mcp],
)
# Agent 3: Root Coordinator
root_agent = Agent(
name="email_coordinator",
model="gemini-2.5-flash",
description="Coordinates email handling between specialized agents",
instruction="""You coordinate email handling for the organization.
Your sub-agents:
- email_classifier: Use to categorize and prioritize new emails
- email_responder: Use to draft and send responses
Workflow for handling emails:
1. When asked to check emails, use classifier to categorize them
2. Based on classification, decide if response is needed
3. For emails needing response, use responder to draft and send
4. Report back with summary of actions taken
For general email tasks (create inbox, send email), handle directly.
For batch processing (check and respond to all), use sub-agents.""",
sub_agents=[classifier_agent, responder_agent],
tools=[agentmail_mcp],
)
Looking at the bigger picture: Multi-agent orchestration
Multi-agent systems offer several advantages over monolithic agents:
- Separation of Concerns: Each agent specializes in one task
- Maintainability: Update one agent without affecting others
- Scalability: Add new capabilities by adding new agents
- Debugging: Easier to identify which agent caused an issue
ADK supports multiple orchestration patterns:
- Hierarchical: Parent agent delegates to child agents (our example)
- Sequential: Agents run in a defined order
- Parallel: Multiple agents work simultaneously
- Loop: Agents repeat until a condition is met
The root agent serves as the orchestrator, choosing which specialist agent to use for each task.
Step 5: Creating the Application Runtime
Add the runtime code to execute your agent. This handles the conversation loop:
async def main():
# Create a session service to maintain conversation state
session_service = InMemorySessionService()
# Create a runner to execute the agent
runner = Runner(
agent=email_agent, # or root_agent for multi-agent
app_name="email_assistant",
session_service=session_service,
)
# Start a new session
session = await session_service.create_session(
app_name="email_assistant",
user_id="user_1"
)
print("Email Assistant ready. Type 'quit' to exit.\n")
while True:
user_input = input("You: ").strip()
if user_input.lower() == 'quit':
break
# Create the message content
user_content = Content(
role="user",
parts=[Part(text=user_input)]
)
# Process the request and stream events
async for event in runner.run_async(
user_id="user_1",
session_id=session.id,
new_message=user_content
):
if event.is_final_response():
# Extract and display the response
if event.content and event.content.parts:
response_text = event.content.parts[0].text
print(f"\nAssistant:{response_text}\n")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Event-driven architecture
The runner.run_async() method returns an asynchronous stream of events, not just a final response. This architecture enables:
- Real-time feedback: Show users what’s happening as it happens
- Tool visibility: See when tools are called and their results
- Agent transfers: Track when control passes between agents
- Error handling: Catch and handle issues at each step
Event types include:
- is_final_response(): The agent’s complete answer
- Tool invocation events: When the agent uses a tool
- Agent transfer events: When delegating to sub-agents
- Thinking events: The agent’s reasoning process
For production apps, you’ll want to handle more event types to give users a better experience.
Step 6: Running and Testing Your Agent
Run your email assistant:
python agent.py
Test with these prompts:
Create an inbox:
You: Create a new inbox called "support"
List existing inboxes:
You: What inboxes do I have?
Send an email:
You: Send an email from my support inbox to vivekksonar2000@gmail.com with subject
"Welcome!" and body "Thanks for signing up. Let us know if you have questions."
Check for messages:
You: Check my support inbox for new messages
Reply to a message:
You: Reply to the last message saying "Thanks for your feedback!"
Testing Multi-Agent Systems
When testing multi-agent systems, verify:
- Delegation works: The root agent correctly routes to specialists.
- Context passes: Sub-agents receive the necessary information.
- Results return: Final responses reflect sub-agent work.
- Errors are handled gracefully: Failures in one agent don’t crash the system.
For the multi-agent version, test classification and response workflows:
You: Check my inbox and respond to any urgent support emails
This tests the entire process: reading emails, classifying them, and generating responses.
Step 7: Production Considerations
For production deployments, consider these enhancements:
Persistent Sessions
Replace InMemorySessionService with a database-backed implementation:
from google.adk.sessions import DatabaseSessionService
session_service = DatabaseSessionService(
connection_string="postgresql://..."
)
Error Handling
Wrap agent calls with proper error handling:
try:
async for event in runner.run_async(...):
# process events
except Exception as e:
logger.error(f"Agent error:{e}")
# Handle gracefully
Rate Limiting
For high-volume applications, implement rate limiting on email operations to stay within AgentMail quotas.
Logging and Monitoring
Add structured logging to track agent performance:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Log tool calls, agent transfers, response times
Complete Code
Here’s the complete agent.py file:
import os
from dotenv import load_dotenv
from google.adk.agents import Agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from google.genai.types import Content, Part
from mcp import StdioServerParameters
load_dotenv()
# Configure the AgentMail MCP server
agentmail_mcp = McpToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="npx",
args=["-y", "agentmail-mcp"],
env={"AGENTMAIL_API_KEY": os.getenv("AGENTMAIL_API_KEY")}
),
timeout=30
)
)
# Create the email agent
email_agent = Agent(
name="email_assistant",
model="gemini-2.5-flash",
description="An AI assistant that can send, receive, and manage emails.",
instruction="""You are an email assistant with access to email tools.
You can:
- Create new email inboxes
- Send emails to any recipient
- Check for new messages in inboxes
- Reply to emails within threads
- Forward messages to other addresses
- List and manage existing inboxes
When asked to perform email tasks:
1. First check if an inbox exists or create one if needed
2. Use the appropriate email tool for the task
3. Confirm the action was completed
4. Provide relevant details (message ID, inbox address, etc.)
Always be helpful and confirm actions clearly.
If you need more information to complete a task, ask for it.""",
tools=[agentmail_mcp],
)
async def main():
session_service = InMemorySessionService()
runner = Runner(
agent=email_agent,
app_name="email_assistant",
session_service=session_service,
)
session = await session_service.create_session(
app_name="email_assistant",
user_id="user_1"
)
print("Email Assistant ready. Type 'quit' to exit.\n")
while True:
user_input = input("You: ").strip()
if user_input.lower() == 'quit':
break
user_content = Content(
role="user",
parts=[Part(text=user_input)]
)
async for event in runner.run_async(
user_id="user_1",
session_id=session.id,
new_message=user_content
):
if event.is_final_response():
if event.content and event.content.parts:
response_text = event.content.parts[0].text
print(f"\nAssistant:{response_text}\n")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Use Cases
Here are practical applications you can build with AgentMail and Google ADK:
Customer Support Automation
support_agent = Agent(
name="support_agent",
instruction="""You handle customer support emails.
For common questions (password reset, billing):
- Send automated responses with clear instructions
- Include relevant help links
For complex issues:
- Acknowledge receipt
- Gather necessary information
- Escalate to support-team@company.com with summary
Always be empathetic and professional.""",
model="gemini-2.5-flash",
tools=[agentmail_mcp],
)
Sales Follow-Up Pipeline
sales_agent = Agent(
name="sales_agent",
instruction="""You manage sales outreach and follow-ups.
For new leads:
- Send personalized initial outreach
- Track responses in threads
For follow-ups:
- If no response in 48 hours, send follow-up
- After 3 attempts, mark as cold and notify sales team
For interested prospects:
- Schedule demos via calendar link
- CC sales-team@company.com on all replies""",
tools=[agentmail_mcp],
)
Automated Reporting
reporting_agent = Agent(
name="reporting_agent",
instruction="""You generate and send automated reports.
Daily digest:
- Compile statistics from the day
- Send to team-leads@company.com at 6pm
Weekly summary:
- Aggregate daily data
- Include trends and highlights
- Send to leadership@company.com Monday 9am
Format reports with clear sections and bullet points.""",
tools=[agentmail_mcp],
)
What sets this apart
Traditional email integrations require:
- OAuth setup and token management
- SMTP server configuration
- Custom code for threading and storage
- Manual inbox provisioning
With AgentMail + Google ADK:
- API key authentication: No OAuth complexity
- Managed infrastructure: No SMTP servers to configure
- Built-in threading: Conversations stay organized automatically
- Programmatic inboxes: Create inboxes via API as needed
- MCP standard: Works with the growing MCP ecosystem
Your agent gets a real inbox, not just the ability to send emails. It has full inbox features, including threads, storage, and message history.
Conclusion and next steps
This tutorial showed how Google ADK makes it possible to build effective multi-agent email systems. To create even more advanced agents, try exploring ADK features such as:
- Artifacts: Managing binary data and attachments
- Events: Controlling agent execution flow
- Context: Handling conversation state
- Callbacks: Implementing safety filters and logging
For deployment, ADK integrates with:
- Vertex AI Agent Engine: Managed agent hosting
- Cloud Run: Containerized deployment
- GKE: Kubernetes orchestration
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.
FAQs
What is Google ADK?
Google ADK (Agent Development Kit) is an open-source framework for building AI agents. It supports Python, TypeScript, Go, and Java, and works with various LLMs, including Gemini, Claude, and models via Vertex AI. ADK provides tools for multi-agent orchestration, tool integration, and deployment.
What is MCP, and why does it matter for AI agents?
MCP (Model Context Protocol) is an open standard for connecting AI applications to external systems. Think of it like USB-C for AI: a standardized way to plug in tools, data sources, and services. MCP lets agents access capabilities without custom integrations for each tool.
Can I use AgentMail with other agent frameworks?
Yes. AgentMail provides native integrations for LangChain, LlamaIndex, CrewAI, and now Google ADK. The AgentMail MCP server works with any framework that supports MCP toolsets, making it easy to add email capabilities to existing agents.
Do I need to manage SMTP servers or email infrastructure?
No. AgentMail handles all email infrastructure: SMTP, deliverability (SPF, DKIM, DMARC), storage, and threading. Your agent interacts with a simple API. You focus on building agent logic, not managing email servers.
How does email help with multi-agent coordination?
Email provides a natural communication layer for multi-agent systems. Each agent can have its own inbox, send messages to other agents or humans, and maintain conversation history. Email threads preserve context across interactions, and the audit trail shows which agent did what.
What email operations can my Google ADK agent perform?
With the AgentMail MCP integration, your agent can: create and manage inboxes, send emails, receive and read messages, reply to and forward emails, access conversation threads, download attachments, and update message properties like read status.


![5 Best Email API For Developers Compared [2026]](/_next/image?url=%2Fblog%2F5-best-email-api-for-developers-compared.png&w=3840&q=75&dpl=dpl_K1abswBLsuCSLeLFSeoppUe4c7sF)