Why This Pairing Works

Pydantic AI (v2.0 as of June 2026, roughly 19k GitHub stars) is the type-safe agent framework from the Pydantic team: tools are plain Python functions, and their signatures and docstrings become the schema the model sees. Dead Simple's Python SDK is a thin typed client — so an honest email tool is a few lines of your own code, not an adapter package. To be clear about what ships where: Dead Simple publishes native adapters for LangChain, CrewAI, AutoGen, LlamaIndex, and the OpenAI Agents SDK; for Pydantic AI the integration is the snippet below or the MCP toolset — both fully supported paths.

Custom Tools with @agent.tool

Wrap the SDK calls your agent actually needs. Pydantic AI derives the tool schemas from the type hints and docstrings:

email_agent.py
import os
from pydantic_ai import Agent
from deadsimple import DeadSimple

client = DeadSimple(os.environ["DSE_API_KEY"])

agent = Agent(
    "openai:gpt-4o",
    system_prompt="You are an email assistant with a Dead Simple inbox.",
)

@agent.tool_plain
def send_email(inbox_id: str, to: str, subject: str, body: str) -> str:
    """Send a plain-text email from a Dead Simple inbox."""
    result = client.messages.send(inbox_id, to=[to], subject=subject, text_body=body)
    return f"Sent {result.message_id}"

@agent.tool_plain
def read_messages(inbox_id: str, limit: int = 5) -> list[dict]:
    """List the most recent messages in an inbox."""
    result = client.messages.list(inbox_id, limit=limit)
    return [
        {"from": m.from_email, "subject": m.subject, "snippet": m.snippet}
        for m in result.messages
    ]

@agent.tool_plain
def wait_for_verification_code(inbox_id: str, timeout: float = 120.0) -> dict | None:
    """Block until a verification email arrives, then return the OTP / magic link."""
    return client.messages.wait_for_verification(inbox_id, timeout=timeout)

result = agent.run_sync(
    "Check inbox inb_a1b2c3 and summarize anything new, then reply to the "
    "most recent message thanking the sender."
)
print(result.output)

Use @agent.tool (with a RunContext first argument) instead of @agent.tool_plain when you want to pass the Dead Simple client through deps rather than module scope — handy for testing with a fake client.

Zero Wrapper Code: the MCP Toolset

Pydantic AI has first-class MCP client support — MCP servers plug in as toolsets. Point it at Dead Simple's hosted server and the agent gets all 14 email tools with no wrapper functions at all:

mcp_agent.py
import os
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP

deadsimple = MCPServerStreamableHTTP(
    url="https://api.deadsimple.email/mcp",
    headers={"Authorization": f"Bearer {os.environ['DSE_API_KEY']}"},
)

agent = Agent("openai:gpt-4o", toolsets=[deadsimple])

async def main():
    async with agent:
        result = await agent.run(
            "Create an inbox called 'signups', use it to register for "
            "the newsletter at example.com, and read back the "
            "confirmation email."
        )
        print(result.output)

Prefer a local process? MCPServerStdio("python", args=["-m", "deadsimple.mcp"], env={"DSE_API_KEY": "..."}) runs the same server over stdio — install it with pip install "deadsimple-email[mcp]". The available tools are 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.

Why Dead Simple Fits Pydantic AI

  • Typed all the way down. The SDK returns dataclasses, your tools return typed values, and Pydantic AI validates the model's arguments — no dict-of-strings soup.
  • OTP flows without parsing. wait_for_verification blocks until a code arrives and hands back the extracted OTP or magic link — the fiddliest part of agent signup flows, done in one call.
  • Real two-way inboxes. Agents get actual addresses that receive mail, with threading, webhooks, and a dashboard — not a send-only relay.
  • Deliverability handled. SPF, DKIM, DMARC, and bounce monitoring run on the Dead Simple side.
  • Free plan is enough to build. Five inboxes and 5,000 emails/month, no card required.

FAQ

No — and it doesn't need one. Pydantic AI builds tool schemas from ordinary Python type hints and docstrings, so wrapping the deadsimple-email SDK with @agent.tool is a few honest lines per tool. If you want zero wrapper code, attach the hosted MCP server as a toolset instead.

Custom @agent.tool functions give you a hand-picked surface, your own docstrings, and full control over return shapes — best for production agents. The MCP toolset gives you all 14 email tools in three lines — best for prototypes and agents that should decide for themselves. Both talk to the same API.

Expose the SDK's wait_for_verification method as a tool. It blocks until a verification email arrives in the inbox, then returns the extracted OTP or magic link, so the agent can complete signups without parsing raw email.

Any model Pydantic AI supports — OpenAI, Anthropic, Google, Groq, Mistral, Bedrock, and local models. The email tools are plain Python functions or MCP tools; nothing is model-specific.

5 inboxes and 5,000 emails per month, no credit card required — enough to develop and run a small Pydantic AI agent in production.

Related Integrations

  • LangChain — native Dead Simple toolkit (shipped adapter)
  • OpenAI Agents SDK — native adapter for OpenAI's agent framework
  • Agno — custom email toolkit in another Python-first framework
  • Strands Agents — the same pattern with AWS's @tool decorator
  • MCP Server — the server behind the toolset option
  • Python SDK — the client these tools wrap

Ready to build?

Create a free account and give your Pydantic AI agent an inbox in minutes. Free tier: 5 inboxes, 5,000 emails/month, no credit card.

API Reference Get Started Free