Testing Email with SMTP and MCP
By Denis · Published 2026-09-15.
There are two ways to make Tempx part of your test suite: point your application at an SMTP sandbox so every message it sends gets captured instead of delivered, or connect an AI agent over MCP so it can watch an inbox, read verification codes and compose test mail on its own. Both paths end in the same place, one disposable inbox that collects everything, shows the original recipients, and never leaks a single real email.
The model: capture, never deliver
Test runs should never send mail to real addresses. Tempx is a capture trap: your app authenticates with a personal test credential, the gateway accepts any recipient (to:, cc:, bcc:, any domain), and the message is stored in the inbox paired with that credential. The original headers are preserved so you can assert exactly what would have been sent, and nothing ever leaves the sandbox.
Path 1: SMTP sandbox for your application
Use this when your code sends the mail: framework mailers, background jobs, integration tests. Create a persistent inbox and an SMTP credential on the account page (the password is shown once), then point your mailer at the gateway:
MAIL_MAILER=smtp MAIL_HOST=smtp.tempx.uk MAIL_PORT=587 MAIL_USERNAME=tmtp_x9f3… YOUR_USERNAME MAIL_PASSWORD=YOUR_PASSWORD MAIL_ENCRYPTION=tls
Now send to any address, customer@example.com, ops@some-corp.net, a list of them. The gateway answers 250, captures the message, and it appears in the paired inbox within seconds with the original To/Cc intact and Bcc recorded on the envelope. Limits: up to 25 recipients per message, 10 MB per message. Your test assertions read the captured copy; your staging environment never emails a human again.
Path 2: MCP for AI agents and QA bots
Use this when an agent does the work: signing up on a site, completing an email-verification step, or watching a mailbox as part of a longer workflow. Pair from the account page (or the one-command Claude pairing): the connection is scoped to one inbox, carries explicit permissions (read, search, wait, optional send), expires on a date you choose, and can be revoked instantly.
The agent then gets a small toolbox: list_emails, get_email, search_emails, wait_for_email (a server-side long-poll that returns the moment a matching message arrives), and with the send permission send_email, which composes mail to up to 10 recipients and captures it in the same inbox, Mailtrap-style:
tools/call wait_for_email
{ "from_contains": "noreply@saas-app.test",
"subject_contains": "Verify",
"timeout_seconds": 60 }
tools/call send_email
{ "to": ["qa@example.com", "lead@example.com"],
"subject": "Trial started",
"text": "Welcome aboard - this copy is captured, not delivered." }
Because the token is scoped to one mailbox, a leaked or over-eager agent can never read anything else, and because sending is capture-only it cannot be abused to spam anyone.
A full agent test, end to end
The pattern below is the whole reason the MCP surface exists: an agent that completes a real sign-up flow without a human forwarding codes by hand.
Which path should you use?
| SMTP sandbox | MCP connection | |
|---|---|---|
| Best for | Your app, framework mailers, CI integration tests | AI agents, QA bots, interactive workflows |
| Credential | tmtp_… username + password | tmcp_… scoped token |
| Recipients | Any domain, up to 25 per message | Any domain, up to 10 per message |
| Reading mail | Inbox web UI or API | First-class: wait_for_email long-poll, search, get |
| Scope | One inbox per credential | One inbox per token, with permissions + expiry |
They compose: run your app against the SMTP credential and let the agent watch the same inbox over MCP when a test needs both sides.
Good practice
- One inbox per project or test suite, captured mail from different runs stays separable.
- Rotate credentials per environment (staging vs CI); regenerating a password invalidates the old one at once.
- Give agent connections the shortest expiry that works, and the
sendpermission only when the workflow composes mail. - Never move an account you want to keep onto a disposable address, sandboxes are for flows you are testing, not accounts you depend on.
Related: Ask AI to test your email · Testing email flows with a disposable inbox · Give your email to your AI agent · Testing Resend emails
Ports, TLS, and network reality
The gateway listens where submission clients expect it: port 587 with STARTTLS as the primary path, and 2525 as the fallback for networks (hotel wifi, corporate egress, some CI providers) that quietly block or hijack the classic submission ports. Both ports speak the same protocol and accept the same credentials; the only difference is the number. Authentication is live-validated: the gateway checks credentials against the API on every session, so a revoked credential stops working at once rather than at some cache boundary.
Certificate hygiene matters for test suites that verify TLS: the gateway presents a real, publicly-trusted certificate, so strict clients pass without disabling checks, and any test that fails certificate verification on 587 is telling you about the network path, not the gateway. Keep that signal on; it is a free canary for the interception middleboxes that love submission ports.
Credential lifecycle for teams
SMTP credentials are personal and paired: each tmtp_ username captures into exactly one inbox, shown once at creation, revocable from the account page. The team discipline that scales: one credential per environment and per developer, named for its owner ("tempx-staging-ci", "tempx-anna-dev"), so a leaked or stale credential is identifiable from logs alone and revocation never collateral-damages a teammate's running suite.
Rotation is mint-and-replace rather than edit: create the new credential, update the one secret store that feeds your environments, revoke the old one, and move on. Because credentials validate live, the swap is atomic from the test suite's perspective, no propagation window, no half-deployed state. The limit worth knowing: a bounded number of active credentials per account, which keeps the hygiene honest and forces cleanup instead of accretion.
Choosing the path, in one breath each
The two paths serve different hands. SMTP capture for the code you already own: frameworks, libraries, legacy apps, anything that speaks SMTP natively and should keep believing it is sending. MCP for the things that reason: agents, exploratory test sessions, automations that need to wait and decide. The overlap is real but small, an agent can call create_smtp_credential to hand your app a credential, which is the bridge: the agent sets up, the app sends, both read the same captured inbox.
With both workable, pick the boring one: SMTP for deterministic pipelines, MCP whenever the words "wait for" or "check whether" appear in the requirement. The inbox at the end is identical either way, which is why mixing paths per workflow costs nothing.
Set up your test inbox
Create an inbox, mint an SMTP credential, pair an agent, all under a minute.
Open account Try the inbox