Integration
Browser Use + Email Verification Codes
Give self-hosted Browser Use agents a real inbox for signup emails and OTPs: a @tools.action custom tool that waits for the verification code, plus an MCP option.
The Problem Every Browser Agent Hits
Browser Use (YC W25, roughly 109k GitHub stars as of August 2026) is the most popular way to let AI agents drive a real browser — and almost every real-world browser task runs into the same wall: the site sends an email. Signup confirmations, one-time codes, magic links, receipts. The browser agent can fill every form on the internet, but it still needs an address that receives mail and a way to pull the code out.
Browser Use Cloud ships a built-in inbox for exactly this reason, and if you run there it works well. This page is for the other half of the community: teams running the open-source library self-hosted, who need to bring their own email provider — and teams who want inboxes they control regardless of where the browser runs. A Dead Simple inbox is a persistent, API-managed address with built-in OTP and magic-link extraction, a dashboard over every message, and the same account shared with the rest of your agent stack.
Custom Tools with @tools.action
Register two small actions: one that tells the agent which email address to type into signup forms, and one that waits for the verification email and returns the extracted code:
import os from browser_use import Agent, Tools from deadsimple import DeadSimple dse = DeadSimple(os.environ["DSE_API_KEY"]) inbox = dse.inboxes.create(display_name="signup-bot") tools = Tools() @tools.action(description="Get the email address to use for signups") def get_signup_email() -> str: return inbox.email @tools.action( description="Wait for the verification email and return the OTP code " "or magic link. Call after submitting a signup form." ) def get_verification_code(from_contains: str = "") -> str: result = dse.messages.wait_for_verification( inbox.inbox_id, from_contains=from_contains, timeout=120 ) if not result: return "No verification email arrived within 120 seconds." return result.get("verification_code") or result.get("magic_link_url", "") agent = Agent( task="Sign up for a free account at example.com using the signup " "email address, then complete verification with the emailed code.", llm=llm, # any Browser Use-supported model tools=tools, ) agent.run_sync()
The flow at runtime: the agent calls get_signup_email, types the address into the form, submits, calls get_verification_code — which blocks until the email lands and returns the parsed OTP or magic link — and finishes verification in the browser. No IMAP polling, no regex over raw MIME, no throwaway mailbox that a target site has already blacklisted.
MCP Option
Browser Use can also act as an MCP client, pulling in tools from external servers alongside its browser actions. Register Dead Simple's MCP server and the agent gets the full 14-tool surface (create_inbox, send_email, wait_for_email, get_verification_code, get_verification_link, and more) with no custom actions:
# pip install "browser-use[mcp]" "deadsimple-email[mcp]" import os from browser_use import Agent, Tools from browser_use.mcp.client import MCPClient tools = Tools() deadsimple = MCPClient( server_name="deadsimple", command="python", args=["-m", "deadsimple.mcp"], env={"DSE_API_KEY": os.environ["DSE_API_KEY"]}, ) await deadsimple.connect() await deadsimple.register_to_tools(tools) agent = Agent( task="Create a fresh inbox, sign up for the beta at example.com " "with it, and verify using the emailed code.", llm=llm, tools=tools, ) await agent.run()
The snippet above uses the stdio server (API shown as of Browser Use 0.7). Any MCP-capable host can instead use the hosted server at https://api.deadsimple.email/mcp with the header Authorization: Bearer dse_your_api_key.
Why a Dead Simple Inbox for Browser Agents
- Built-in OTP extraction.
wait_for_verificationreturns the parsed code or magic link in one call — the single fiddliest step of signup automation, solved server-side. - Fresh or persistent — your choice. Spin up an inbox per run for clean-room signups, or keep one address alive so the accounts your agent creates stay reachable afterward.
- Not a disposable-mail domain. Inboxes live on real, deliverability-managed domains — not the throwaway TLDs signup forms already reject.
- Audit trail included. Every email your agent triggered is visible in the dashboard and queryable via API — useful when a run fails mid-verification.
- One provider across your stack. The same inboxes work from LangChain, Claude Agent SDK, Mastra, or plain REST — the browser agent doesn't get a silo.
FAQ
If you run on Browser Use Cloud and its inbox covers your flow, use it. This integration is for the open-source, self-hosted path — where no inbox is included — and for teams that want inboxes they control: persistent addresses that survive across runs, a dashboard and API over every message, webhooks, and the same inboxes shared with the rest of their agent stack.
Dead Simple extracts it for you. The SDK's wait_for_verification method (and the MCP get_verification_code tool) blocks until the verification email arrives, then returns the parsed OTP or magic link — the agent never sees raw MIME.
Yes — create an inbox per run with one API call (inboxes.create), or reuse a persistent inbox when you want the account to stay reachable after the run. The free tier includes 5 inboxes; paid plans scale to hundreds.
Yes. Browser Use can act as an MCP client, so you can register Dead Simple's MCP server (stdio via python -m deadsimple.mcp, or the hosted server at https://api.deadsimple.email/mcp) alongside its browser tools instead of writing custom actions.
5 inboxes and 5,000 emails per month, no credit card required — plenty for signup and OTP automation at development scale.
Related Integrations
- MCP Server — the server behind the MCP option
- Claude Agent SDK — the same verification tools in Anthropic's agent SDK
- Mastra — TypeScript agents with the same wait-for-email pattern
- Hermes Agent — email tools and an email channel for Nous Research's runtime
- Python SDK — the client these actions wrap