The automation layer pro

Everything a human does in mimux is free, forever. When something other than a human needs to drive the mailbox, that is the pro layer: a REST API, an MCP server, a CLI, and webhooks.

Read this page before the API guide or the MCP page — it is where the credentials come from.

What you get

SurfaceMounted atFor
REST API/api/v1Scripts, integrations, anything that speaks HTTP and JSON.
MCP server/api/mcpAI agents, over streamable HTTP or the bundled stdio bridge.
CLImimux mailShells, scripts and cron — and agents with a bash harness but no MCP client.
WebhooksoutboundSigned POSTs to your URL when mail arrives, so nothing has to poll.

All four share one credential model, one scope set and one domain layer. The MCP server is the REST API wearing the protocol an agent already speaks; the CLI is that same API wearing a shell prompt, and talks to a running server over HTTP like any other client.

Running a pro build

The pro layer ships as a separate image and separate binaries, because the free ones do not contain it at all. Swap the image and add your key:

services:
  mimux:
    image: ghcr.io/mattmezza/mimux:pro   # or :v0.21-pro to stay on one minor
    environment:
      - MIMUX_LICENCE_KEY=mimuxlic1....  # from account.mimux.dev

Binaries are attached to each release as mimux-pro-<os>-<arch>. Alternatively, paste the key into Settings → Licence instead of setting the environment variable — the environment wins when both are present, so an install that provisions its licence from the environment never has to clear a stale database row.

The licence

Verification is offline and signature-only. An ed25519 public key is linked into the binary at build time; a key you paste is verified against it. There is no phone-home, no activation call and no machine fingerprint. Keys are bought and re-sent at account.mimux.dev.

StateWhat happens
TrialA pro build with no usable key runs for 14 days from its first pro boot. Responses carry an X-Mimux-Trial header counting down.
Annual licenceWorks until it expires, then keeps working through a 45-day grace period during which responses carry X-Mimux-Licence-Warning. After that the API and MCP pause.
Perpetual licenceCovers every build released within a year of purchase, and those builds run forever. A build released after that window is not covered, and says so out loud rather than degrading silently.
Invalid keyTreated as no key at all: the trial rules apply and the status line explains why the key was ignored, rather than hard-failing the install over a mangled paste.

When the licence does not allow it, /api/v1/* and /api/mcp answer 402 with error code licence_required or licence_version, and a message naming the fix. Two endpoints stay open unconditionally: /api/health and /api/v1/openapi.json — a probe and the documentation are not the product.

How perpetual coverage is decided

A perpetual key carries the date its coverage runs to — your purchase date plus a year — signed into it by the shop. Every mimux build carries the date it was released, linked into the binary. The rule is the comparison of those two: if this build went out before your coverage ended, it is covered, and it stays covered for as long as you keep running it. Nothing re-checks, nothing expires underneath you, and nothing phones home to ask.

The version number is not part of the decision. mimux licence status prints both dates so there is nothing to guess about; a binary you compiled yourself carries no release date and is never gated on one.

Keys issued before mid-2026 predate coverage dates and carry only a version watermark — the version the shop was selling at the time. Those keep the rule they were sold under: builds up to and including that minor version, forever. Nothing about an existing key changes, and mimux licence status says which rule applies to yours.

Mail itself never stops. Licensed, expired or absent, the client keeps syncing, sending, searching and rendering. The licence gate wraps two route groups in pro/ and nothing else; the mail client is AGPL code that has no idea it exists.

mimux licence status prints exactly where an install stands, and exits 0 when the API is answering and 1 when it is not — which makes it one line in a monitoring script. See Command line.

API tokens

Machine access authenticates with a personal access token created in Settings → API. Browser session cookies are never accepted by the API; the pro routes mount outside the cookie auth group entirely.

  • Tokens start with mimux_pat_.
  • The secret is shown once, at creation. Only its argon2id hash is stored — there is no way to recover it, only to make another.
  • Each token has a label, an optional expiry, a scope set, and a last-used timestamp (written at most once a minute, because it is a write on a read path).
  • Revoking takes effect immediately. Every request re-reads the token row and re-checks revoked/expired state, so nothing has to be invalidated or waited out.

Scopes

ScopeGrants
mail:readRead mail: list and read messages, folders, search, read filters.
mail:sendSend mail, and create or update drafts.
mail:modifyChange mail: read/star flags, labels, move, archive, spam, trash — and create filter rules.
accounts:readRead the account list and its sync state.
webhooks:manageManage webhook endpoints, including reading them.

A token's scopes are a space-separated subset of those five; an unrecognised scope is dropped on the way in, so a typo can never be stored and later honoured as a grant. A token created with nothing ticked gets mail:read, because a credential that authenticates and can do nothing is worse than useless.

Filters follow the mail scopes rather than getting one of their own — they govern how mail is handled. Webhooks are the exception: webhooks:manage covers reading them too, because a list of endpoints is a list of places this mailbox already talks to.

Grant the narrowest set that works. An agent that triages but must never send gets mail:read mail:modify and physically cannot send — on the MCP surface the send tools are not even listed.

Authenticating

curl -H "Authorization: Bearer $MIMUX_TOKEN" \
     https://mail.example.com/api/v1/tokens/self
{"label":"triage bot","scopes":["mail:read","mail:modify"]}

GET /api/v1/tokens/self needs no scope by design: it tells a client what its own credential may do, which is exactly what a client with a too-narrow token needs in order to find that out.

Rate limiting

Each token gets a continuously refilling bucket, 120 requests per minute by default. Change it with MIMUX_API_RATE_LIMIT; set it to 0 to switch limiting off entirely.

Over the limit is 429 with code rate_limited and a Retry-After header in whole seconds. The licence is checked before the token, everywhere, so a 402 never spends a request from your budget.

Where to go next