Home/Notes & PKM/apple-mail

apple-mail

Safe
Notes & PKM

Apple Mail.app integration for macOS. Read inbox, search emails, send emails, reply.

SKILL.md

# Apple Mail Interact with Mail.app via AppleScript and SQLite. Run scripts from: `cd {baseDir}` ## Commands | Command | Usage | |---------|-------| | **Refresh** | `scripts/mail-refresh.sh [account] [wait_seconds]` | | List recent | `scripts/mail-list.sh [mailbox] [account] [limit]` | | Search | `scripts/mail-search.sh "query" [mailbox] [limit]` | | Fast search | `scripts/mail-fast-search.sh "query" [limit]` | | Read email | `scripts/mail-read.sh <message-id> [message-id...]` | | Delete | `scripts/mail-delete.sh <message-id> [message-id...]` | | Mark read | `scripts/mail-mark-read.sh <message-id> [message-id...]` | | Mark unread | `scripts/mail-mark-unread.sh <message-id> [message-id...]` | | Send | `scripts/mail-send.sh "to@email.com" "Subject" "Body" [from-account] [attachment]` ¹ | | Reply | `scripts/mail-reply.sh <message-id> "body" [reply-all]` | | List accounts | `scripts/mail-accounts.sh` | | List mailboxes | `scripts/mail-mailboxes.sh [account]` | ## Refreshing Mail Force Mail.app to check for new messages: ```bash scripts/mail-refresh.sh # All accounts, wait up to 10s scripts/mail-refresh.sh Google # Specific account only scripts/mail-refresh.sh "" 5 # All accounts, max 5 seconds scripts/mail-refresh.sh Google 0 # Google account, no wait ``` **Smart sync detection:** - Script monitors database message count - Returns early when sync completes (no changes for 2s) - Reports new message count: `Sync complete in 2s (+3 messages)` **Notes:** - Mail.app must be running (script will error if not) - `mail-list.sh` does NOT auto-refresh — call `mail-refresh.sh` first if you need fresh data ## Output Format List/search returns: `ID | ReadStatus | Date | Sender | Subject` - `ā—` = unread, blank = read ## Gmail Mailboxes āš ļø Gmail special folders need `[Gmail]/` prefix: | Shows as | Use | |----------|-----| | `Spam` | `[Gmail]/Spam` | | `Sent Mail` | `[Gmail]/Sent Mail` | | `All Mail` | `[Gmail]/All Mail` | | `Trash` | `[Gmail]/Trash` | Custom labels work without prefix. ## Fast Search (SQLite) ✨ **Now safe even if Mail.app is running** — copies database to temp file first. ```bash scripts/mail-fast-search.sh "query" [limit] # ~50ms vs minutes ``` Previously required Mail.app to be quit. Now works anytime by copying the database to a temp file before querying. ## Performance Notes **Speed by operation:** | Operation | Speed | Notes | |-----------|-------|-------| | `mail-fast-search.sh` | ~50ms | SQLite query, fastest | | `mail-accounts.sh` | <1s | Simple AppleScript | | `mail-list.sh` | 1-3s | AppleScript, direct mailbox access | | `mail-send.sh` | 1-2s | Creates and sends message | | `mail-read.sh` | ~2s | Position-optimized lookup | | `mail-delete.sh` | ~0.5s | Position-optimized lookup | | `mail-mark-*.sh` | ~1.5s | Position-optimized lookup | **Optimization technique:** SQLite provides account UUID and approximate message position. AppleScript jumps directly to that position instead of iterating from the start. **Batch operations supported:** - `mail-read.sh 123 456 789` - Read multiple (separator between each) - `mail-delete.sh 123 456 789` - Delete multiple - `mail-mark-read.sh 123 456` - Mark multiple as read - `mail-mark-unread.sh 123 456` - Mark multiple as unread **āš ļø No auto-refresh:** Scripts read cached data. Call `mail-refresh.sh` first if you need latest emails. ## Managing Emails **Delete emails:** ```bash scripts/mail-delete.sh 12345 # Delete one scripts/mail-delete.sh 12345 12346 12347 # Delete multiple ``` **Mark as read/unread:** ```bash scripts/mail-mark-read.sh 12345 12346 # Mark as read scripts/mail-mark-unread.sh 12345 # Mark as unread ``` **Bulk operations example:** ```bash # Find spam emails scripts/mail-fast-search.sh "spam" 50 > spam.txt # Extract IDs and delete them grep "^[0-9]" spam.txt | cut -d'|' -f1 | xargs scripts/mail-delete.sh ``` ## Reading Email Bodies ```bash scripts/mail-read.sh 12345 # Single email scripts/mail-read.sh 12345 12346 12347 # Multiple emails (separated output) ``` Uses position-optimized lookup (~2s per message). Multiple emails are separated by `========` with a summary at the end. ## Errors | Error | Cause | |-------|-------| | `Mail.app is not running` | Open Mail.app before running scripts | | `Account not found` | Invalid account — check mail-accounts.sh | | `Message not found` | Invalid/deleted ID — get fresh from mail-list.sh | | `Can't get mailbox` | Invalid name — check mail-mailboxes.sh | | `Mail database not found` | SQLite DB missing — check ~/Library/Mail/V{9,10,11}/MailData/ | ## Technical Details **Database:** `~/Library/Mail/V{9,10,11}/MailData/Envelope Index` **Message lookup method (optimized):** 1. Query SQLite for account UUID, mailbox path, and approximate position 2. AppleScript accesses the specific account directly (no iteration) 3. Search starts at the approximate position (±5 messages buffer) 4. Falls back to full mailbox search only if position hint fails **Safety:** - Fast search copies database to temp file before querying - Safe to use even if Mail.app is running - Delete/read/mark operations query live database but access is minimal ## Notes - Message IDs are internal, get fresh ones from list/search - Confirm recipient before sending - AppleScript search is slow but comprehensive; SQLite is fast for metadata - Delete/mark operations support bulk actions (pass multiple IDs) - Always refresh before listing if you need the absolute latest emails ¹ **Known limitation:** Mail.app adds a leading blank line to sent emails. This is an AppleScript/Mail.app behavior that cannot be bypassed.

More in Notes & PKM