Integration
Agno Email Toolkit
Build an Agno email toolkit around real two-way agent inboxes: a custom Toolkit class wrapping the Dead Simple Python SDK, or MCPTools pointed at the hosted MCP server.
Send-Only vs. an Actual Inbox
Agno (formerly Phidata, roughly 41k GitHub stars as of August 2026) already ships email toolkits natively — Resend for transactional sends and Gmail for driving a Google account. What neither gives you is an inbox the agent owns: Resend is send-only, and Gmail means OAuth-ing a human account with everything that implies. Dead Simple is the agent-inbox alternative — real two-way addresses created via API, with receive, reply threading, OTP extraction, webhooks, and a dashboard. Honesty note: Dead Simple ships native adapters for LangChain, CrewAI, AutoGen, LlamaIndex, and the OpenAI Agents SDK; for Agno the integration is the custom toolkit below (a short snippet you own) or Agno's own MCPTools.
Custom Toolkit Class
Agno toolkits are plain classes: subclass Toolkit, register the methods you want the model to see, and Agno reads the schemas from your type hints and docstrings:
import os from agno.tools import Toolkit from deadsimple import DeadSimple class DeadSimpleEmailTools(Toolkit): def __init__(self, **kwargs): self.client = DeadSimple(os.environ["DSE_API_KEY"]) super().__init__( name="deadsimple_email", tools=[self.send_email, self.read_messages, self.wait_for_reply], **kwargs, ) def send_email(self, inbox_id: str, to: str, subject: str, body: str) -> str: """Send a plain-text email from a Dead Simple inbox.""" result = self.client.messages.send( inbox_id, to=[to], subject=subject, text_body=body ) return f"Sent {result.message_id}" def read_messages(self, inbox_id: str, limit: int = 5) -> list[dict]: """List the most recent messages in an inbox.""" result = self.client.messages.list(inbox_id, limit=limit) return [ {"from": m.from_email, "subject": m.subject, "snippet": m.snippet} for m in result.messages ] def wait_for_reply(self, inbox_id: str, from_contains: str = "") -> dict | None: """Block until a new inbound email arrives, then return it.""" msg = self.client.messages.wait_for( inbox_id, from_contains=from_contains, timeout=120 ) return {"from": msg.from_email, "subject": msg.subject} if msg else None
Attach it to an agent like any built-in toolkit:
from agno.agent import Agent from agno.models.openai import OpenAIChat from deadsimple_toolkit import DeadSimpleEmailTools agent = Agent( model=OpenAIChat(id="gpt-4o"), tools=[DeadSimpleEmailTools()], markdown=True, ) agent.print_response( "Email vendor@example.com from inbox inb_a1b2c3 asking for the " "August invoice, then wait for their reply and summarize it." )
All 14 Tools via MCPTools
Prefer zero wrapper code? Agno's MCPTools connects to Dead Simple's hosted MCP server over streamable HTTP:
import asyncio, os from agno.agent import Agent from agno.tools.mcp import MCPTools, StreamableHTTPClientParams server_params = StreamableHTTPClientParams( url="https://api.deadsimple.email/mcp", headers={"Authorization": f"Bearer {os.environ['DSE_API_KEY']}"}, ) async def main(): async with MCPTools( server_params=server_params, transport="streamable-http" ) as mcp_tools: agent = Agent(tools=[mcp_tools], markdown=True) await agent.aprint_response( "Create an inbox called 'trials', sign up for the beta at " "example.com, and read me the verification code when it lands." ) asyncio.run(main())
The agent gets create_inbox, list_inboxes, delete_inbox, send_email, read_messages, read_message, reply_to_message, forward_message, wait_for_email, get_verification_code, get_verification_link, list_threads, read_thread, and get_usage. A local stdio server is also available: pip install "deadsimple-email[mcp]", then MCPTools(command="python -m deadsimple.mcp", env={"DSE_API_KEY": ...}).
Dead Simple vs. Agno's Built-in Email Toolkits
| Capability | Resend toolkit | Gmail toolkit | Dead Simple |
|---|---|---|---|
| Send email | Yes | Yes | Yes |
| Receive email | No (send-only) | Yes (human account) | Yes (agent-owned inbox) |
| Create inboxes via API | No | No | Yes, unlimited by plan |
| Auth model | API key | OAuth on a human account | API key |
| OTP / magic-link extraction | No | Manual parsing | Built-in (wait_for_verification) |
Use Resend when the agent only fires notifications. Use Dead Simple when the agent needs an address of its own — support bots that hold conversations, procurement agents that wait for vendor replies, or signup automations that need the verification code.
FAQ
Different jobs. Resend is send-only transactional email, and the Gmail toolkit drives a human Google account with OAuth. Dead Simple gives agents their own inboxes — created via API, able to send and receive, with reply threading, OTP extraction, webhooks, and a dashboard. If your agent needs a real address that gets replies, that's the gap Dead Simple fills.
No. Agno's Toolkit base class makes a custom toolkit a short, honest snippet — subclass Toolkit, register the SDK-backed methods you want, and pass it to your Agent. Or skip wrappers entirely and use Agno's MCPTools against the hosted MCP server.
Yes. The SDK's wait_for and wait_for_verification methods block until a matching email arrives; the MCP server exposes the same capability as wait_for_email, get_verification_code, and get_verification_link tools.
Any model Agno supports — OpenAI, Anthropic, Google, Groq, Ollama, and more. The toolkit is plain Python; nothing is model-specific.
5 inboxes and 5,000 emails per month, no credit card required — enough to develop and run a small Agno agent in production.
Related Integrations
- CrewAI — native Dead Simple tools (shipped adapter)
- Pydantic AI — the same pattern with @agent.tool
- Strands Agents — the same pattern with AWS's @tool decorator
- LangChain — native Dead Simple toolkit (shipped adapter)
- MCP Server — the server behind the MCPTools option
- Python SDK — the client this toolkit wraps