Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

mnm is not mail

The mnm project is building a legitimate replacement for email: a server (see below), a client, and a simple protocol between them.

Learn more at

Server status

11 December 2020 - v0.1 is released for Linux!

13 April 2019 - A private preview is now live! Contact the author if you'd like to try it.

19 August 2018 - After testing with mnm client, made a handful of fixes. Changed license to MPL.

25 September 2017 - A client application is in development.

3 August 2017 - A simulation of 1000 concurrent active clients delivers 1 million messages totaling 6.7GB in 46 minutes. It uses ~200MB RAM, <10MB disk, and minimal CPU time. Each client runs a 19-step cycle that does login, then post for two recipients (15x) or for a group of 100 (2x) every 1-30s, then logout and idle for 1-30s.

Quick start

  1. Download binary or build from source
    a) Get mnm-tmtpd-linux-amd64-v0.1.0.tgz
    b) Extract with tar xzf mnm-tmtpd-linux-amd64-v0.1.0.tgz
    a) go get

  2. Enable TCP+TLS with self-signed certificate
    a) cd mnm
    b) openssl ecparam -genkey -name secp384r1 -out server.key
    c) openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
    d) cp mnm.conf mnm.config # edit to revise ntp.hosts and adjust listen.laddr with "host:port"

    Note: On a public Internet host, port 443 will see a steady trickle of probe requests (often with malicious intent) which pollutes the mnm log. Choose a port above 1024 to avoid this.

  3. Run server
    a) ./mnm # default port 443 may require sudo ./mnm; logs to stdout & stderr
    b) Ctrl-C to stop
    a) ./mnm >> logfile 2>&1 & # run in background, logs to end of logfile
    b) kill -s INT <background_pid> # send SIGINT signal, triggering graceful shutdown

  4. Distribute the server address to users
    +  Use =address:port for a self-signed certificate, for example =
    +  Use +address:port for a CA-issued certificate, for example


The file "mnm.config" contains a JSON object with these fields.

The ntp (network time protocol) object defines:
hosts - an array of NTP servers
retries - the number of times to retry each host

The listen object defines:
net & laddr - arguments to net.ListenConfig.Listen(nil, net, laddr)
certPath & keyPath - arguments to tls.LoadX509KeyPair(certPath, keyPath)

The name parameter defines the server's tmtprev response .name field.

The auth parameter defines where third party authentication is required:
0 - not supported
1 - required for registration
2 - required for registration and login (not yet implemented)

The authby array defines a set of objects describing OpenID Connect providers:
label - the name of the OIDC provider/application
login - an array giving the base URL, followed by name=value request parameters, for OIDC /authorize
token - an array giving the base URL, followed by name=value request parameters, for OIDC /token
std - an array of name=value request parameters to append to both login & token requests
keys - the URL for the public key needed to validate tokens provided by OIDC authentication
iss & aud - expected values for claims in the .id_token field of OIDC tokens

If the first authby object is empty, OpenID Connect authentication is optional. This is useful for testing.

Build & package

Assuming this repository has been obtained via git clone:

a) cd mnm
b) git stash # if required
c) git checkout <your_branch>
d) Edit kVersionDate in main.go
e) ./ # make release downloads


Continuous test sequence with simulated clients
a) ./mnm 10 > /dev/null # may be 2-1000
b) ctrl-C to stop

The file test.json gives a sequence of requests and expected results, which runs prior to the continuous test. It includes invalid requests, which print messages to stderr.

What's here

  • codestyle.txt: how to make Go source more clear
  • qlib/: TMTP implementation
  • test.json: qlib test data
  • userdb.go: user & group records management
  • userdb-test.go: userdb test procedure
  • main.go: main(), network frontend
  • mnm.conf: site-specific parameters; rename to mnm.config to enable TCP server
  • mnm: the server executable
  • After first run:
    userdb/: user & group data
    qstore/: queued messages awaiting delivery


Copyright 2020 Liam Breck
Published at

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at


mnm implements TMTP protocol. Let Internet sites message members directly, instead of unreliable, insecure email. Contributors welcome! (Server)








No packages published