The project is under active development, do not use in production before the final v1.0.0
(or at least do some manual backups).
- Multi-accounting
- Interactive configuration via wizard (requires
wizard
feature) - Synchronize pair of backends together (namely
left
andright
) - Partial synchronization based on filters
- Restrictive synchronization based on permissions
- IMAP backend (requires
imap
feature) - Maildir backend (requires
maildir
feature) - Notmuch backend (requires
notmuch
feature) - Backup and restore emails using the Maildir backend
Neverest CLI is written in Rust, and relies on cargo features to enable or disable functionalities. Default features can be found in the features
section of the Cargo.toml
.
The v1.0.0
is currently being tested on the master
branch, and is the prefered version to use. Previous versions (including GitHub beta releases and repositories published versions) are not recommended.
Neverest CLI v1.0.0
can be installed with a pre-built binary. Find the latest pre-release
GitHub workflow and look for the Artifacts section. You should find a pre-built binary matching your OS.
Neverest CLI v1.0.0
can also be installed with cargo:
$ cargo install --git https://github.com/pimalaya/neverest.git --force neverest
These installation methods should not be used until the v1.0.0
is finally released, as they are all (temporarily) outdated:
Pre-built binary
Neverest CLI can be installed with a prebuilt binary:
# As root:
$ curl -sSL https://raw.githubusercontent.com/pimalaya/neverest/master/install.sh | sudo sh
# As a regular user:
$ curl -sSL https://raw.githubusercontent.com/pimalaya/neverest/master/install.sh | PREFIX=~/.local sh
These commands install the latest binary from the GitHub releases section.
Binaries are built with default cargo features. If you want to enable or disable a feature, please use another installation method.
Cargo
Neverest CLI can be installed with cargo:
$ cargo install neverest
# With only IMAP support:
$ cargo install neverest --no-default-features --features imap
You can also use the git repository for a more up-to-date (but less stable) version:
$ cargo install --git https://github.com/pimalaya/neverest.git neverest
Nix
Neverest CLI can be installed with Nix:
$ nix-env -i neverest
You can also use the git repository for a more up-to-date (but less stable) version:
$ nix-env -if https://github.com/pimalaya/neverest/archive/master.tar.gz
# or, from within the source tree checkout
$ nix-env -if .
If you have the Flakes feature enabled:
$ nix profile install neverest
# or, from within the source tree checkout
$ nix profile install
# you can also run Neverest directly without installing it:
$ nix run neverest
Sources
Neverest CLI can be installed from sources.
First you need to install the Rust development environment (see the rust installation documentation):
$ curl https://sh.rustup.rs -sSf | sh
Then, you need to clone the repository and install dependencies:
$ git clone https://github.com/pimalaya/neverest.git
$ cd neverest
$ cargo check
Now, you can build Neverest:
$ cargo build --release
Binaries are available under the target/release
folder.
Just run neverest
, the wizard will help you to configure your default account.
You can also manually edit your own configuration, from scratch:
- Copy the content of the documented
./config.sample.toml
- Paste it in a new file
~/.config/neverest/config.toml
- Edit, then comment or uncomment the options you want
Proton Mail (Bridge)
When using Proton Bridge, emails are synchronized locally and exposed via a local IMAP/SMTP server. This implies 2 things:
- Id order may be reversed or shuffled, but envelopes will still be sorted by date.
- SSL/TLS needs to be deactivated manually.
- The password to use is the one generated by Proton Bridge, not the one from your Proton Mail account.
[accounts.proton]
email = "[email protected]"
backend = "imap"
imap.host = "127.0.0.1"
imap.port = 1143
imap.encryption = false
imap.login = "[email protected]"
imap.passwd.raw = "<bridge-imap-p@ssw0rd>"
message.send.backend = "smtp"
smtp.host = "127.0.0.1"
smtp.port = 1025
smtp.encryption = false
smtp.login = "[email protected]"
smtp.passwd.raw = "<bridge-smtp-p@ssw0rd>"
Keeping your password inside the configuration file is good for testing purpose, but it is not safe. You have 2 better alternatives:
-
Save your password in any password manager that can be queried via the CLI:
imap.passwd.cmd = "pass show proton"
-
Use the global keyring of your system (requires the
keyring
cargo feature):imap.passwd.keyring = "proton-example"
Running
neverest configure -a proton
will ask for your IMAP password, just paste the one generated previously.
Gmail
Google passwords cannot be used directly. There is two ways to authenticate yourself:
Using App Passwords
This option is the simplest and the fastest. First, be sure that:
- IMAP is enabled
- Two-step authentication is enabled
- Less secure app access is enabled
First create a dedicated password for Neverest.
[accounts.gmail]
email = "[email protected]"
folder.alias.inbox = "INBOX"
folder.alias.sent = "[Gmail]/Sent Mail"
folder.alias.drafts = "[Gmail]/Drafts"
folder.alias.trash = "[Gmail]/Trash"
backend = "imap"
imap.host = "imap.gmail.com"
imap.port = 993
imap.login = "[email protected]"
imap.passwd.cmd = "pass show gmail"
message.send.backend = "smtp"
smtp.host = "smtp.gmail.com"
smtp.port = 465
smtp.login = "[email protected]"
smtp.passwd.cmd = "pass show gmail"
Keeping your password inside the configuration file is good for testing purpose, but it is not safe. You have 2 better alternatives:
-
Save your password in any password manager that can be queried via the CLI:
imap.passwd.cmd = "pass show gmail"
-
Use the global keyring of your system (requires the
keyring
cargo feature):imap.passwd.keyring = "gmail-example"
Running
neverest configure -a gmail
will ask for your IMAP password, just paste the one generated previously.
This option is the most secure but the hardest to configure. It requires the oauth2
and keyring
cargo features.
First, you need to get your OAuth 2.0 credentials by following this guide. Once you get your client id and your client secret, you can configure your Neverest account this way:
[accounts.gmail]
email = "[email protected]"
folder.alias.inbox = "INBOX"
folder.alias.sent = "[Gmail]/Sent Mail"
folder.alias.drafts = "[Gmail]/Drafts"
folder.alias.trash = "[Gmail]/Trash"
backend = "imap"
imap.host = "imap.gmail.com"
imap.port = 993
imap.login = "[email protected]"
imap.oauth2.client-id = "<imap-client-id>"
imap.oauth2.auth-url = "https://accounts.google.com/o/oauth2/v2/auth"
imap.oauth2.token-url = "https://www.googleapis.com/oauth2/v3/token"
imap.oauth2.pkce = true
imap.oauth2.scope = "https://mail.google.com/"
message.send.backend = "smtp"
smtp.host = "smtp.gmail.com"
smtp.port = 465
smtp.login = "[email protected]"
smtp.oauth2.client-id = "<smtp-client-id>"
smtp.oauth2.auth-url = "https://accounts.google.com/o/oauth2/v2/auth"
smtp.oauth2.token-url = "https://www.googleapis.com/oauth2/v3/token"
smtp.oauth2.pkce = true
smtp.oauth2.scope = "https://mail.google.com/"
# If you want your SMTP to share the same client id (and so the same access token)
# as your IMAP config, you can add the following:
#
# imap.oauth2.client-id = "<client-id>"
# imap.oauth2.client-secret.keyring = "gmail-oauth2-client-secret"
# imap.oauth2.access-token.keyring = "gmail-oauth2-access-token"
# imap.oauth2.refresh-token.keyring = "gmail-oauth2-refresh-token"
#
# imap.oauth2.client-id = "<client-id>"
# imap.oauth2.client-secret.keyring = "gmail-oauth2-client-secret"
# imap.oauth2.access-token.keyring = "gmail-oauth2-access-token"
# smtp.oauth2.refresh-token.keyring = "gmail-oauth2-refresh-token"
Running neverest configure -a gmail
will complete your OAuth 2.0 setup and ask for your client secret.
Outlook
[accounts.outlook]
email = "[email protected]"
backend = "imap"
imap.host = "outlook.office365.com"
imap.port = 993
imap.login = "[email protected]"
imap.passwd.cmd = "pass show outlook"
message.send.backend = "smtp"
smtp.host = "smtp.mail.outlook.com"
smtp.port = 587
smtp.encryption = "start-tls"
smtp.login = "[email protected]"
smtp.passwd.cmd = "pass show outlook"
This option is the most secure but the hardest to configure. First, you need to get your OAuth 2.0 credentials by following this guide. Once you get your client id and your client secret, you can configure your Neverest account this way:
[accounts.outlook]
email = "[email protected]"
backend = "imap"
imap.host = "outlook.office365.com"
imap.port = 993
imap.login = "[email protected]"
imap.oauth2.client-id = "<imap-client-id>"
imap.oauth2.auth-url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
imap.oauth2.token-url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
imap.oauth2.pkce = true
imap.oauth2.scope = "https://outlook.office.com/IMAP.AccessAsUser.All"
message.send.backend = "smtp"
smtp.host = "smtp.mail.outlook.com"
smtp.port = 587
smtp.starttls = true
smtp.login = "[email protected]"
smtp.oauth2.client-id = "<smtp-client-id>"
smtp.oauth2.auth-url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
smtp.oauth2.token-url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
smtp.oauth2.pkce = true
smtp.oauth2.scope = "https://outlook.office.com/SMTP.Send"
# If you want your SMTP to share the same client id (and so the same access token)
# as your IMAP config, you can add the following:
#
# imap.oauth2.client-id = "<client-id>"
# imap.oauth2.client-secret.keyring = "outlook-oauth2-client-secret"
# imap.oauth2.access-token.keyring = "outlook-oauth2-access-token"
# imap.oauth2.refresh-token.keyring = "outlook-oauth2-refresh-token"
#
# imap.oauth2.client-id = "<client-id>"
# imap.oauth2.client-secret.keyring = "outlook-oauth2-client-secret"
# imap.oauth2.access-token.keyring = "outlook-oauth2-access-token"
# smtp.oauth2.refresh-token.keyring = "outlook-oauth2-refresh-token"
Running neverest configure -a outlook
will complete your OAuth 2.0 setup and ask for your client secret.
iCloud Mail
From the iCloud Mail support page:
- IMAP port =
993
. - IMAP login = name of your iCloud Mail email address (for example,
johnappleseed
, not[email protected]
) - SMTP port =
587
withSTARTTLS
- SMTP login = full iCloud Mail email address (for example,
[email protected]
, notjohnappleseed
)
[accounts.icloud]
email = "[email protected]"
backend = "imap"
imap.host = "imap.mail.me.com"
imap.port = 993
imap.login = "johnappleseed"
imap.passwd.cmd = "pass show icloud"
message.send.backend = "smtp"
smtp.host = "smtp.mail.me.com"
smtp.port = 587
smtp.encryption = "start-tls"
smtp.login = "[email protected]"
smtp.passwd.cmd = "pass show icloud"
How to debug Neverest CLI?
The simplest way is to use --debug
and --trace
arguments.
The advanced way is based on environment variables:
RUST_LOG=<level>
: determines the log level filter, can be one ofoff
,error
,warn
,info
,debug
andtrace
.RUST_SPANTRACE=1
: enables the spantrace (a span represent periods of time in which a program was executing in a particular context).RUST_BACKTRACE=1
: enables the error backtrace.RUST_BACKTRACE=full
: enables the full error backtrace, which include source lines where the error originated from.
Logs are written to the stderr
, which means that you can redirect them easily to a file:
RUST_LOG=debug neverest 2>/tmp/neverest.log
How the wizard discovers IMAP configs?
All the lookup mechanisms use the email address domain as base for the lookup. It is heavily inspired from the Thunderbird Autoconfiguration protocol. For example, for the email address [email protected]
, the lookup is performed as (in this order):
- check for
autoconfig.example.com
- look up of
example.com
in the ISPDB (the Thunderbird central database) - look up
MX example.com
in DNS, and formx1.mail.hoster.com
, look uphoster.com
in the ISPDB - look up
SRV example.com
in DNS - try to guess (
imap.example.com
,smtp.example.com
…)
Special thanks to the NLnet foundation and the European Commission that helped the project to receive financial support from various programs:
- NGI Assure in 2022
- NGI Zero Entrust in 2023
- NGI Zero Core in 2024 (still ongoing)
If you appreciate the project, feel free to donate using one of the following providers: