Files
Josh Zhang 131a92e1d0 docs(integrations): refresh e2a page for the hosted-only MCP server (#2026)
* docs(integrations): refresh e2a page for the hosted-only MCP server

The e2a integration page has drifted from the service since it landed in
May. Corrections:

- Drop both Local MCP Server tabs. The `@e2a/mcp-server` npm package is
  retired and the current server has no stdio transport, so `npx -y
  @e2a/mcp-server` installs an abandoned build.
- Point the remote examples at `https://api.e2a.dev/mcp`, the endpoint
  published in the MCP Registry, instead of the older `mcp.e2a.dev`.
- Remove `E2A_AGENT_EMAIL`, which no longer exists; `whoami` takes no
  inputs and resolves identity from the credential.
- Remove the `E2A_BASE_URL` config table (renamed, and unused now that
  the page is hosted-only).
- Fix the held-send status: `pending_review`, not `pending_approval`.
- Drop the `agent_mode: local|cloud` guidance. There is no delivery mode
  to choose; inbound is available by polling or webhook subscription.
- Refresh the tool surface (~60 tools, was 18) and group it by credential
  scope, since an agent-scoped key sees only the runtime tools.
- Update repository links for the tokencanopy org rename.

* docs(integrations): recommend the e2a SDK for production ADK agents

The MCP toolset gives the model the inbox, which is the wrong layer for
the deterministic parts of a deployment: webhook signature verification,
at-least-once delivery handling, and idempotent sends. Add a section
recommending the SDK own that boundary, with the MCP toolset kept for
model-driven actions inside a turn, and point at the working example.

* docs(integrations): add WebSocket delivery and future-proof the tool count

Two corrections after checking the page against the running service:

- Receiving mail listed only polling and webhooks. WebSocket delivery via
  the SDK's listen() needs no public URL, which makes it the practical
  choice while developing an ADK agent or for a long-running agent that
  isn't a web service.
- The tool surface grows; state 60+ rather than a number that dates.

* docs(integrations): restructure e2a page to the integration template

Address review feedback. Drop the four added top-level sections ('For
production', 'Key scope', 'Receiving mail', 'Sending and review holds')
and fold only the load-bearing facts back into the template's existing
shape:

- Key scope becomes two sentences introducing Available tools, since an
  agent-scoped key genuinely cannot see the admin tools listed there.
- The SDK recommendation becomes a short tip after the code sample,
  keeping the inline links.
- Delivery options and OAuth become one sentence each in Configuration.
- accepted/pending_review moves into the send_message table row.

Additional resources trimmed to four: dropped the MCP Registry link (a
raw JSON API) and the two SDK links, which remain linked inline.

Page is now intro / use cases / prerequisites / one sample / tools /
configuration / resources, 186 lines.

---------

Co-authored-by: Kristopher Overholt <koverholt@google.com>
2026-07-28 17:48:35 -05:00

8.1 KiB

catalog_title, catalog_description, catalog_icon, catalog_tags
catalog_title catalog_description catalog_icon catalog_tags
e2a Authenticated email gateway for AI agents with human-in-the-loop approval /integrations/assets/e2a.png
mcp

e2a MCP tool for ADK

Supported in ADKPythonTypeScript

The e2a MCP Server connects your ADK agent to e2a, an authenticated email gateway built for AI agents. This integration gives your agent its own email inbox to send, receive, and reply to messages using natural language, with SPF/DKIM/DMARC verification on inbound mail and an optional human review hold on outbound messages.

The server is hosted at https://api.e2a.dev/mcp and speaks Streamable HTTP — there is nothing to install or run locally.

Use cases

  • Give agents their own inboxes: Provision dedicated email addresses (e.g. support-bot@your-domain.com) and let agents send and receive mail just like a teammate.

  • Authenticated inbound: Every incoming message carries SPF, DKIM, and DMARC evidence, so your agent can tell whether the sender is who they claim to be before acting on the content.

  • Human-in-the-loop review: Turn on a review hold and outbound messages are parked as pending_review until a human approves them — optionally with edits to the subject, body, or recipients before sending.

  • Automate threaded conversations: Reply with In-Reply-To and References headers preserved, so threads stay intact across multiple turns in the recipient's mail client.

Prerequisites

Use with agent

=== "Python"

=== "Remote MCP Server"

    ```python
    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,
    )

    E2A_API_KEY = "YOUR_E2A_API_KEY"

    root_agent = Agent(
        model="gemini-flash-latest",
        name="e2a_agent",
        instruction=(
            "You manage email through the e2a tools. Call whoami once to "
            "learn your identity and inbox address. Use list_messages and "
            "get_message to read; use reply_to_message when replying to an "
            "existing thread (it preserves In-Reply-To and References), and "
            "send_message only to start a new thread. Both 'accepted' and "
            "'pending_review' are successful outcomes — never re-send after "
            "either one."
        ),
        tools=[
            McpToolset(
                connection_params=StreamableHTTPConnectionParams(
                    url="https://api.e2a.dev/mcp",
                    headers={"Authorization": f"Bearer {E2A_API_KEY}"},
                    timeout=30,
                ),
            )
        ],
    )
    ```

=== "TypeScript"

=== "Remote MCP Server"

    ```typescript
    import { LlmAgent, MCPToolset } from "@google/adk";

    const E2A_API_KEY = "YOUR_E2A_API_KEY";

    const rootAgent = new LlmAgent({
        model: "gemini-flash-latest",
        name: "e2a_agent",
        instruction:
            "You manage email through the e2a tools. Call whoami once to " +
            "learn your identity and inbox address. Use list_messages and " +
            "get_message to read; use reply_to_message when replying to an " +
            "existing thread (it preserves In-Reply-To and References), and " +
            "send_message only to start a new thread. Both 'accepted' and " +
            "'pending_review' are successful outcomes — never re-send after " +
            "either one.",
        tools: [
            new MCPToolset({
                type: "StreamableHTTPConnectionParams",
                url: "https://api.e2a.dev/mcp",
                transportOptions: {
                    requestInit: {
                        headers: {
                            Authorization: `Bearer ${E2A_API_KEY}`,
                        },
                    },
                },
            }),
        ],
    });

    export { rootAgent };
    ```

!!! tip "For production, pair the toolset with the e2a SDK"

The MCP toolset hands the inbox to the model. Keep the deterministic
parts — verifying webhook signatures, handling at-least-once delivery,
sending idempotently — in application code with the
[Python](https://pypi.org/project/e2a/) or
[TypeScript](https://www.npmjs.com/package/@e2a/sdk) SDK. The ADK webhook
example below is a complete working version of that shape.

Available tools

The hosted server exposes 60+ tools; call tools/list against the endpoint for the authoritative set. Which ones you see depends on your key: an agent-scoped key (e2a_agt_…) — recommended for a deployed agent — sees only the runtime tools, while an account-scoped key (e2a_acct_…) also sees the admin tools below.

Runtime — inbox tools

Tool Description
whoami Return the authenticated identity: user, credential scope, plan and usage limits, plus agent_email for an agent-scoped credential
get_agent Fetch one agent's full record
list_messages List inbox or sent mail with direction, read_status, search filters, and cursor pagination
get_message Full body, headers, attachment metadata, and SPF/DKIM/DMARC evidence for one message
get_message_lifecycle Reconstructed delivery history for one message
get_attachment Attachment metadata, or the bytes inline with inline: true
send_message Send a new email; returns accepted, or pending_review when a review hold catches it — both are success, neither should be retried
reply_to_message Reply in-thread; preserves In-Reply-To and References
forward_message Forward a message to new recipients
list_conversations / get_conversation Browse threads rather than individual messages
update_message_labels Add or remove labels on a message
delete_message / restore_message Soft-delete to trash, and restore

Admin — provisioning and setup

Tool Description
list_agents, create_agent, update_agent, delete_agent, restore_agent Manage agent inboxes
get_protection, update_protection Per-agent screening and review-hold configuration
list_domains, register_domain, get_domain, verify_domain, delete_domain Custom domain registration and DNS verification
list_reviews, get_review, approve_review, reject_review Work the human review queue
list_webhooks, create_webhook, update_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries Webhook subscriptions and delivery history
list_events, get_event, redeliver_event Event log and replay
list_templates, create_template, update_template, delete_template, validate_template Server-side email templates (beta)
list_api_keys, create_api_key, delete_api_key API key management

Configuration

The hosted endpoint needs no environment variables beyond your API key, which ADK passes in the Authorization header shown above. To use a self-hosted e2a deployment, change the url to that deployment's /mcp endpoint.

Interactive MCP clients can add https://api.e2a.dev/mcp as an OAuth 2.1 connector instead of pasting a key. To receive mail, poll list_messages, open a WebSocket with the SDK's listen() (no public URL required), or subscribe an HTTPS endpoint with create_webhook.

Additional resources