SMTP server
MailBox Ultra implements just enough of RFC 5321 to play nice with every mainstream sender library and CLI we've tested. The list below is exhaustive — anything not on it returns 500 5.5.2.
#Supported verbs
| Verb | Behaviour |
|---|---|
HELO |
Records that the client greeted; replies 250. |
EHLO |
Returns the multi-line capability list (see below). |
MAIL FROM:<addr> |
Stores the envelope sender. Empty <> is allowed (RFC 5321 null sender). |
RCPT TO:<addr> |
Stores one envelope recipient. Repeat for each recipient. |
DATA |
Reads body until \r\n.\r\n, dot-unstuffs, parses MIME, stores. |
RSET |
Clears the envelope. |
NOOP |
Returns 250. |
QUIT |
Returns 221 and closes. |
HELP |
Lists the supported verbs. |
VRFY |
Returns 252 (per RFC, "cannot verify but will accept"). |
AUTH PLAIN | LOGIN |
See authentication. |
STARTTLS is intentionally absent. MailBox Ultra is a local-only tool — the listener only ever binds 127.0.0.1 unless you change the bind address in Preferences, so wrapping plaintext in TLS would be ceremony with no security benefit. There is no plan to implement legacy SOML, SAML, EXPN, or TURN.
#EHLO capabilities
250-MailBoxUltra hello
250-PIPELINING
250-8BITMIME
250-SMTPUTF8
250-SIZE 26214400
250-AUTH PLAIN LOGIN (only when "Require AUTH" is enabled)
250 HELPSIZE mirrors the Max message size field in Preferences (default 25 MiB).
#Authentication
By default, no AUTH is advertised and the server accepts anyone. To require credentials:
- Open Preferences with
⌘,. - Under the SMTP section, tick Require AUTH.
- Fill in User and Password.
- Click Apply.
The SMTP listener restarts in place; existing captured messages are preserved. After Apply, attempting MAIL FROM before authenticating returns:
530 5.7.0 authentication requiredBoth AUTH PLAIN and AUTH LOGIN are supported, in initial-response and prompt-response forms.
#AUTH PLAIN
Inline form:
C: AUTH PLAIN AGFsaWNlAHMzY3JldA==
S: 235 2.7.0 authentication successfulOr two-step:
C: AUTH PLAIN
S: 334
C: AGFsaWNlAHMzY3JldA==
S: 235 2.7.0 authentication successfulWrong credentials get 535 5.7.8.
#AUTH LOGIN
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6 (Username:)
C: YWxpY2U= (alice)
S: 334 UGFzc3dvcmQ6 (Password:)
C: czNjcmV0 (s3cret)
S: 235 2.7.0 authentication successfulThe server is permissive about case and whitespace. Initial-response form (username on the same line as AUTH LOGIN) is also accepted, as that's what some older clients send.
#Size limits
The Max message size field in Preferences sets the cap. Oversize bodies get 552 5.3.4 after the data is consumed so the client receives a clean response. The captured envelope is reset on rejection — RSET semantics, automatically.
#Capture vs. delivery
Plain capture: nothing is delivered, the message lands in the in-app inbox, and the SMTP transaction returns 250 2.0.0 message accepted.
With Forward each captured message upstream ticked under Relay, the same flow runs and a relay task hands the message to the upstream MTA. If the relay fails, the captured message is still in the inbox; the failure is surfaced in the toolbar relay pill. See relay mode for details.
#Hostname
The Hostname field in Preferences controls what the server announces in the 220 greeting and the 250 NAME hello response. Default is MailBoxUltra. Some sender libraries pin to a specific hostname for testing; this is the knob.
#Rejected verbs
Anything outside the supported list returns:
500 5.5.2 unrecognised command: FOOEmpty lines return 500 5.5.2 syntax error: empty command. Malformed MAIL/RCPT parameters return 501 5.5.4 syntax: ....
#Wire-level testing
Want to poke the protocol by hand? Use nc:
nc -C 127.0.0.1 1025Type EHLO me, MAIL FROM:<a@x>, RCPT TO:<b@x>, DATA, the body, ., QUIT. The inbox updates in real time.