mnotify is a simple cli for the matrix chat system.
It was developed for the use case of sending notifications from a headless server.
The binary is called mn.
The output is always JSON (on stdout); logs go to stderr.
$ cargo build [--release]
Requires Rust 1.93 or newer (Rust edition 2024, matrix-sdk 0.18).
Obtain a fresh matrix user account on an arbitrary homeserver or use an existing one.
First, create a login.
Be aware to always use the complete matrix id including the domain, e.g. @user:example.org.
Without the -p flag, mn reads the password from stdin or interactively from the terminal.
$ mn login @user:example.org
The session (access/refresh token) and the passphrase of the encrypted state
store are kept in the system keyring. On a remote machine without a keyring
daemon set MN_NO_KEYRING; the secrets then live in a 0600 file
$XDG_STATE_HOME/mnotify/$USER_ID/session.json instead.
Homeservers backed by a next-generation auth server (OAuth 2.0 / MAS, e.g. matrix.org) no longer accept password logins from new clients. Instead:
$ mn login @user:example.org --qr
mn prints a QR code in the terminal. Open an already signed-in Element,
choose "Link new device" / "Sign in with QR code", scan the terminal, and
type the two-digit check code Element shows back into mn.
If your homeserver has an SSO button on the Element login page (enterprise SAML, OIDC, ...):
$ mn login @user:example.org --sso
mn prints the homeserver's SSO URL and waits for the browser redirect on a
local port. Open the URL, sign in, done. On a headless box, forward the port
first (the command prints the exact ssh -L ... line). Use --idp <id> to
skip the server's identity-provider picker.
A fresh login is unverified and cannot read encrypted history. Either verify it from another device...
$ mn verify
Start the verification from Element (or another client), compare the emojis and confirm.
...or, if you have set up recovery before, restore the cross-signing and backup keys from your recovery key:
$ mn recovery recover < recovery-key.txt
The first device of an account has to enable recovery once, which bootstraps cross-signing and the server-side key backup and prints the recovery key:
$ mn recovery enable
{"recovery_key":"EsT ..."}
mn recovery status reports the current recovery / backup / cross-signing state.
$ mn send -r "$ROOM_ID" "Hello. :)"
or
$ echo "Hello. :)" | mn send -r "$ROOM_ID"
With -m/--markdown the body is rendered as Markdown (the message keeps a
plain-text fallback for clients that don't render it):
$ mn send -r "$ROOM_ID" -m "**build failed** on \`main\`, see [log]($URL)"
--markdown also works with -n/--notice and -e/--emote.
or send a file
$ mn send -r "$ROOM_ID" --attachment "cat.jpg"
Images are sent as m.image with their dimensions and, for anything larger
than 800px, a generated thumbnail, so clients show an inline preview.
--raw prints the events as they come from the server.
Without --raw only messages are printed.
$ mn sync --raw
The sync token is persisted in the state store, so each invocation only fetches what changed since the last one.
Since matrix provides a lot of features, a debug build can be quite large (see
#18). For a smaller binary
use a --release build, or try
LTO. TLS is
always rustls; there is no system-TLS
option anymore.
Standard tracing
filter, e.g. RUST_LOG=matrix_sdk=debug. Overrides -v/-q.
Use this proxy for all matrix requests. Only http proxies are supported.
Disable TLS verification.
mnotify uses the system keyring via the
Secret Service API.
Set this to store the secrets in a 0600 file instead. Be warned.
Overwrite the path to meta.json (see below).
mnotify conforms to the
XDG Base Directory Specification.
$XDG_STATE_HOME/mnotify/meta.json-- which user the current session belongs to.$XDG_STATE_HOME/mnotify/$USER_ID/session.json-- session + store passphrase, only withMN_NO_KEYRING.$XDG_STATE_HOME/mnotify/$USER_ID/store/-- the SQLite state/crypto store, encrypted with the store passphrase.