Skip to content

TestingTransactionalAgentic

Mail for your tests, your app and your agents.

Give every test its own inbox. Send receipts from your domain and read the replies. Let agents sign in over MCP. One inbox model, one API, one key.

$npm i @mailwurf/e2e @mailwurf/transactional

Three products, one mailbox

Pick the job. The inbox underneath stays the same.

Email testing

Every test gets its own inbox.

Your app keeps sending through Resend or SES. The test creates an address, waits for the message and opens the link. Only the recipient changes, so provider, template and DNS are covered too.

  • Mail arrives over real MX, from the provider your users get mail from.
  • One inbox per worker. Parallel runs never read each other’s mail.
  • The wait lives on the server, up to 120 seconds. No polling, no sleep.
  • Links and OTP come back parsed. The raw MIME stays next to them.
Read the @mailwurf/e2e docs
tests/signup.spec.ts@mailwurf/e2e
const inbox = await mailwurf.createInbox();

await page.fill("[name=email]", inbox.address);
await page.click("text=Sign up");

const mail = await inbox.waitFor({
  subject: "Confirm your email",
  timeout: 15_000,
});

expect(mail.otp).toMatch(/^\d{6}$/);
await page.goto(mail.links[0]);
Waited for the mailArrived after 1.4 s
SubjectConfirm your email
Linkyourapp.com/confirm?t=ey…
Code418902
Underneath

It’s just inboxes.

Tests, apps and agents all work with the same object. Learn it once and use it three ways, with the same key, the same dashboard and the same raw MIME.

  • INBOX

    Temporary or permanent

    Tests create inboxes that expire. Apps and agents register permanent addresses on your domain.

  • /v1

    One HTTP API

    The same endpoints for reading, waiting and sending. A bearer key, nothing else.

  • /mcp

    One MCP server

    The same mailbox, exposed as tools. OAuth for people, not keys in prompts.

  • MX

    Real delivery

    STARTTLS on our MX, your DNS for sending. Unknown recipients get a clean 550.

Developers

A small API, on purpose.

Every call under /v1 takes your key as a bearer token. The TypeScript clients are thin fetch wrappers, so anything that speaks HTTP works the same way.

  • POST/v1/inboxes
  • GET/v1/inboxes/{id}/messages
  • GET/v1/inboxes/{id}/messages/wait
  • POST/v1/inboxes/{id}/messages
  • GET/v1/messages/{id}
  • DELETE/v1/inboxes/{id}
  • POST/mcp
Open the API reference
import { createMailwurf } from "@mailwurf/e2e";

const mailwurf = createMailwurf(process.env.MAILWURF_API_KEY!);
const inbox = await mailwurf.createInbox();

const mail = await inbox.waitFor({ subject: "Confirm" });
console.log(mail.otp, mail.links[0]);
MAILWURF_API_KEY=mw_live_…one per project
Pricing

Three plans. Prices land with the public launch.

Mailwurf is in private access while we finish billing. Tell us what you want to test, send or automate and we’ll tell you which plan fits.

Trial

For the first spec or the first send, on the shared domain.

Pricing to be announced

  • Inboxes on mail.mailwurf.io
  • Short message retention
  • One API key
Ask about Trial

Team

Most teams

For suites on every pull request and apps that send daily.

Pricing to be announced

  • Sending domains and permanent addresses
  • Several keys, one per project
  • MCP access for the whole organization
Ask about Team

Dedicated

For teams that need their own MX name and isolation.

Pricing to be announced

  • Your domain on our MX
  • Isolated storage
  • Support agreement and DPA
Ask about Dedicated
FAQ

Questions that come up first

How is testing different from Mailpit or Mailhog?

Those are SMTP sinks you point your app at, so the test never exercises Resend, SES, your templates or your DNS. Mailwurf receives on real MX, so only the recipient changes and the rest of the path stays production.

Do I have to change my app to test it?

No. The app keeps its provider, credentials and templates. The test sets the recipient to an inbox address it created a moment earlier.

Can I send from my own domain?

Yes. Add it as a sending domain in the dashboard and publish its DNS records. Your existing mail provider keeps receiving for that domain.

Where do replies to transactional mail go?

Every sending address is a Mailwurf inbox. Replies arrive there and can be read through the API, the dashboard or an agent.

How does an agent authenticate?

Over OAuth, as a user of your organization. Access tokens last an hour and are scoped to mailbox tools. API keys never go into a prompt.

What does it cost?

Pricing isn’t public yet. Write to us with what you want to test, send or automate and we’ll tell you which plan fits.

Bring your flakiest test, your next receipt or your first agent.

Tell us what you’re building and we set up an organization and a key. One call later, mail is the boring part again.

The Mailwurf mole holding an envelope