Using Mutt with Office365
2025-11-24
mutt
office365
Apparently authenticating IMAP over TLS is not good enough so we have to jump through the multiple OAuth hoops.
Tokens
Use the helper script that comes with neomutt at
/usr/share/neomutt/oauth2/mutt_oauth2.py but change it to
redirect to localhost. This fails but we can grab the code from the
request.
--- /old 2025-11-24 10:12:28.187218739 +1100
+++ /new 2025-11-24 10:12:19.191166524 +1100
@@ -63,7 +63,7 @@
'authorize_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
'devicecode_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/devicecode',
'token_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
- 'redirect_uri': 'https://login.microsoftonline.com/common/oauth2/nativeclient',
+ 'redirect_uri': 'http://localhost',
'tenant': 'common',
'imap_endpoint': 'outlook.office365.com',
'pop_endpoint': 'outlook.office365.com',Run the script to set new tokens:
$ /usr/share/neomutt/oauth2/mutt_oauth2.py --authorize ~/.mutt/toennjes.tokens
and when asked use the client_id from Thunderbird
9e5f94bc-e8a4-4e73-b8be-63364c29d753 (taken from https://github.com/mozilla/releases-comm-central/blob/master/mailnews/base/src/OAuth2Providers.sys.mjs#L192)
Then things like mbsync just work like this (set in config):
PassCmd "/usr/share/neomutt/oauth2/mutt_oauth2.py ~/.mutt/toennjes.tokens"
SMTP
To send you need the following in mutt’s config:
set smtp_url = smtp://${imap_user}@smtp.office365.com:587
set ssl_force_tls = yes
set ssl_use_sslv3 = yes
set smtp_authenticators = 'xoauth2'
set smtp_oauth_refresh_command = "/usr/share/neomutt/oauth2/mutt_oauth2.py ~/.mutt/toennjes.tokens"