$npx -y skills add agentscope-ai/QwenPaw --skill himalaya-enCLI 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).
| 1 | # Himalaya Email CLI |
| 2 | |
| 3 | Himalaya is a CLI email client that lets you manage emails from the terminal using IMAP, SMTP, Notmuch, or Sendmail backends. |
| 4 | |
| 5 | ## References |
| 6 | |
| 7 | - `references/configuration.md` (config file setup + IMAP/SMTP authentication) |
| 8 | |
| 9 | ## Prerequisites |
| 10 | |
| 11 | 1. **Himalaya CLI** - the `himalaya` binary must already be on `PATH`. Check with `himalaya --version`. |
| 12 | - **Recommended: v1.2.0 or newer.** Older releases can fail against some IMAP servers; v1.2.0+ includes related fixes. |
| 13 | 2. A configuration file at `~/.config/himalaya/config.toml` |
| 14 | 3. IMAP/SMTP credentials configured (password stored securely) |
| 15 | |
| 16 | ## Configuration Setup |
| 17 | |
| 18 | Run the interactive wizard to set up an account (replace `default` with |
| 19 | any name you want, e.g. `gmail`, `work`): |
| 20 | |
| 21 | ```bash |
| 22 | himalaya account configure default |
| 23 | ``` |
| 24 | |
| 25 | Or create `~/.config/himalaya/config.toml` manually: |
| 26 | |
| 27 | ```toml |
| 28 | [accounts.personal] |
| 29 | email = "you@example.com" |
| 30 | display-name = "Your Name" |
| 31 | default = true |
| 32 | |
| 33 | backend.type = "imap" |
| 34 | backend.host = "imap.example.com" |
| 35 | backend.port = 993 |
| 36 | backend.encryption.type = "tls" |
| 37 | backend.login = "you@example.com" |
| 38 | backend.auth.type = "password" |
| 39 | backend.auth.cmd = "pass show email/imap" # or use keyring |
| 40 | |
| 41 | message.send.backend.type = "smtp" |
| 42 | message.send.backend.host = "smtp.example.com" |
| 43 | message.send.backend.port = 587 |
| 44 | message.send.backend.encryption.type = "start-tls" |
| 45 | message.send.backend.login = "you@example.com" |
| 46 | message.send.backend.auth.type = "password" |
| 47 | message.send.backend.auth.cmd = "pass show email/smtp" |
| 48 | ``` |
| 49 | |
| 50 | If you are using 163 mail account, add `backend.extensions.id.send-after-auth = true` in the config file to ensure proper functionality. |
| 51 | |
| 52 | ## Common Operations |
| 53 | |
| 54 | ### List Folders |
| 55 | |
| 56 | ```bash |
| 57 | himalaya folder list |
| 58 | ``` |
| 59 | |
| 60 | ### List Emails |
| 61 | |
| 62 | List emails in INBOX (default): |
| 63 | |
| 64 | ```bash |
| 65 | himalaya envelope list |
| 66 | ``` |
| 67 | |
| 68 | List emails in a specific folder: |
| 69 | |
| 70 | ```bash |
| 71 | himalaya envelope list --folder "Sent" |
| 72 | ``` |
| 73 | |
| 74 | List with pagination: |
| 75 | |
| 76 | ```bash |
| 77 | himalaya envelope list --page 1 --page-size 20 |
| 78 | ``` |
| 79 | |
| 80 | If meet with error, try: |
| 81 | |
| 82 | ```bash |
| 83 | himalaya envelope list -f INBOX -s 1 |
| 84 | ``` |
| 85 | |
| 86 | ### Search Emails |
| 87 | |
| 88 | ```bash |
| 89 | himalaya envelope list from john@example.com subject meeting |
| 90 | ``` |
| 91 | |
| 92 | ### Read an Email |
| 93 | |
| 94 | Read email by ID (shows plain text): |
| 95 | |
| 96 | ```bash |
| 97 | himalaya message read 42 |
| 98 | ``` |
| 99 | |
| 100 | Export raw MIME: |
| 101 | |
| 102 | ```bash |
| 103 | himalaya message export 42 --full |
| 104 | ``` |
| 105 | |
| 106 | ### Send / Compose Emails |
| 107 | |
| 108 | **Recommended approach:** Use `template write | template send` pipeline for simple emails. |
| 109 | |
| 110 | **Send a simple email:** |
| 111 | |
| 112 | ```bash |
| 113 | export EDITOR=cat |
| 114 | himalaya template write \ |
| 115 | -H "To: recipient@example.com" \ |
| 116 | -H "Subject: Email Subject" \ |
| 117 | "Email body content" | himalaya template send |
| 118 | ``` |
| 119 | |
| 120 | **Send with multiple headers:** |
| 121 | |
| 122 | ```bash |
| 123 | export EDITOR=cat |
| 124 | himalaya template write \ |
| 125 | -H "To: recipient@example.com" \ |
| 126 | -H "Cc: cc@example.com" \ |
| 127 | -H "Subject: Email Subject" \ |
| 128 | "Email body content" | himalaya template send |
| 129 | ``` |
| 130 | |
| 131 | **Send with attachments (using Python):** |
| 132 | |
| 133 | For emails with attachments, use Python's `smtplib` and `email.mime` modules: |
| 134 | |
| 135 | ```python |
| 136 | import smtplib |
| 137 | from email.mime.multipart import MIMEMultipart |
| 138 | from email.mime.text import MIMEText |
| 139 | from email.mime.base import MIMEBase |
| 140 | from email import encoders |
| 141 | |
| 142 | msg = MIMEMultipart() |
| 143 | msg['From'] = 'sender@163.com' |
| 144 | msg['To'] = 'recipient@example.com' |
| 145 | msg['Subject'] = 'Email with attachment' |
| 146 | |
| 147 | msg.attach(MIMEText('Email body', 'plain')) |
| 148 | |
| 149 | # Add attachment |
| 150 | with open('/path/to/file.pdf', 'rb') as f: |
| 151 | part = MIMEBase('application', 'octet-stream') |
| 152 | part.set_payload(f.read()) |
| 153 | encoders.encode_base64(part) |
| 154 | part.add_header('Content-Disposition', 'attachment; filename="file.pdf"') |
| 155 | msg.attach(part) |
| 156 | |
| 157 | server = smtplib.SMTP_SSL('smtp.163.com', 465) |
| 158 | server.login('sender@163.com', 'password') |
| 159 | server.send_message(msg) |
| 160 | server.quit() |
| 161 | ``` |
| 162 | |
| 163 | **⚠️ MML attachment limitations:** The `template send` command with MML format may fail with "cannot parse MML message: empty body" when using multipart/attachments. This is a known issue in himalaya v1.1.0. Use Python approach for attachments. |
| 164 | |
| 165 | **⚠️ Avoid `message write` for automation:** The `himalaya message write` command requires interactive TUI selection (Edit/Discard/Quit) and will hang in non-interactive environments. |
| 166 | |
| 167 | **⚠️ `message send` limitations:** Direct `himalaya message send <raw_email>` may fail with "cannot send message without a recipient" due to header parsing issues. Use `template send` instead. |
| 168 | |
| 169 | **Configuration requirement:** Ensure `message.send.save-to-folder` is set in con |