| name | himalaya |
| description | Use for generic email tasks on connected mail accounts: search, read, summarize, draft, reply, forward, send, and organize email over IMAP/SMTP. This is the better match for normal mailbox work that is not specifically a Gmail or Google Workspace request. |
| homepage | https://github.com/pimalaya/himalaya |
| metadata | {"openclaw":{"emoji":"📧","displayName":"Email","requires":{"bins":["himalaya"]},"install":[{"id":"brew","kind":"brew","formula":"himalaya","bins":["himalaya"],"label":"Install Himalaya (brew)","versionCommand":["himalaya","--version"],"versionRegex":"himalaya v?(?<version>[0-9]+\\.[0-9]+\\.[0-9]+)","recommendedVersion":"1.2.0"}]}} |
Himalaya Email CLI
Himalaya is a CLI email client that lets you manage emails from the terminal using IMAP, SMTP, Notmuch, or Sendmail backends.
References
references/configuration.md (config file setup + IMAP/SMTP authentication)
references/message-composition.md (MML syntax for composing emails)
scripts/send_template.py (shared Himalaya send wrapper with narrow iCloud retry)
scripts/icloud_send_smoke.py (repeatable iCloud send smoke harness)
Prerequisites
- Himalaya CLI installed (
himalaya --version to verify)
- A configuration file at
~/.config/himalaya/config.toml
- IMAP/SMTP credentials configured (password stored securely)
- For the stock Homebrew build, prefer password or app-password auth. The local
himalaya v1.1.0 build here does not include OAuth2 support.
Automation Rule
- Prefer direct safe-bin invocation first:
himalaya account list,
himalaya folder list, then himalaya envelope list.
- Use Himalaya for email only. It is not a fallback for Google Calendar, Drive,
Docs, Sheets, or Contacts.
- When a Gmail-specific
gog task fails because Google auth/provider/tooling is
unavailable, use Himalaya only if himalaya account list or config proves the
account is the same mailbox the user intended.
- For sends, never silently switch sender identities. If the same-mailbox
account is unclear, stop and ask the user before sending.
- Before drafting an email reply, re-read the message/thread or search recent
mail from that person first. Email is usually less volatile than chat, but
stale drafts can still answer the wrong state.
- When presenting email context for a reply decision, include the exact full
text of the latest relevant inbound email from the other person when it is
available, then add a concise summary only if useful. Do not force the user to
rely on a summary when the sender's actual wording matters.
- Before any approved email send, refresh the same thread/person again. Stop if
newer relevant thread movement, inbound or outbound, changes or duplicates the
reply, even when the draft and approval happen in the same short flow.
- If Gmail auth fails and Himalaya is not safely configured for the same
mailbox, report the blocker and ask whether the user wants to reconnect
Google.
- In Normal permissions mode, direct
himalaya ... commands are allowed. The
default restriction is on shell wrappers (bash -lc, sh -c), pipes,
chaining, and redirection.
- If you wrap
himalaya through openclaw nodes run, insert -- before the
child argv so Himalaya keeps its own flags.
- Ban dumb shell chaining, pipes, and redirection around
himalaya.
- Allow node execution when the runtime supports it. Missing
system.run.prepare alone does not make Himalaya execution invalid.
Inbox Triage Pattern
- Default to the inbox and a clear timeframe unless the user asks for a broader
mailbox audit.
- Shortlist before reading bodies. Use
himalaya envelope list with folder,
page-size, sender, subject, or date filters to inspect message metadata and
snippets first.
- Keep the first pass small, usually about 20 envelopes, then refine or page
older only if the result set is incomplete.
- Filter obvious noise early: newsletters, calendar churn, receipts,
automated alerts, delivery notifications, and resolved FYI threads.
- Read full messages only for shortlisted items where sender, subject,
timestamp, and preview are not enough to classify urgency or reply-needed
state.
- Escalate to thread/recent-mail context when a message appears to be part of an
active conversation and earlier or newer messages may change the answer.
- Bucket results as
Urgent, Needs reply soon, Waiting on them,
Schedule, Delegate, Archive / no action, or FYI.
- State scope and confidence: account, folder, timeframe/search terms, page
size, and whether the result is a sampled slice or a complete enough scan.
- Treat "needs reply" as an inference unless the thread context clearly shows
the user is the next responder.
Configuration Setup
Run the interactive wizard to set up an account:
himalaya account configure personal
Or create ~/.config/himalaya/config.toml manually:
[accounts.personal]
email = "you@example.com"
display-name = "Your Name"
default = true
folder.aliases.inbox = "INBOX"
folder.aliases.sent = "Sent"
folder.aliases.drafts = "Drafts"
folder.aliases.trash = "Trash"
backend.type = "imap"
backend.host = "imap.example.com"
backend.port = 993
backend.encryption.type = "tls"
backend.login = "you@example.com"
backend.auth.type = "password"
backend.auth.cmd = "pass show email/imap"
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 = "you@example.com"
message.send.backend.auth.type = "password"
message.send.backend.auth.cmd = "pass show email/smtp"
Use the provider-specific Gmail and iCloud templates in references/configuration.md instead of guessing mailbox names.
Common Operations
List Folders
himalaya folder list
List Emails
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
Search Emails
himalaya envelope list from john@example.com subject meeting
Read an Email
Read email by ID (shows plain text):
himalaya message read 42
Export raw MIME:
himalaya message export 42 --full
Reply to an Email
Interactive reply (opens $EDITOR):
himalaya message reply 42
Reply-all:
himalaya message reply 42 --all
Forward an Email
himalaya message forward 42
Write a New Email
Interactive compose (opens $EDITOR):
himalaya message write
Send directly using template:
cat << 'EOF' | python3 skills/himalaya/scripts/send_template.py --account personal
From: you@example.com
To: recipient@example.com
Subject: Test Message
Hello from Himalaya!
EOF
For agent-run or scripted CLI sends, prefer this wrapper over raw himalaya template send. It writes a local .eml archive plus a .result.json command
receipt under ~/.local/state/openclaw/email-send-proof by default, ensures a
Message-ID exists, and only then runs Himalaya. If that local archive cannot be
written, the wrapper refuses to send instead of creating an unprovable automated
send. Set OPENCLAW_EMAIL_PROOF_DIR or pass --proof-dir for a different local
proof directory.
The local proof is command evidence, not recipient delivery confirmation. Raw
Himalaya v1 does not expose SMTP RCPT acceptance details, so do not claim live
recipient proof unless you verified inbox arrival, a reply, or a provider bounce
with explicit approval. iCloud Sent is not reliable proof for this lane.
After sending an important reply, you may offer to monitor that thread for a
response. Ask before creating any monitor, and include the target, cadence, stop
condition, expiry, and draft-vs-send policy.
The wrapper behaves like normal Himalaya for no-attachment and small-attachment
sends, so those still attempt to save a Sent copy. Only larger iCloud attachment
payloads flip message.send.save-copy = false to avoid Himalaya's post-send
IMAP append timeout. If iCloud still reports a post-send append failure such as
Quota Exceeded, the wrapper treats that as ambiguous delivery and does not
retry the whole send.
If an explicit audit copy is approved, pass one or more --audit-bcc audit@example.com flags. Never add Bcc silently.
Or with headers flag:
himalaya message write -H "To:recipient@example.com" -H "Subject:Test" "Message body here"
Move/Copy Emails
Move to folder:
himalaya message move "Archive" 42
Copy to folder:
himalaya message copy "Important" 42
Delete an Email
himalaya message delete 42
Manage Flags
Add flag:
himalaya flag add 42 seen
Remove flag:
himalaya flag remove 42 seen
Multiple Accounts
List accounts:
himalaya account list
Use a specific account:
himalaya envelope list -a work
Attachments
Save attachments from a message:
himalaya attachment download 42
Save to specific directory:
himalaya attachment download 42 --dir ~/Downloads
Output Formats
Most commands support --output for structured output:
himalaya envelope list --output json
himalaya envelope list --output plain
Debugging
Enable debug logging:
RUST_LOG=debug himalaya envelope list
Full trace with backtrace:
RUST_LOG=trace RUST_BACKTRACE=1 himalaya envelope list
Tips
- Use
himalaya --help or himalaya <command> --help for detailed usage.
- In v1.1.x, account selection lives on the subcommand:
himalaya envelope list -a work, not himalaya --account work ....
- Message IDs are relative to the current folder; re-list after folder changes.
- For composing rich emails with attachments, use MML syntax (see
references/message-composition.md).
- Store passwords securely using
pass, system keyring, or a command that outputs the password.
- For automated sends, prefer
python3 skills/himalaya/scripts/send_template.py --account <name> over raw himalaya template send.
- The wrapper records local proof before the send and result metadata after the
send. Treat the printed
.eml, .result.json, and Message-ID as local command
proof only, not delivery proof.
- If the wrapper reports that it skipped the Sent copy for a larger iCloud attachment payload, tell the user plainly:
- the email was sent through Himalaya
- the Sent-folder copy was intentionally skipped to avoid the iCloud IMAP append timeout
- not seeing it in Sent does not mean the send failed
- If iCloud reports
cannot add IMAP message: Quota Exceeded after a send,
treat it like the same post-SMTP Sent-copy failure class. Do not retry the
whole email, because SMTP delivery may already have succeeded.
- When a user asks for proof after a Sent-copy skip, prefer concrete evidence:
- send a copy to the user's own address and verify it arrived in Inbox
- or show that the intended recipient replied / did not bounce
- do not claim Sent-folder presence when the wrapper explicitly skipped it