Skip to content
mailwerk.app

Quick start

Updated on 2026-08-13

A site is added in three steps: create the customer and the site in the platform, install the agent at the customer and enrol it, then point the device at it. Enrolment through the platform does not exist yet. What works today is the agent on its own, set up on the command line, and that is what this page covers.

The tenant side comes before any of it: an app registration in the customer's Microsoft 365 tenant, with admin consent, restricted to the mailbox this site is meant to send from. That is covered step by step in Entra ID setup.

The agent stores everything under %ProgramData%\Mailwerk\Relay\ on Windows and /var/lib/mailwerk/ elsewhere. Override with MAILWERK_DATA_DIR.

# 1. Store the credentials of the app registration in the customer's tenant. The
#    secret is read from stdin so it does not appear in your shell history or in
#    the process list.
mailwerk add-credential -name "Contoso tenant" -tenant <tenant-id> -client-id <client-id>

# 2. Create a device login. The sender address is forced onto every message this
#    login submits, whatever the device claims.
mailwerk add-account -username printer-2og -password <device-password> \
    -from scan@example.com -credential <credential-id>

# 3. Verify the tenant side before you touch a printer.
mailwerk test-credential <credential-id>

# 4. Run it.
mailwerk serve

test-credential reports the sender address Graph would actually stamp on a message. If that differs from the address you configured - which happens when you use an alias rather than the mailbox's primary address - it says so. Check it before wiring devices, not afterwards.

mailwerk status prints instance identity, account and credential counts, and queue state. mailwerk list-credentials shows ids and last-check results.

Repeat this per site. Every site gets an agent of its own, holding the credentials from its own customer's tenant.

What changes once the platform is there

Once enrolment exists, the agent will register itself against its site with an enrolment key on first start instead of being configured locally. What that looks like in the interface goes here once there is one, and not before.