Installation
Two ways in, both first-class: a container, or a single binary dropped on your PATH by one command. Pick whichever you would rather operate.
One command
curl -fsSL https://mimux.dev/install.sh | bash
That installs the free client. For the pro build — the REST API, MCP,
webhooks and the mimux mail terminal client, with the 14-day
trial built in:
curl -fsSL https://mimux.dev/install.sh | bash -s -- pro
The script picks the right binary for your machine, checks its SHA-256
against the checksums.txt published with the release, and refuses
to install on a mismatch. It writes to /usr/local/bin when that is
yours to write to and ~/.local/bin otherwise; it never calls
sudo by itself. Builds cover Linux amd64 and arm64, and macOS on
both Intel and Apple Silicon.
Run it in a terminal (rather than through a pipe) and it asks which build you
want first. Useful flags:
--version v0.21.0 to pin,
--bin-dir DIR to choose where it lands,
--non-interactive to silence every prompt.
Read it before you run it — it is served as plain text at
mimux.dev/install.sh.
The split worth knowing about. Run the server in
docker, where it restarts with the host and upgrades with a
pull. Install the pro binary locally and use it purely
as a client — mimux mail login https://mail.example.com — so
your terminal talks to the instance you already run. One deployment, one
command line, no second server.
Docker Compose
services:
mimux:
image: ghcr.io/mattmezza/mimux:latest
ports:
- "8083:8083"
volumes:
- ./data:/data
environment:
- MIMUX_DB=/data/mimux.db
- MIMUX_BASE_URL=http://localhost:8083
# - MIMUX_SECRET=... # optional; auto-generated and persisted to /data/secret
- TZ=Europe/Zurich
restart: unless-stopped
docker compose up
Then open http://localhost:8083. Mount a
volume at /data — that directory is the entire installation.
Images
| Tag | What it is |
|---|---|
ghcr.io/mattmezza/mimux:latest | The free client, newest of everything. Moves across minor versions. |
ghcr.io/mattmezza/mimux:v0.21 | Recommended. Floating: stays on the 0.21 series and picks up every patch released in it. |
ghcr.io/mattmezza/mimux:v0.21.0 | An exact pin. Never moves. 0.21.0 without the v also works. |
ghcr.io/mattmezza/mimux:pro | The client plus the automation layer, newest of everything. |
ghcr.io/mattmezza/mimux:v0.21-pro | Recommended. The floating pro pin, same rule. |
ghcr.io/mattmezza/mimux:v0.21.0-pro | An exact pro pin. |
Releases are vMAJOR.MINOR.PATCH. The minor is
the unit that matters to you: it is what a pro licence is sold in, and what
the rest of these docs mean when they say a version. The
patch is just how a fix reaches you inside that minor.
So :v0.21 is the pin worth having — it keeps receiving fixes
without ever moving off the series you are on, or, if you have a pro licence,
off the one you paid for. Take :v0.21.0 instead when you want a
digest-stable image that changes only when you change it, and
:latest when you would rather always be on the newest thing.
The free and pro images are genuinely different builds, not one image with a feature switch: the free one does not contain the automation code at all. See The automation layer for the licence key, and Architecture for how the split is enforced.
Prebuilt binaries, by hand
The installer above is a wrapper around this. Every release attaches static
binaries for linux/amd64, linux/arm64,
darwin/amd64 and darwin/arm64, plus a
checksums.txt covering all of them:
| File | Build |
|---|---|
mimux-linux-amd64, mimux-linux-arm64, mimux-darwin-amd64, mimux-darwin-arm64 | Free client |
mimux-pro-linux-amd64, mimux-pro-linux-arm64, mimux-pro-darwin-amd64, mimux-pro-darwin-arm64 | Client + automation layer |
checksums.txt | SHA-256 of every file above, in sha256sum format |
curl -fsSLO https://github.com/mattmezza/mimux/releases/latest/download/mimux-linux-amd64
curl -fsSLO https://github.com/mattmezza/mimux/releases/latest/download/checksums.txt
sha256sum --ignore-missing -c checksums.txt
chmod +x mimux-linux-amd64 && ./mimux-linux-amd64
With no environment set it creates ./data/mimux.db and listens on
0.0.0.0:8083. ./mimux -version prints the version and
exits.
First run
- Open the base URL. The first visit is a wizard that creates the single admin account — this is the login for mimux itself, not for any mailbox.
- Settings → Accounts → Add account. Pick a provider preset (which fills in IMAP/SMTP hosts and ports) or enter hosts by hand, then either a password / app password, or OAuth2 — see below.
- The sync worker starts as soon as the account is saved. Add, edit and remove accounts at any time; changes take effect immediately, with no restart.
- Optional: Settings → Integrations for a Google Translate or OpenRouter key, Settings → Notifications, Settings → Filters.
Removing an account also deletes its downloaded folders and messages from mimux. Re-adding an account with the same name reattaches whatever is still on the server at the next sync.
Environment variables
These are the bootstrap settings — the ones that cannot live in the database, because they are needed to find it. Every one has a working default. Everything else is in the Settings GUI.
| Variable | Default | Description |
|---|---|---|
MIMUX_DB | ./data/mimux.db | SQLite database path, created if absent. |
MIMUX_HOST | 0.0.0.0 | Bind address. |
MIMUX_PORT | 8083 | Bind port. |
MIMUX_BASE_URL | http://localhost:<port> | Public URL. Used for OAuth redirects and links in email; an https:// value is what enables Secure cookies. |
MIMUX_SECRET | generated | Session and CSRF signing secret. When unset it is generated once and persisted to a secret file next to the database, so sessions survive restarts. |
MIMUX_AI_BASE_URL | OpenRouter | Any OpenAI-compatible chat-completions endpoint — another provider, or a local runner such as http://llama:8080/v1. /chat/completions is appended to the base. With this set, the OpenRouter key becomes optional. |
MIMUX_API_RATE_LIMIT | 120 | pro API requests per token per minute. 0 disables limiting. |
MIMUX_LICENCE_KEY | unset | pro Licence key. Takes precedence over the one saved in Settings → Licence. Free builds ignore it. |
It is MIMUX_LICENCE_KEY, with the British spelling and
the _KEY suffix. MIMUX_LICENCE is not read
by anything.
Run it behind HTTPS
Put mimux behind a reverse proxy (Caddy, nginx, Traefik) and set
MIMUX_BASE_URL to the public URL. Two things depend on it:
- Cookies are only marked
Securewhen the base URL starts withhttps://. - Web Push and the service worker are refused by browsers on an insecure
origin, so
http://<lan-ip>:8083cannot install as an app or deliver push. - OAuth callbacks must match the redirect URI registered with the provider exactly.
mimux is single-user with one admin password. Do not expose it to the internet without HTTPS and a strong password.
OAuth setup (Gmail, Zoho)
For accounts using OAuth2 — choose OAuth2 in the account editor:
-
Create an OAuth client in the provider console:
- Gmail —
Google Cloud Console →
APIs & Services → Credentials → Create OAuth client ID →
Web application. Enable the Gmail API for the project.
Requested scope:
https://mail.google.com/. - Zoho —
Zoho API Console →
Add Client → Server-based Application. Scopes:
ZohoMail.accounts.READ ZohoMail.messages.ALL. mimux uses the.comregion endpoints; adjustinternal/mail/oauth.gofor other regions.
- Gmail —
Google Cloud Console →
APIs & Services → Credentials → Create OAuth client ID →
Web application. Enable the Gmail API for the project.
Requested scope:
- Set the authorised redirect URI to
<MIMUX_BASE_URL>/oauth/callback, e.g.https://mail.example.com/oauth/callback. It must matchMIMUX_BASE_URLexactly. - In Settings → Accounts, add the account with auth OAuth2 and paste the client ID and client secret; save.
- The account shows Connect — in the sidebar and in the Accounts list — until authorised. Click it to grant consent. Tokens are stored in the database and refreshed automatically; the sync worker (re)starts on callback.
Gmail also works with an app password and auth = "password", but
OAuth2 is the better path.
Upgrading
In a container, pull a new image:
docker compose pull && docker compose up -d
As a binary, it upgrades itself:
mimux upgrade # replace this binary with the newest release
mimux upgrade --check # just say what is current; exit 1 if outdated
mimux upgrade --version v0.21.3
It fetches the same build it already is — a pro binary stays pro — verifies it
against the release's checksums.txt, and swaps it into place with
a rename, so an interrupted download never leaves half a binary on your PATH.
If the file belongs to root it says so and prints the sudo
command rather than escalating on its own. Run inside a container it refuses
outright and points at docker pull, because patching a container
layer is undone by the next restart.
Schema migrations run at boot. There is no separate migration command and no
downtime window to plan for beyond the restart. Back up the data directory
first if the upgrade crosses a major version — it is one directory, so a
cp -a is a complete backup.
Backup
Everything is in the data directory: mimux.db (plus its
-wal/-shm sidecars) and the secret file.
Copy the directory and you have accounts, credentials, message cache,
sessions, filters, saved searches, OAuth tokens and API tokens.
For something portable and human-readable, use Settings → Accounts → Backup & restore, which exports a JSON copy of the configuration. It contains your passwords and API keys in plain text — treat the file accordingly.