Documentation

Read the docs

Everything you need to run MailMock — from a single Docker command to the full stack with ClamAV and Rspamd.

Quick start

Point your app's outgoing mail at MailMock and inspect every captured message in the browser.

# run MailMock (in-memory storage, built-in analyzers) docker run -d --name mailmock \ -p 8080:8080 \ -p 1125:1125 \ justmediapl/mailmock:latest

Then

  • Point your application's SMTP client at localhost:1125 (no TLS, no auth).
  • Send some mail from your app.
  • Open the web UI at http://localhost:8080 to see captured messages.
Nothing is delivered anywhere — mail sent to MailMock is captured, parsed and displayed. It's a single-tenant developer tool meant to run in your own environment.

Sending & viewing mail

Any SMTP library works — set host and port, send, and the message is captured.

Sending mail

Point your SMTP client at MailMock's SMTP port (default 1125). No TLS and no authentication. For a Spring Boot app, for example:

spring.mail.host=localhost spring.mail.port=1125

Viewing messages

Open the web UI (default http://localhost:8080). The home page lists captured messages; use the search box to filter by subject, sender, recipient or body. Click a message to open it — with tabs:

  • Plain — text body.
  • Attachments — downloadable files.
  • Headers — all MIME headers.
  • View — the original HTML rendered in a sandboxed iframe (scripts disabled, remote resources blocked).
  • Analysis — the spam / spoofing / virus verdicts.

Delete a single message, or use Clear all. New mail is pushed over WebSocket (SockJS/STOMP, endpoint /ws, topic /topic/messages) — the UI shows a toast and refreshes automatically.

REST API

Base path /api. Responses are JSON. Interactive docs: Swagger UI at /swagger-ui.html.

MethodPathParametersReturns
GET/api/messagespage, sizePage of messages
GET/api/messages/searchsearch, page, sizeMatching messages
DELETE/api/messages/clearDelete all
POST/api/messages/chaos/togglechaosEnabledToggle chaos mode
GET/api/messages/chaosCurrent chaos state
GET/api/message/{id}Single message + analysis
PUT/api/message/{id}/readMark read
PUT/api/message/{id}/unreadMark unread
GET/api/message/{id}/{partId}Attachment bytes
DELETE/api/message/{id}Delete one

Example

# list the latest messages curl "http://localhost:8080/api/messages?page=0&size=10" # search curl "http://localhost:8080/api/messages/search?search=invoice" # turn chaos mode off curl -X POST "http://localhost:8080/api/messages/chaos/toggle?chaosEnabled=false"
Analysis runs asynchronously, so immediately after a message arrives analysis may briefly be null before the verdicts are filled in.

Mail analysis

Every captured message is analyzed asynchronously across three dimensions, shown in the Analysis tab and the REST API.

Spam

LOWMEDIUMHIGH

A score 0–100 with a level and the reasons that contributed (spam keywords, ALL-CAPS, excessive links, sender/header anomalies).

Spoofing

PASSSUSPICIOUSFAIL

From header heuristics: From vs Return-Path / envelope mismatch, display-name spoofing, Authentication-Results failures, punycode look-alike domains and From vs Reply-To divergence.

Virus

CLEANSUSPICIOUSINFECTED

Attachment scanning for the standard EICAR test signature and risky file extensions.

Built-in vs external engines

The built-in analyzers are heuristic and run in-process with no dependencies — the Analysis tab is always populated. You can additionally enable real ClamAV (virus) and Rspamd (spam). When an external engine is enabled and reachable, its verdict replaces the built-in one; if it's unreachable, MailMock falls back to the built-in result.

Configuration

MailMock is configured entirely through environment variables, with sensible defaults.

Ports & server

VariableDefaultDescription
APP_PORT8080HTTP port for the web UI and REST API.
SMTP_PORT1125Port the SMTP server listens on.
PROFILESSpring profiles to activate.

Storage

VariableDefaultDescription
DB_ENGINEinMemoryStorage back-end: inMemory or mongo.
MESSAGES_LIMIT500Max stored messages; oldest evicted past the limit.
MONGO_HOSTlocalhostMongoDB host (when DB_ENGINE=mongo).
MONGO_PORT27017MongoDB port.
MONGO_DB / MONGO_USER / MONGO_PASSsmtpMongoDB database, username and password.

Chaos mode

VariableDefaultDescription
CHAOS_MODE_ENABLEDtrueEnable the ChaosEngine (random SMTP errors).
CHAOS_MODE_LATENCY5Inject an error roughly every Nth connection.

Analysis

VariableDefaultDescription
ANALYSIS_THREADS4Thread-pool size for asynchronous analysis.
ANALYSIS_SPAM_ENABLEDtrueBuilt-in heuristic spam scoring.
ANALYSIS_SPOOFING_ENABLEDtrueBuilt-in header-based spoofing detection.
ANALYSIS_VIRUS_ENABLEDtrueBuilt-in virus checks (EICAR + risky extensions).
ANALYSIS_CLAMAV_ENABLEDfalseUse ClamAV for virus scanning when reachable.
ANALYSIS_SPAM_RSPAMD_ENABLEDfalseUse Rspamd for spam scoring when reachable.
External engines are off by default. ClamAV/Rspamd also accept _HOST, _PORT, _URL and _TIMEOUT variables — see Self-hosting.

Self-hosting

MailMock ships as a Docker image. Run a single container, or the full stack with real ClamAV and Rspamd.

Single container (recommended)

docker run -d --name mailmock \ --restart unless-stopped \ -p 8080:8080 -p 1125:1125 \ -e DB_ENGINE=inMemory \ justmediapl/mailmock:latest

Web UI on http://localhost:8080, SMTP on localhost:1125. In-memory storage, built-in analyzers enabled, a few hundred MB of RAM.

Persistence with MongoDB

docker run -d --name mailmock \ -p 8080:8080 -p 1125:1125 \ -e DB_ENGINE=mongo \ -e MONGO_HOST=mongo -e MONGO_PORT=27017 \ -e MONGO_USER=smtp -e MONGO_PASS=smtp -e MONGO_DB=smtp \ justmediapl/mailmock:latest

Full stack with ClamAV + Rspamd

The repository includes docker/docker-compose.yml, which runs MailMock together with ClamAV, Rspamd and MongoDB:

docker compose -f docker/docker-compose.yml up --build
ClamAV loads its signature database into memory, so the full stack needs roughly 2–3 GB of RAM. On first start it downloads the database (a minute or two) before it becomes healthy.

Security model

MailMock is a single-tenant developer tool with no authentication by design (like MailHog/Mailpit) — anyone who can reach the web UI or SMTP port can read and delete captured mail. Don't expose it to untrusted networks; if you must, put it behind your own reverse proxy. Captured HTML is always rendered in a sandboxed iframe, so untrusted mail cannot execute scripts in your browser.