ycakes blog/My Mutt setup
31.01.2024

My Mutt setup

mutt, and the related tools, alwasy seemed kinda faszinating to me. Even though I am very happy with thunderbird, most CLI/TUI tools seem very productive and (sometimes counter-intuitively) user-friendly. So a few days I ago I finally found the time to try it out.

I will document my complete setup including Mutt itself but also offlineimap and msmtp. For password management I used KeepassXC as a "Secret Service" provider, which I will document as well.

The documentation here is not at all complete. For a better step by step guide for the tools used, the excellent ArchWiki can be used.

Mutt

Mutt is a terminal-based Email client, even though Mutt has support for IMAP and SMTP built-in, you will quickly run into limitations when using Mutt this way (No offline usage etc.). You are much better off if you are using Mutt only to view and write mail and leave the communication with mailservers to dedicated applications.

This is an aspect I absolutely love about Unix/CLI applications. The individual programs do one (or a few) things well, use standardized interfaces to communicate and are interchangeable. To install mutt on arch I ran: pacman -S mutt.

Why not Neomutt?

I guess I wanted to start "simple" and don't get confused by the massive amount of features :). In retrospect, I could have used Neomutt straight from the beginning because I assume that's what I would want to use anyway if I am going to continue to use Mutt. The Tutorial steps I listed here should be valid for Neomutt as well though.

Config

All tools I used helpfully respect the XDG_* vars. For simplicity reasons I just have this in my .zshrc:

export XDG_CACHE_HOME=$HOME/.cache
export XDG_CONFIG_HOME=$HOME/.config
export XDG_DATA_HOME=$HOME/.local/share
export XDG_STATE_HOME=$HOME/.local/state

The config for Mutt then goes into the following file: $XDG_CONFIG_HOME/mutt/muttrc. My basic config-file looks like this:

set editor=vim
set mbox_type=Maildir
set folder = ~/mail
set spoolfile=+INBOX
set record=+Sent
alternative_order text/plain text/html
set realname="My Name"
set sendmail="/usr/bin/msmtp"
set from=my@mail.address

That is all we have to do to configure Mutt for now. But how do we receive mail? Or more specifically: How to we get mail into our ~/mail directory so Mutt can read it?

Sync Mail with OfflineIMAP

There are multiple options to sync mail with IMAP servers. I chose "OfflineIMAP", another valid option would have been isync. To install OfflineIMAP on Arch I ran: pacman -S offlineimap.

The Path for my OfflineImap config file is: $XDG_CONFIG_HOME/offlineimap/config.

The basic content is fairly simple:

[general]
# List of accounts to be synced, separated by a comma.
accounts = main

[Account main]
# Identifier for the local repository; e.g. the maildir to be synced via IMAP.
localrepository = main-local
# Identifier for the remote repository; i.e. the actual IMAP, usually non-local.
remoterepository = main-remote

[Repository main-local]
# OfflineIMAP supports Maildir, GmailMaildir, and IMAP for local repositories.
type = Maildir
# Where should the mail be placed?
localfolders = ~/mail

[Repository main-remote]
type = IMAP
remotehost = provider.imap.address
remoteuser = my@mail.address
starttls = no
sslcacertfile = /etc/ssl/certs/ca-certificates.crt

Viewing our mail

Running offlineimap should be enough now to start the sync. The first sync may take some time. Subsequent syncs will be much faster. For now we get prompted for the password every time and have to input/paste it manually. We will remedy this in the "Passwords" Chapter.

After offlineimap is done with the sync we can simply run mutt and view our Emails. The first screen you should see is the so called "Index" This Post is not meant as a complete Mutt manual but here are a few important key-bindings.

msmtp

So the basic receiving of mail via IMAP is working. To send mails we use SMTP. I used msmtp which can be installed via pacman -S msmtp.

We already did the first step for using msmtp earlier via the muttrc:

set sendmail="/usr/bin/msmtp"
The config file, under $XDG_HOME_CONFIG/msmtp/config for msmtp is pretty simple as well:

# Set default values for all following accounts.
defaults
auth           on
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        ~/.msmtp.log

# Account 1
account        account.name
host           smtp.address
port           smtp.port
tls_starttls   off
from           my@mail.adress
user           my@mail.adress
password

# Set a default account
account default: account.name

When running msmtp via mutt it will not prompt for a password. So to prevent storing the password in plain text we will do it "right" and simply use a Password Manager which is documented in the following chapter.

Passwords

OfflineIMAP and msmtp support the "freedesktop.org secret service" protocol. I Use KeypassXC as a provider since i use Keypass on all my devices. A good alternative would be "gnome-keyring". The configuration for OfflineIMAP and msmtp stays the same regardless of the provider.

KeypassXC

I am assuming KeypassXC is already installed an the mail password is already stored in a Keypass Database. Using KeypassXC as a Keyring provider is pretty simple and allows all application to query KeyypassXC for credentials. If you don't have any kind of Secret Service provider running activating it for KeypassXC is as simple as Checking the "Enable KeypassXC Freedesktop.org Secret Service integration" Box under Settings -> Secret Service Integration.

If you haven't already you need the following additional attributed for the Email-Password Entry (Your values for host and user will vary of course:

msmtp

msmtp supports the secret service protocol natively. So considering everything is set up as above, sending mail should be possible now. With the default configuration KeypassXC will show a prompt every time an applications asks for a password to confirm.

OfflineIMAP

Offline IMAP doesn't support the secret service protocol as natively as msmtp, but has very flexible scripting capabilities for this use case. First, it it is not already installed, we need to install the application secret-tool. This app is used to retrieve credentials from our secret service provider via the command line. Then we need to add to lines to our $XDG_CONFIG_HOME/offlineimap/config file:

[general]
accounts = main
pythonfile=~/scripts/get_pass.py
# unchanged
[Repository main-remote]
# unchanged
remotepasseval = get_pass("my@mail.address")

The script get_pass.py is really simple:

#! /usr/bin/env python
import os
from subprocess import check_output

def get_pass(user):
    return check_output("secret-tool lookup user " +user, shell=True).splitlines()[0].decode("UTF-8")

It probably would make sense to put this file into /usr/local/lib, especially for multi-user systems. But this works for now. Running offlineimap now should trigger the prompt, just like with msmtp.

Triggering sync

Running offlineimap manually in a separate terminal window every time we want to check for new mail obviously is not a nice solution. So the usual way people update is by using some kind of cron job. For testing I went with a simpler, manual solution which is nice to demonstrate another great feature of mutt: Macros. To be able to trigger an IMAP sync from withing mutt I added a single line to my muttrc.

macro index <f5> <shell-escape>"offlineimap > /dev/null 2>&1 & exit"<enter>
Now I can run offlineimap by pressing F5 while in the "Index" View. This is not perfect, for example you need to press enter once, but I am prod of this solution because I came up with it myself :).

Whats missing?

This is a pretty usable base configuration but I haven't touched a few important bits yet.

PGP Encription

Mutt has support for E2E encryption and signing built-in. So getting this to work should not be too much of a problem.

Multiple accounts.

All tools support multiple accounts well. I haven't touched those features yet, but this would be very important for me if I were to make a full switch.

And now?

Setting up Mutt was quite fun and I am surprised how fast I was able to somewhat use Mutt. I was amazed how well all those tools from IMAP to Secret Service integrate with each other. But learning all the key-bindings and being more productive than in Thunderbird is going to take a long time. I probably won't switch to Mutt entirely, but use it for some specific tasks.