CrewAI lets you define agents with specific roles and tools. Adding email tools gives your crew the ability to handle verification flows, send notifications, and receive external input via email.

Create Custom Email Tools

from crewai import Agent, Task, Crew
from crewai.tools import BaseTool
import httpx

BASE = "https://api.agentmailr.com"
KEY = "ak_your_key"
HEADERS = {"X-API-Key": KEY, "Content-Type": "application/json"}

class CreateInboxTool(BaseTool):
    name: str = "create_inbox"
    description: str = "Create a new email inbox. Returns the inbox ID and email address."

    def _run(self, name: str = "") -> dict:
        r = httpx.post(f"{BASE}/v1/inboxes", headers=HEADERS, json={"name": name})
        return r.json()

class WaitForOtpTool(BaseTool):
    name: str = "wait_for_otp"
    description: str = "Wait for an OTP verification code to arrive in an inbox. Pass the inbox_id."

    def _run(self, inbox_id: str, timeout: int = 60) -> str:
        r = httpx.get(
            f"{BASE}/v1/inboxes/{inbox_id}/otp",
            headers=HEADERS,
            params={"timeout": timeout},
            timeout=timeout + 5
        )
        data = r.json()
        return data.get("code", "No OTP found")

class SendEmailTool(BaseTool):
    name: str = "send_email"
    description: str = "Send an email from an inbox. Requires inbox_id, to, subject, and text."

    def _run(self, inbox_id: str, to: str, subject: str, text: str) -> dict:
        r = httpx.post(
            f"{BASE}/v1/inboxes/{inbox_id}/send",
            headers=HEADERS,
            json={"to": to, "subject": subject, "text": text}
        )
        return r.json()

Define an Agent with Email Tools

registration_agent = Agent(
    role="Account Registration Specialist",
    goal="Register for web services using provided email addresses and handle verification",
    tools=[CreateInboxTool(), WaitForOtpTool(), SendEmailTool()],
    verbose=True
)

registration_task = Task(
    description="Register for the service at https://example.com. Create an inbox, fill the signup form, and complete email verification.",
    agent=registration_agent
)

crew = Crew(agents=[registration_agent], tasks=[registration_task])
result = crew.kickoff()

MCP Alternative

If you are using CrewAI with Claude as the underlying model, you can also connect AgentMailr via MCP instead of writing custom tools. The MCP server exposes all tools natively.