Skip to content

MCP wait_for_email

wait_for_email blocks until a matching message arrives or the timeout expires. It is read-only and requires access to the target inbox.

{
"inbox": "pmbx_…", // required: opaque id or project-local address
"from": "no-reply@acme.test", // optional sender substring
"subject": "verification", // optional subject substring
"regex": "(?i)code", // optional Go RE2 expression
"link_hint": "verify", // optional URL preference, not a match filter
"since_now": true, // default: ignore earlier messages
"timeout_ms": 120000 // default 120s, maximum 600s
}

regex is case-sensitive unless it includes (?i). The MCP server sends it to the REST match field. link_hint biases verification-link extraction after a message matches.

{
"matched": true,
"message": {
"id": "msg_8Tz",
"thread_id": "thr_9aB",
"inbox": "support@extrovertmail.com",
"direction": "inbound",
"from": { "email": "no-reply@acme.test" },
"subject": "Verify your email",
"text": null,
"html": "<p>Your code is <strong>492013</strong></p>",
"extracted_text": null,
"extracted_html": "<p>Your code is <strong>492013</strong></p>",
"folder": "INBOX",
"seen": false
},
"otp_code": "492013",
"verification_link": "https://acme.test/verify?token=…",
"waited_ms": 8421
}

On timeout, the tool returns matched: false with waited_ms. This is a normal result. The agent can retry, extend the timeout, or trigger another verification email.

The structured message preserves source MIME alternatives:

  • text is source plain text and may be null.
  • html is source HTML and may be null.
  • extracted_text and extracted_html are nullable, best-effort derivatives.

The server does not synthesize one source format from the other. The top-level otp_code and verification_link are credential extraction results, not replacements for the message body fields.

Use get_message with variant: "source" when exact content matters. Use variant: "extracted" for a concise presented body when quote and signature removal is acceptable. The structured result keeps the separate fields in either case.

The server checks for newer message ids on a bounded interval. A matching message can therefore arrive shortly before the tool returns. since_now: true records a baseline at the start and prevents an older message from satisfying a new workflow.

Keep the wait budget close to the external workflow’s actual expiry. Custom MCP transports and proxies must allow a read timeout longer than timeout_ms; the packaged server already does.