# Send & Receive Emails with Google ADK (/integrations/frameworks/google-adk)

<!-- agent-signals: reading_time_min: 4 · est_tokens: 1737 · updated: 2026-09-06 -->
Related: [Send & Receive Emails with Claude Cowork](/integrations/frameworks/claude-cowork.md), [Send & Receive Emails with Claude Code](/integrations/frameworks/claude-code.md), [Send & Receive Emails with OpenAI Codex](/integrations/frameworks/codex.md), [Send & Receive Emails with OpenClaw](/integrations/frameworks/openclaw.md), [Send & Receive Emails with Grok](/integrations/frameworks/grok.md), [Send & Receive Emails with Manus](/integrations/frameworks/manus.md)



# Connect a Google ADK agent to AgentMail over MCP

Google ADK agents get their email tools from the hosted AgentMail MCP server through ADK's built-in MCP client, so there is no separate integration package. Use this to let an ADK agent, Python or TypeScript, create its own `@agentmail.to` inbox, send email, and read and reply to threads.

## Do this

Python 3.10 or newer.

```bash
pip install "google-adk[mcp]"
mkdir email_agent
touch email_agent/__init__.py
```

Save as `email_agent/agent.py`:

```python
import os

from google.adk.agents import Agent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams

root_agent = Agent(
    model="gemini-flash-latest",
    name="email_agent",
    instruction=(
        "You are an email agent with your own AgentMail inbox. "
        "You can create inboxes, send email, and read and reply to threads."
    ),
    tools=[
        McpToolset(
            connection_params=StreamableHTTPConnectionParams(
                url="https://mcp.agentmail.to/mcp",
                headers={"x-api-key": os.environ["AGENTMAIL_API_KEY"]},
            ),
        )
    ],
)
```

Save as `email_agent/.env`:

```bash
GOOGLE_API_KEY="<GOOGLE_API_KEY>"
AGENTMAIL_API_KEY="<API_KEY>"
```

Run from the folder that contains `email_agent/`, then prompt the agent at `[user]:`:

```bash
adk run email_agent
```

## SDK

The integration surface is ADK's MCP toolset, in both ADK languages.

Python, `pip install "google-adk[mcp]"`:

* Connect: `McpToolset(connection_params=StreamableHTTPConnectionParams(url="https://mcp.agentmail.to/mcp", headers={"x-api-key": ...}))`.
* Scope tools: add `tool_filter=["list_threads", "get_thread", "reply_to_message"]` to the `McpToolset` call.
* Define: `Agent(model=..., name=..., instruction=..., tools=[...])` as module-level `root_agent` in `email_agent/agent.py`, next to an empty `__init__.py`.

TypeScript, `npm install @google/adk @modelcontextprotocol/sdk` plus `npm install -D @google/adk-devtools` for the `adk` command:

* Connect: `new MCPToolset({ type: "StreamableHTTPConnectionParams", url: "https://mcp.agentmail.to/mcp", transportOptions: { requestInit: { headers: { "x-api-key": ... } } } })`.
* Scope tools: pass `["list_threads", "get_thread", "reply_to_message"]` as the second `MCPToolset` constructor argument.
* Define: `new LlmAgent({...})` exported as `rootAgent` from `agent.ts`. Run with `npx adk run agent.ts` from the folder that contains it.

Core SDK and CLI installs: /integrations/sdks-and-cli

## Facts

* Hosted MCP server URL: `https://mcp.agentmail.to/mcp`. Authentication: the `x-api-key` header carrying the AgentMail API key.
* The agent discovers the server's current email tools each time it connects. Full tool catalog: /integrations/mcp-and-skills.
* Model credentials use a different variable per language: `GOOGLE_API_KEY` in Python, `GEMINI_API_KEY` in TypeScript. `AGENTMAIL_API_KEY` covers only the email tools.
* `adk run` and `adk web` load a `.env` file from the folder that holds the agent file before the agent starts.
* `adk web` (Python) or `npx adk web` (TypeScript) serves a view of each tool call at `http://localhost:8000`.
* Tools the page exercises: `create_inbox`, `send_message`, `list_threads`, `get_thread`, `reply_to_message`.
* ADK hands a failed tool call's error text back to the model, so the agent can retry within the same run. A `403` from a taken username lists up to 3 available alternatives in `suggestions`. A `403` from the plan's inbox limit names the limit and an upgrade link.
* One agent turn spends a model call per tool step, which drains a small free-tier Gemini quota fast.
* A new `adk run` has no memory of the previous one. Each prompt must name the inbox address to operate on.
* Mail takes about two seconds in each direction. An agent that reports an empty inbox probably checked before the email arrived. Ask it to check again.

## Not supported

* `pip install google-adk` without the `[mcp]` extra does not install the MCP client, so the `McpToolset` import fails.
* A clean startup does not prove `AGENTMAIL_API_KEY` works. The agent starts and discovers the tools even with an invalid key. Every tool call then fails with `Forbidden (HTTP 403)`.
* `adk run email_agent` does not resolve the agent from anywhere. The argument is a path resolved from the current folder.

## Errors

| Error                                           | Status                 | Cause                                                                      | Fix                                                                                     |
| ----------------------------------------------- | ---------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `ImportError: cannot import name 'McpToolset'`  | none, Python exception | `google-adk` installed without the `mcp` extra                             | `pip install "google-adk[mcp]"`                                                         |
| `API key not valid`                             | `400 INVALID_ARGUMENT` | Invalid Gemini key. Stops at the first message, before any email tool runs | Set `GOOGLE_API_KEY` (Python) or `GEMINI_API_KEY` (TypeScript) in `.env`                |
| `Forbidden (HTTP 403)` on every email tool call | 403                    | `AGENTMAIL_API_KEY` missing from `.env` or mistyped                        | Fix the key in `.env`                                                                   |
| `429 RESOURCE_EXHAUSTED`                        | 429                    | Free-tier Gemini quota exhausted mid-flow                                  | Wait out the retry delay named in the error, or use a model the key still has quota for |
| `503 UNAVAILABLE`                               | 503                    | Busy free-tier Gemini pool                                                 | Retry later                                                                             |
| `Directory 'email_agent' does not exist`        | none, CLI error        | `adk run` executed outside the parent folder of `email_agent/`             | Run from that folder, or pass the full path to the agent                                |

## Verify

Start `adk run email_agent` and prompt the agent to create an inbox and send an email to an address you already check. Success: the email arrives moments later from a new `@agentmail.to` address and the agent reports that address. Startup alone verifies nothing about `AGENTMAIL_API_KEY`.

## Related

* /integrations/mcp-and-skills - full hosted tool catalog and every other way to connect to the server
* /advanced/webhooks - start a run when mail arrives instead of prompting by hand
* /quickstart - get an AgentMail API key for a first project
