{"slug": "himalaya-cli-to-manage-emails", "title": "Himalaya – CLI to Manage Emails", "summary": "Himalaya, a Rust-based CLI tool for managing emails, supports IMAP, SMTP, JMAP, Gmail REST API, and Microsoft Graph, with features including multi-account TOML configuration, TLS via Rustls or Native TLS, and proxy support. The tool can be installed via shell script, cargo, or package managers like pacman, brew, and scoop, and offers a wizard for automatic provider discovery.", "body_md": "[Features](#features)[Installation](#installation)[Configuration](#configuration)[Usage](#usage)[Interfaces](#interfaces)[FAQ](#faq)[AI disclosure](#ai-disclosure)[License](#license)[Social](#social)[Contributing](#contributing)[Sponsoring](#sponsoring)\n\n**Shared API** for`mailboxes`\n\n,`envelopes`\n\n,`flags`\n\n,`messages`\n\nand`attachments`\n\n**Protocol-specific APIs** exposing each backend's full surface**IMAP**,** SMTP**,** JMAP**,** Gmail**(REST API),** Microsoft Graph**(Outlook / Microsoft 365) support** Maildir**,[specs](https://cr.yp.to/proto/maildir.html)** m2dir**support[specs](https://man.sr.ht/~bitfehler/m2dir/)** Simple auth**support for IMAP/SMTP: anonymous, login, plain, oauthbearer, xoauth2, scram-sha-256** HTTP auth**support for JMAP: basic, bearer** TLS**support:[Rustls](https://crates.io/crates/rustls)with ring crypto[Rustls](https://crates.io/crates/rustls)with aws crypto (requires`rustls-aws`\n\nfeature)[Native TLS](https://crates.io/crates/native-tls)(requires`native-tls`\n\nfeature)\n\n**Discovery** support:**SOCKS5**,** HTTP**proxy support via`$ALL_PROXY`\n\nand`$HTTP_PROXY`\n\n**TOML configuration** with multi-account support**JSON** output via`--json`\n\nTip\n\nHimalaya is written in [Rust](https://www.rust-lang.org/) and uses [cargo features](https://doc.rust-lang.org/cargo/reference/features.html) to gate backend support. The default feature set is declared in [Cargo.toml](/pimalaya/himalaya/blob/master/Cargo.toml).\n\nHimalaya can be installed with the installer:\n\n*As root:*\n\n```\ncurl -sSL https://raw.githubusercontent.com/pimalaya/himalaya/master/install.sh | sudo sh\n```\n\n*As a regular user:*\n\n```\ncurl -sSL https://raw.githubusercontent.com/pimalaya/himalaya/master/install.sh | PREFIX=~/.local sh\n```\n\nThese commands install the latest binary from the GitHub [releases](https://github.com/pimalaya/himalaya/releases) section.\n\nFor a more up-to-date version than the latest release, check out the [releases](https://github.com/pimalaya/himalaya/actions/workflows/releases.yml) GitHub workflow and look for the *Artifacts* section. These pre-built binaries are built from the `master`\n\nbranch.\n\nNote\n\nSuch binaries are built with the default cargo features. If you need specific features, please use another installation method.\n\n```\ncargo install --locked --git https://github.com/pimalaya/himalaya.git\n```\n\nWith only IMAP+SMTP support:\n\n```\ncargo install --locked --git https://github.com/pimalaya/himalaya.git \\\n  --no-default-features \\\n  --features imap,smtp,rustls-ring\n```\n\nFrom the community repository:\n\n```\npacman -S himalaya\n```\n\nOr the [user repository](https://aur.archlinux.org/):\n\n```\ngit clone https://aur.archlinux.org/himalaya-git.git\ncd himalaya-git\nmakepkg -isc\n```\n\nOr with [yay](https://github.com/Jguer/yay):\n\n```\nyay -S himalaya-git\nbrew install himalaya\n```\n\nNote\n\nCargo features are not compatible with brew. If you need a different feature set, please use another installation method.\n\n```\nscoop install himalaya\n```\n\nFrom the [COPR](https://copr.fedorainfracloud.org/coprs/atim/himalaya/) repo:\n\n```\ndnf copr enable atim/himalaya\ndnf install himalaya\n```\n\nIf you have the [Flakes](https://nixos.wiki/wiki/Flakes) feature enabled:\n\n```\nnix profile install github:pimalaya/himalaya\n```\n\nOr run without installing:\n\n```\nnix run github:pimalaya/himalaya\ngit clone https://github.com/pimalaya/himalaya\ncd himalaya\nnix run\n```\n\nRun `himalaya`\n\n. With no configuration file on disk the wizard prompts for an account name and an email address, runs provider discovery (PACC, Thunderbird Autoconfiguration, RFC 6186 SRV and RFC 8620 JMAP resolution, all probed in parallel and merged), fills the IMAP/SMTP (or JMAP) prompts with the discovered defaults, then writes the result to disk.\n\nA persistent configuration is loaded from the first valid path among:\n\n`$XDG_CONFIG_HOME/himalaya/config.toml`\n\n`$HOME/.config/himalaya/config.toml`\n\n`$HOME/.himalayarc`\n\nThese are the same paths the [himalaya-tui](https://github.com/pimalaya/himalaya-tui) TUI looks at: one TOML file backs both binaries. CLI-only fields and TUI-only sections coexist without errors. See [config.sample.toml](/pimalaya/himalaya/blob/master/config.sample.toml) for a documented template.\n\nOverride the path with `-c <PATH>`\n\n; multiple paths can be passed at once, separated by `:`\n\n. The first one is the base and the rest are deep-merged on top.\n\nTo add or reconfigure an account, run the bare `himalaya`\n\nwizard again and redirect its printed TOML into (or merge it with) your config file. There is no in-place edit subcommand; `himalaya account list`\n\nand `himalaya account check`\n\ninspect and validate the accounts already declared.\n\nProton does not expose IMAP/SMTP directly: run [Proton Bridge](https://proton.me/mail/bridge), which synchronizes mail locally and serves it on a local IMAP/SMTP endpoint. The password is the one generated by the Bridge, not your Proton account password.\n\n```\n[accounts.proton]\n\nimap.server = \"imap://127.0.0.1:1143\"\nimap.sasl.plain.username = \"example@proton.me\"\nimap.sasl.plain.password.command = \"pass show proton-bridge\"\n\nsmtp.server = \"smtp://127.0.0.1:1025\"\nsmtp.sasl.plain.username = \"example@proton.me\"\nsmtp.sasl.plain.password.command = \"pass show proton-bridge\"\n```\n\nTo keep TLS on the local link, export the certificate generated by the Bridge and enable STARTTLS:\n\n```\nimap.starttls = true\nimap.tls.cert = \"/path/to/exported/cert.pem\"\n\nsmtp.starttls = true\nsmtp.tls.cert = \"/path/to/exported/cert.pem\"\n```\n\nFastmail needs an [app password](https://www.fastmail.help/hc/en-us/articles/360058752854) for IMAP/SMTP, or an [API token](https://www.fastmail.help/hc/en-us/articles/5254602856719) for its native JMAP endpoint.\n\n```\n[accounts.fastmail]\n\nimap.server = \"imaps://imap.fastmail.com\"\nimap.sasl.plain.username = \"example@fastmail.com\"\nimap.sasl.plain.password.command = \"pass show fastmail\"\n\nsmtp.server = \"smtps://smtp.fastmail.com\"\nsmtp.sasl.plain.username = \"example@fastmail.com\"\nsmtp.sasl.plain.password.command = \"pass show fastmail\"\n```\n\nTo use JMAP instead, replace the `imap`\n\n/`smtp`\n\nblocks with a single `jmap`\n\none:\n\n```\njmap.server = \"https://api.fastmail.com/jmap/session\"\njmap.auth.bearer.token.command = \"pass show fastmail\"\n```\n\nGmail rejects the account password over SASL PLAIN: generate an [app password](https://myaccount.google.com/apppasswords) (requires 2-step verification) and feed it through `password.command`\n\nor `password.raw`\n\n.\n\n```\n[accounts.gmail]\n\nimap.server = \"imaps://imap.gmail.com:993\"\nimap.sasl.plain.username = \"example@gmail.com\"\nimap.sasl.plain.password.command = \"pass show gmail\"\n\nsmtp.server = \"smtps://smtp.gmail.com:465\"\nsmtp.sasl.plain.username = \"example@gmail.com\"\nsmtp.sasl.plain.password.command = \"pass show gmail\"\n\nmailbox.alias.inbox = \"INBOX\"\nmailbox.alias.sent = \"[Gmail]/Sent Mail\"\nmailbox.alias.drafts = \"[Gmail]/Drafts\"\nmailbox.alias.trash = \"[Gmail]/Trash\"\nmailbox.alias.archive = \"[Gmail]/All Mail\"\n```\n\nEvery Gmail label shows up as a top-level IMAP mailbox, and the special mailboxes live under the `[Gmail]/`\n\nprefix — quote them in the shell (`-m \"[Gmail]/Drafts\"`\n\n) or reach them through an alias. `[Gmail]/All Mail`\n\nis the archive containing every message: aliasing it makes \"search everything\" one flag away (`himalaya envelope search -m archive ...`\n\n).\n\nTo use Gmail's native REST API instead of IMAP/SMTP, replace the blocks above with a single OAuth 2.0 bearer token from a helper such as [ortie](https://github.com/pimalaya/ortie):\n\n```\ngmail.auth.token.command = [\"ortie\", \"token\", \"show\", \"-a\", \"gmail\"]\n```\n\nLabels become mailboxes here too, but they carry the API's opaque label ids; address them by name (`-m Himalaya-Test`\n\n) and himalaya resolves the id.\n\nMicrosoft has retired basic authentication: use OAuth 2.0 via `oauthbearer`\n\nor `xoauth2`\n\n, with the access token supplied by an external helper such as [ortie](https://github.com/pimalaya/ortie).\n\n```\n[accounts.outlook]\n\nimap.server = \"imaps://outlook.office365.com:993\"\nimap.sasl.xoauth2.username = \"example@outlook.com\"\nimap.sasl.xoauth2.token.command = [\"ortie\", \"token\", \"show\", \"-a\", \"outlook\"]\n\nsmtp.server = \"smtp://smtp-mail.outlook.com:587\"\nsmtp.starttls = true\nsmtp.sasl.xoauth2.username = \"example@outlook.com\"\nsmtp.sasl.xoauth2.token.command = [\"ortie\", \"token\", \"show\", \"-a\", \"outlook\"]\n```\n\nTo use the native Microsoft Graph API instead of IMAP/SMTP, replace the blocks above with a single OAuth 2.0 bearer token (sending goes through Graph too, so no SMTP is needed):\n\n```\nmsgraph.auth.token.command = [\"ortie\", \"token\", \"show\", \"-a\", \"msgraph\"]\n```\n\nMail folders carry Graph's opaque folder ids; address them by name (`-m Archive`\n\n) or by a well-known name (`-m inbox`\n\n) and himalaya resolves the id.\n\nStandard IMAP/SMTP with your regular account password — no app password required.\n\n```\n[accounts.posteo]\n\nimap.server = \"imaps://posteo.de\"\nimap.sasl.plain.username = \"example@posteo.net\"\nimap.sasl.plain.password.command = \"pass show posteo\"\n\nsmtp.server = \"smtps://posteo.de\"\nsmtp.sasl.plain.username = \"example@posteo.net\"\nsmtp.sasl.plain.password.command = \"pass show posteo\"\n```\n\nFrom the [iCloud Mail](https://support.apple.com/en-us/HT202304) support page: the IMAP login is the name of your address (`johnappleseed`\n\n, not `johnappleseed@icloud.com`\n\n) while the SMTP login is the full address, and a dedicated [app-specific password](https://support.apple.com/en-us/HT204397) is required.\n\n```\n[accounts.icloud]\n\nimap.server = \"imaps://imap.mail.me.com:993\"\nimap.sasl.plain.username = \"johnappleseed\"\nimap.sasl.plain.password.command = \"pass show icloud\"\n\nsmtp.server = \"smtp://smtp.mail.me.com:587\"\nsmtp.starttls = true\nsmtp.sasl.plain.username = \"johnappleseed@icloud.com\"\nsmtp.sasl.plain.password.command = \"pass show icloud\"\n\nmailbox.alias.sent = \"Sent Messages\"\n```\n\nEvery command carries its own `--help`\n\n, the source of truth for its flags and syntax. The snippets below are a taste of the surface.\n\nBackend-agnostic commands run on the account's first configured backend, or the one picked with `-b/--backend`\n\n. When an `inbox`\n\nalias is set under `[mailbox.alias]`\n\n, `-m/--mailbox`\n\ndefaults to it.\n\n```\nhimalaya mailbox list\nhimalaya envelope list --page 2\nhimalaya envelope search from alice and after 2026-01-01 order by date desc\nhimalaya flag add --flag seen 1:3,5\nhimalaya message read 42\nhimalaya message copy --from INBOX --to Archives 42\nhimalaya attachment download 42\n```\n\n`envelope search`\n\nuses himalaya's own cross-backend query DSL; its grammar lives in `himalaya envelope search --help`\n\n.\n\nEach backend also exposes its full native API under its own subgroup, always against that backend (`-b/--backend`\n\nis ignored here):\n\n```\nhimalaya imap raw 'a1 SEARCH FROM \"alice@example.com\"\\r\\n'\nhimalaya jmap mailbox query --role drafts\nhimalaya gmail messages list -q \"from:alice is:unread\"\nhimalaya msgraph mail-folder list\nhimalaya smtp send -f me@example.com -t you@example.com < message.eml\n```\n\n`message compose`\n\n/ `reply`\n\n/ `forward`\n\ncover simple cases through flags. For rich MIME (MML directives, signing, encryption, an editor-driven flow), chain a composer such as [mml](https://github.com/pimalaya/mml) into `message send`\n\n/ `message add`\n\n, or stage a prepared file as a draft:\n\n```\nhimalaya message compose --to you@example.org --subject Hello --body Hi --send\nmml compose >(himalaya message send)\nhimalaya message add -m drafts --flag draft < message.eml\n```\n\nSee `himalaya message send --help`\n\nand the [mml](https://github.com/pimalaya/mml) docs for the composer chaining.\n\nEach invocation opens a fresh TCP+TLS+SASL session. To amortize the handshake, pair himalaya with [sirup](https://github.com/pimalaya/sirup): it serves a pre-authenticated IMAP/SMTP session over a Unix socket that `imap.server`\n\n/ `smtp.server`\n\ncan point at.\n\nHimalaya CLI is one of several front-ends to the Pimalaya libraries:\n\n[pimalaya/himalaya-tui](https://github.com/pimalaya/himalaya-tui): official TUI (in active development)[pimalaya/himalaya-vim](https://github.com/pimalaya/himalaya-vim): Vim plugin[dantecatalfamo/himalaya-emacs](https://github.com/dantecatalfamo/himalaya-emacs): Emacs plugin[jns/himalaya](https://www.raycast.com/jns/himalaya): Raycast extension[openclaw/openclaw](https://github.com/openclaw/openclaw/blob/main/skills/himalaya/SKILL.md): OpenClaw SKILL[parisni/dfzf](https://github.com/parisni/dfzf): dfzf integration\n\n## How different is it from aerc, mutt or alpine?\n\nAerc, mutt and alpine can be categorized as Terminal User Interfaces (TUI). When the program is executed, your terminal is locked into an event loop and you interact with your emails using keybinds.\n\nHimalaya is a Command-Line Interface (CLI). There is no event loop: you interact with your emails using shell commands, in a stateless way.\n\nA dedicated TUI ([himalaya-tui](https://github.com/pimalaya/himalaya-tui)) is in active development on top of the same Pimalaya libraries, and is definitely closer to aerc, mutt and alpine.\n\n## How are secrets resolved?\n\nEvery `*.passwd`\n\n/ `*.password`\n\n/ `*.token`\n\nfield accepts either a raw literal or a shell command that prints the secret on stdout. The raw form is convenient for testing but should not be used in production:\n\n```\nimap.sasl.plain.passwd.raw = \"***\"\nimap.sasl.plain.passwd.command = \"pass show example\"\nimap.sasl.plain.passwd.command = [\"pass\", \"show\", \"example\"]\n```\n\nNative keyring support was removed in v2. Use a third-party keyring CLI (`pass`\n\n, `secret-tool`\n\n, `gopass`\n\n…) as the `command`\n\n.\n\n## How is OAuth 2.0 handled?\n\nv2 does not ship OAuth flows. Use [pimalaya/ortie](https://github.com/pimalaya/ortie) (or any other token broker) to obtain an access token, then plug it as a `command`\n\nreturning the token on stdout. For JMAP, point `jmap.auth.bearer.token.command`\n\nat the broker; for IMAP/SMTP, route the bearer through a SASL mechanism that consumes a command-sourced password.\n\n## How does the wizard discover IMAP/SMTP/JMAP configs?\n\nThe wizard probes several discovery mechanisms in parallel on the email address domain, merges their results and keeps the most secure endpoint per service:\n\n**PACC**: well-known JSON, digest-verified against the[draft-ietf-mailmaint-pacc-02](https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-pacc-02)`_ua-auto-config`\n\nTXT record.**Thunderbird Autoconfiguration**: ISP main / well-known / ISPDB lookups, then MX-based retry, then the`mailconf=<URL>`\n\nTXT redirect.**RFC 6186 SRV**:`_imap._tcp`\n\n,`_imaps._tcp`\n\n,`_submission._tcp`\n\nlookups assembled into a single report.**RFC 8620 JMAP**: the SRV record and the`/.well-known/jmap`\n\nsession resource.\n\nA final WWW-Authenticate probe refines the advertised auth schemes, and a detected Google or Microsoft account short-circuits to its dedicated configurations. See [io-pim-discovery](https://github.com/pimalaya/io-pim-discovery) for the full chain.\n\n## How to debug Himalaya?\n\nUse `--log-level <level>`\n\n(alias `--log`\n\n) where `<level>`\n\nis one of `off`\n\n, `error`\n\n, `warn`\n\n, `info`\n\n, `debug`\n\n, `trace`\n\n:\n\n```\nhimalaya --log trace mailbox list\n```\n\nThe `RUST_LOG`\n\nenvironment variable is consulted when `--log`\n\nis not passed, and supports per-target filters (see the [ env_logger documentation](https://docs.rs/env_logger/latest/env_logger/#enabling-logging)).\n\n`RUST_BACKTRACE=1`\n\nenables full error backtraces.Logs are written to `stderr`\n\n, so they can be redirected easily to a file:\n\n```\nhimalaya --log trace mailbox list 2>/tmp/himalaya.log\n```\n\nYou can also send logs straight to a file via `--log-file <path>`\n\n:\n\n```\nhimalaya --log trace --log-file /tmp/himalaya.log mailbox list\n```\n\n## How to disable color output?\n\nSet `NO_COLOR=1`\n\nin your environment.\n\nThis project is developed with AI assistance. This section documents how, so users and downstream packagers can make informed decisions.\n\n**Tools**: Claude Code (Anthropic), invoked locally with a persistent project-scoped memory and a small set of repo-specific rules.**Used for**: Refactors, mechanical multi-file edits, boilerplate (feature gates, error enums, derive macros, trait impls), test scaffolding, doc polish, exploratory design conversations.**Not used for**: Engineering, critical code, git manipulation (commit, merge, rebase…), real-world tests.** Verification**: Every AI-assisted change is read, compiled, tested, and formatted before commit. Behavioural correctness is verified against the relevant RFC or upstream spec, not assumed from the model output. Tests are never adjusted to fit AI-generated code; the code is adjusted to fit correct behaviour.**Limitations**: AI models occasionally produce code that compiles and passes tests but is subtly wrong. The verification workflow catches most of this; it does not catch all of it. Bug reports are welcome and taken seriously.**Last reviewed**: 17/07/2026\n\nThis project is licensed under either of:\n\nat your option.\n\n- Chat on\n[Matrix](https://matrix.to/#/#pimalaya:matrix.org) - News on\n[Mastodon](https://fosstodon.org/@pimalaya)or[RSS](https://fosstodon.org/@pimalaya.rss) - Mail at\n[pimalaya.org@posteo.net](mailto:pimalaya.org@posteo.net)\n\nContributions are welcome: start with [CONTRIBUTING.md](/pimalaya/himalaya/blob/master/CONTRIBUTING.md), which opens with the Pimalaya-wide guides to read first.\n\nSpecial thanks to the [NLnet foundation](https://nlnet.nl/) and the [European Commission](https://www.ngi.eu/) that have been financially supporting the project for years:\n\n- 2022 → 2023:\n[NGI Assure](https://nlnet.nl/project/Himalaya/) - 2023 → 2024:\n[NGI Zero Entrust](https://nlnet.nl/project/Pimalaya/) - 2024 → 2026:\n[NGI Zero Core](https://nlnet.nl/project/Pimalaya-PIM/) *2027 in preparation…*\n\nIf you appreciate the project, feel free to donate using one of the following providers:", "url": "https://wpnews.pro/news/himalaya-cli-to-manage-emails", "canonical_source": "https://github.com/pimalaya/himalaya", "published_at": "2026-07-30 20:00:35+00:00", "updated_at": "2026-07-30 20:22:39.645996+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Himalaya", "Rust", "IMAP", "SMTP", "JMAP", "Gmail", "Microsoft Graph", "Rustls"], "alternates": {"html": "https://wpnews.pro/news/himalaya-cli-to-manage-emails", "markdown": "https://wpnews.pro/news/himalaya-cli-to-manage-emails.md", "text": "https://wpnews.pro/news/himalaya-cli-to-manage-emails.txt", "jsonld": "https://wpnews.pro/news/himalaya-cli-to-manage-emails.jsonld"}}