Building MailForge: a Self-Hosted Email Desk for Verification, Campaigns and a Unified Inbox
Hosted email verifiers take your list and talk to recipient mail servers somewhere else. I wanted the list, the SMTP check and the replies to stay on a machine I run. That is what MailForge is for.
MailForge is a self-hosted email desk. You upload a CSV or spreadsheet, a Go verifier talks to the recipient server, valid rows can become a campaign from accounts you add, and answers come back to one inbox. MongoDB on that same machine stores the data.
The public repo is MIT licensed. The package version on main is 1.4.2. This article describes only what is in that repository - the README, setup guides and package.json. It is not a claim about production volume, clients or deliverability.
Why run the check yourself?
Mailbox verification works by talking to the recipient's mail server: syntax and MX first, then a live SMTP RCPT dialog when that path is available. If you use a hosted verifier, that conversation happens on their infrastructure, and the list leaves your machine. MailForge keeps that work local.
The default engine is truemail-go, which lives under backend/go/ in the repo. You can set VERIFIER_ENGINE=auto so the app falls back to Reacher when the Go verifier is down.
The full Docker Compose file starts the web app and MongoDB together. The slimmer docker-compose.yml starts the optional Reacher verifier; the README tells you to use the full compose file when you want the app itself.
What you can do with it
The README lists the desk's jobs in one place:
- Verify an address with syntax, MX, disposable and role checks, and a live SMTP RCPT dialog.
- Run a bulk CSV or XLSX job, pause or resume it, and download rows before the job finishes.
- Send a campaign through more than one account, with delays, warm-up fields, a suppression list and an optional unsubscribe link.
- Start from templates shipped in the repo, including 10 freight subjects and 10 bodies, or draft copy when a Groq, OpenRouter or OpenAI key is set.
- Read and reply from a unified IMAP inbox. Sign-in uses JWT. The UI includes a dark theme.
- Check
GET /api/healthfor version, database and verifier status, andGET /api/backup/exportfor a JSON download of your data.
Those health and backup endpoints matter if you treat this as a local desk rather than a throwaway script. Settings in the Windows setup guide also point at a "Download my data" path and an npm run mongo:backup script for moving a database to another PC.
Start it on your machine
The shortest path in the README is Docker:
docker compose -f docker-compose.full.yml up -d --build
Open http://localhost:5000 and register. That command starts MongoDB and the web app. The compose file points the app at that MongoDB service and sets INDUS_SKIP_LICENSE=1, so a local stack starts without a license file.
A Windows client install is documented separately in client.md. That path still expects an indus-license*.json file. The two modes are easy to mix up: Docker on a development machine can skip the license; a packaged client install does not.
From a source checkout, the README asks for Node.js 18 or newer and Go 1.22 or newer. Copy .env.example to .env, set JWT_SECRET and ENCRYPTION_KEY, then run npm install and INDUS_SKIP_LICENSE=1 npm start. The Express app listens on port 5000 by default. If that port is already in use, the Windows setup guide says to set PORT=5001 in .env.
A slightly longer Windows setup
SETUP.md is a checklist for a fresh Windows PC. The required tools are Node.js 18+ LTS, Docker Desktop (for persistent data), Go 1.22+ (for the SMTP verifier) and Git. MongoDB Compass is optional if you want to browse mongodb://127.0.0.1:27017/mailforge.
You can run npm run setup:new-pc after cloning. That script checks Node.js, Docker and Go, runs npm install and go mod tidy, copies .env.example to .env if the file is missing, pulls and starts MongoDB via Docker, and can build a MailForge.exe launcher when .NET Framework is present.
For production-like use, the same guide tells you to replace JWT_SECRET with a long random string (it describes a 64-character secret) and ENCRYPTION_KEY with a 32-character random string, and to set MONGO_URI=mongodb://127.0.0.1:27017/mailforge.
If you send through Gmail, SETUP.md walks through Google app passwords: create an app password, then add the account under MailForge → Senders, or bulk-import a CSV with Email, AppPassword and Name columns. Keep those secrets out of the repo.
When Docker is running, Settings → Connection should show persistent storage. If you see an in-memory banner instead, the guide says to run npm run mongo:up and restart. Daily start options include Start-MailForge.bat, MailForge.exe, or npm run start:easy.
How the repo is laid out
| Path | What it is |
|---|---|
server.js |
Express app on port 5000 |
public/ |
Browser UI |
controllers/ and routes/ |
HTTP API |
backend/go/ |
truemail-go SMTP verifier |
tests/ |
node --test suite |
CONTRIBUTING.md describes the fork, branch and test flow. Run npm test before a pull request. Bug and feature forms are in .github/ISSUE_TEMPLATE/. Screenshots of the signed-in dashboard and the shipped templates live under docs/screenshots/.
Windows client installs are a different path
client.md is the guide meant to travel with a MailForge folder. In that mode the web app still opens at http://localhost:5000, but the database is an embedded MongoDB and Docker is not required.
The client is expected to receive a folder named MailForge plus a license file whose name starts with indus-license and ends with .json. Double-clicking Client-Install-MailForge.bat installs production Node packages, builds the local Go verifier executable, downloads an embedded MongoDB binary into tools/mongodb-binaries, stores app data in data/mongodb, and creates Desktop and Start Menu shortcuts.
On startup, that build verifies the INDUS license online and can then tolerate short internet outages with a local license cache. If the app reports that no license file was found, the file belongs in the app folder or the data folder.
I mention this only because the Docker README path and the client path are both in the repo, and they do not use the same license rule.
What this article does not claim
The repo does not publish inbox placement rates, list sizes from real campaigns, or client names. It ships freight-themed starter templates; that is a starting point for copy, not a statement about any freight company.
SMTP still depends on outbound network access. If you cannot reach recipient servers, a live mailbox dialog will not complete. Use the tool on lists you are allowed to check, and keep JWT and encryption secrets private.
FAQ
What is MailForge?
MailForge is a self-hosted email desk. It verifies lists, can send campaigns from accounts you add, and reads replies in a unified IMAP inbox. The source is github.com/mafzalkalwardev/mailforge.
Who built it?
Muhammad Afzal Kalwar (@mafzalkalwardev).
Which checks run on each address?
Syntax, MX, disposable and role checks, plus a live SMTP RCPT dialog. truemail-go is the default engine.
Can I use a second verifier?
Yes. Set VERIFIER_ENGINE=auto to fall back to Reacher when the Go verifier is down. The default docker-compose.yml starts the optional Reacher service; use docker-compose.full.yml to start the app and MongoDB.
Does a local Docker install need a license file?
The full compose file sets INDUS_SKIP_LICENSE=1, so that local stack starts without a license file. A Windows client install still expects indus-license*.json.
What do I need to run it from source?
Node.js 18 or newer, Go 1.22 or newer, a .env file with JWT_SECRET and ENCRYPTION_KEY, then npm install and INDUS_SKIP_LICENSE=1 npm start. Docker is the documented path for persistent MongoDB.
Where is the data stored?
MongoDB on the machine you run. The full compose file starts that database next to the app. There is a JSON export at GET /api/backup/export, and the Windows guide also documents npm run mongo:backup.
What is the license?
MIT. See LICENSE in the repository.
Where can I read more?
The README covers features and the HTTP API. SETUP.md is the new-PC checklist. client.md is the Windows client install guide. Source: https://github.com/mafzalkalwardev/mailforge
Comments
No comments yet. Start the discussion.