CLI to manage emails via IMAP/SMTP. Use himalaya to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
Himalaya is a CLI email client that lets you manage emails from the terminal using IMAP, SMTP, Notmuch, or Sendmail backends.
references/configuration.md (config file setup + IMAP/SMTP authentication)references/message-composition.md (MML syntax for composing emails)himalaya --version to verify)~/.config/himalaya/config.toml# Pre-built binary (Linux/macOS — recommended)
curl -sSL https://raw.githubusercontent.com/pimalaya/himalaya/master/install.sh | PREFIX=~/.local sh
# macOS via Homebrew
brew install himalaya
# Or via cargo (any platform with Rust)
cargo install himalaya --locked
Run the interactive wizard to set up an account:
himalaya account configure
Or create ~/.config/himalaya/config.toml manually:
[accounts.personal]
email = "[email protected]"
display-name = "Your Name"
default = true
backend.type = "imap"
backend.host = "imap.example.com"
backend.port = 993
backend.encryption.type = "tls"
backend.login = "[email protected]"
backend.auth.type = "password"
backend.auth.cmd = "pass show email/imap" # or use keyring
message.send.backend.type = "smtp"
message.send.backend.host = "smtp.example.com"
message.send.backend.port = 587
message.send.backend.encryption.type = "start-tls"
message.send.backend.login = "[email protected]"
message.send.backend.auth.type = "password"
message.send.backend.auth.cmd = "pass show email/smtp"
# Gmail / Google Workspace (verified working config):
# backend.host = "imap.gmail.com", port 993, encryption tls
# message.send.backend.host = "smtp.gmail.com", port 587, encryption start-tls
# Use an App Password (myaccount.google.com/apppasswords) — required when 2FA is on.
# backend.auth.type = "password", backend.auth.raw = "<app password with spaces>"
cat << EOF | himalaya template send) is recommended for reliability. Interactive $EDITOR mode works with pty=true + background + process tool, but requires knowing the editor and its commands--output json for structured output that's easier to parse programmaticallyhimalaya account configure wizard requires interactive input — use PTY mode: terminal(command="himalaya account configure", pty=true)himalaya envelope list --page-size 5 "flag unseen" ✅ NOT himalaya envelope list --query "flag unseen" ❌flag unseen is the correct query for unread mail — NOT unseen or flag:unseenflags field in JSON output may return empty [] even for unread messages — flag unseen query also returned empty results in testing. Gmail's IMAP flag handling may not map cleanly to Himalaya's filter. Fall back to listing recent mail and checking manually if needed.* flag shown in plain text output means "recent" (IMAP RECENT flag), not "unread".himalaya folder list
List emails in INBOX (default):
himalaya envelope list
List emails in a specific folder:
himalaya envelope list --folder "Sent"
List with pagination:
himalaya envelope list --page 1 --page-size 20
himalaya envelope list from [email protected] subject meeting
Read email by ID (shows plain text):
himalaya message read 42
Export raw MIME:
himalaya message export 42 --full
To reply non-interactively from Hermes, read the original message, compose a reply, and pipe it:
# Get the reply template, edit it, and send
himalaya template reply 42 | sed 's/^$/\nYour reply text here\n/' | himalaya template send
Or build the reply manually:
cat << 'EOF' | himalaya template send
From: [email protected]
To: [email protected]
Subject: Re: Original Subject
In-Reply-To: <original-message-id>
Your reply here.
EOF
Reply-all (interactive — needs $EDITOR, use template approach above instead):
himalaya message reply 42 --all
# Get forward template and pipe with modifications
himalaya template forward 42 | sed 's/^To:.*/To: [email protected]/' | himalaya template send
Non-interactive (use this from Hermes) — pipe the message via stdin:
cat << 'EOF' | himalaya template send
From: [email protected]
To: [email protected]
Subject: Test Message
Hello from Himalaya!
EOF
Or with headers flag:
himalaya message write -H "To:[email protected]" -H "Subject:Test" "Message body here"
Note: himalaya message write without piped input opens $EDITOR. This works with pty=true + background mode, but piping is simpler and more reliable.
Move to folder — TARGET comes before IDs (not after):
# Correct syntax — move one or more messages
himalaya message move "Archive" 42
himalaya message move "[Gmail]/Trash" 42 43 44 # bulk move, space-separated IDs
Copy to folder:
himalaya message copy 42 "Important"
himalaya message delete does NOT work with Gmail via IMAP — it throws a "No folder Trash" error.
Instead, move to Gmail's trash folder:
# Gmail — move one or more messages to trash (supports multiple IDs)
himalaya message move "[Gmail]/Trash" 42 43 44
Add flag:
himalaya flag add 42 --flag seen
Remove flag:
himalaya flag remove 42 --flag seen
List accounts:
himalaya account list
Use a specific account:
himalaya --account work envelope list
Save attachments from a message:
himalaya attachment download 42
Save to specific directory:
himalaya attachment download 42 --dir ~/Downloads
Most commands support --output for structured output:
himalaya envelope list --output json
himalaya envelope list --output plain
Enable debug logging:
RUST_LOG=debug himalaya envelope list
Full trace with backtrace:
RUST_LOG=trace RUST_BACKTRACE=1 himalaya envelope list
himalaya --help or himalaya <command> --help for detailed usage.references/message-composition.md).pass, system keyring, or a command that outputs the password.pzlc legn gziz vsxs) — Gmail accepts both with and without spaces, but keep them as-is to avoid typos.