Skip to content
Blog / Developer Resources

Build an Email Agent with Google ADK and AgentMail

Binoy Perera

How to wire Google's ADK into AgentMail's MCP server so your agents can send and receive email without touching SMTP or OAuth. Python setup, stdio transport, and a few things worth knowing before you ship it.

  • google adk
  • agent development kit
  • agentmail
  • mcp
  • model context protocol
  • email agent
  • multi-agent
  • gemini
  • agentmail mcp
  • google adk agentmail
  • python agents
  • ai agents email

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:

  1. Shared session state: Agents read and write to a common context
  2. LLM-driven delegation: Agents dynamically route tasks using function calls
  3. 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.

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:

  1. Python 3.10+ (or TypeScript/Node.js for the TypeScript version)
  2. An AgentMail account: Sign up at agentmail.to
  3. An AgentMail API key: Generate one from your dashboard
  4. 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:

Code

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:

Code

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:

Code

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 environmentsource .venv/bin/activate  # On Windows: .venv\Scripts\activate

Install the required packages:

Code

pip install google-adk python-dotenv litellm

Create a .env file with your API keys:

Code

# Gemini API Key - get from https://aistudio.google.com/apikeyGEMINI_API_KEY=your_gemini_api_key# AgentMail API Key - get from https://console.agentmail.toAGENTMAIL_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

AgentMail runs a hosted MCP server that your ADK agent connects to over HTTP. Create the file agent.py:

Python

import osfrom dotenv import load_dotenvfrom google.adk.agents import Agentfrom google.adk.runners import Runnerfrom google.adk.sessions import InMemorySessionServicefrom google.adk.tools.mcp_tool import McpToolsetfrom google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParamsfrom google.genai.types import Content, Partload_dotenv()# Configure the AgentMail MCP server (hosted)agentmail_mcp = McpToolset(   connection_params=StreamableHTTPConnectionParams(       url="https://mcp.agentmail.to/mcp",       headers={"x-api-key": os.environ["AGENTMAIL_API_KEY"]},   ))

This configuration:

  • Connects to AgentMail's hosted MCP server over Streamable HTTP
  • Passes your API key in the supported request header
  • Requires no local process or package install

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 StreamableHTTPConnectionParams establishes communication over HTTP, which is:

  • Simple: No local process to install or manage
  • Always current: Runs the latest hosted server version
  • Reliable: Connection 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:

Python

# Create the email agentemail_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:

Python

from google.adk.agents import Agent# Agent 1: Email Classifierclassifier_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 Responderresponder_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 Coordinatorroot_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:

  1. Separation of Concerns: Each agent specializes in one task
  2. Maintainability: Update one agent without affecting others
  3. Scalability: Add new capabilities by adding new agents
  4. 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:

Python

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:

Code

python agent.py

Test with these prompts:

Create an inbox:

Code

You: Create a new inbox called "support"

List existing inboxes:

Code

You: What inboxes do I have?

Send an email:

Code

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:

Code

You: Check my support inbox for new messages

Reply to a message:

Code

You: Reply to the last message saying "Thanks for your feedback!"

Testing Multi-Agent Systems

When testing multi-agent systems, verify:

  1. Delegation works: The root agent correctly routes to specialists.
  2. Context passes: Sub-agents receive the necessary information.
  3. Results return: Final responses reflect sub-agent work.
  4. Errors are handled gracefully: Failures in one agent don’t crash the system.

For the multi-agent version, test classification and response workflows:

Code

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:

Python

from google.adk.sessions import DatabaseSessionServicesession_service = DatabaseSessionService(    connection_string="postgresql://...")

Error Handling

Wrap agent calls with proper error handling:

Python

try:    async for event in runner.run_async(...):        # process eventsexcept 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:

Python

import logginglogging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)# Log tool calls, agent transfers, response times

Complete Code

Here’s the complete agent.py file:

Python

import osfrom dotenv import load_dotenvfrom google.adk.agents import Agentfrom google.adk.runners import Runnerfrom google.adk.sessions import InMemorySessionServicefrom google.adk.tools.mcp_tool import McpToolsetfrom google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParamsfrom google.genai.types import Content, Partload_dotenv()# Configure the AgentMail MCP server (hosted)agentmail_mcp = McpToolset(   connection_params=StreamableHTTPConnectionParams(       url="https://mcp.agentmail.to/mcp",       headers={"x-api-key": os.environ["AGENTMAIL_API_KEY"]},   ))# Create the email agentemail_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

Python

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

Python

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

Python

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

FAQ

Questions, answered.

Through the AgentMail MCP server, which ADK's built-in MCP support connects to directly. The integration gives ADK agents full email capabilities: create/list/delete inboxes, send, receive, reply in threads, forward, access full conversation threads, download attachments, and update read/unread status, no SMTP config, no OAuth, no token refreshes.

Google's open-source Agent Development Kit: multi-language (Python, TypeScript, Go, Java), model-agnostic (Gemini, Claude, Vertex AI, Ollama, and others), with multi-agent orchestration via shared session state, LLM-driven delegation, or explicit agent-as-tool invocation, and deployment support for Cloud Run, GKE, or local execution.

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.

You connect via the AgentMail MCP server by configuring an McpToolset with StreamableHTTPConnectionParams, passing your AgentMail API key in the request headers. ADK automatically discovers all available email tools from the server.

Your agent can create, list, and delete inboxes, send and receive emails, reply within threads, forward messages, download attachments, and update read/unread status.

Python 3.10 or higher is required, as MCP support does not work on older versions.

A multi-agent system uses specialized sub-agents (such as a classifier and a responder) coordinated by a root agent, which improves separation of concerns, maintainability, and debugging compared to a single monolithic agent.

Replace InMemorySessionService with a database-backed session service, add structured logging, implement error handling around agent calls, and apply rate limiting on email operations to stay within AgentMail quotas.

Blog

Suggested reading

View all posts

Prompt

Give yourself access to AgentMail by following the guide at:

https://agentmail.to/docs/get-started/agent-signup

and refer to:

https://agentmail.to/llms.txt

for the documentation index.

Start integrating AgentMail into your AI agents today.