Awesome-openclaw-skills apple-mail
Apple Mail.app integration for macOS. Read inbox, search emails, send emails, reply, and manage messages with fast direct access (no enumeration).
git clone https://github.com/sundial-org/awesome-openclaw-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/sundial-org/awesome-openclaw-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/apple-mail" ~/.claude/skills/sundial-org-awesome-openclaw-skills-apple-mail && rm -rf "$T"
T=$(mktemp -d) && git clone --depth=1 https://github.com/sundial-org/awesome-openclaw-skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/apple-mail" ~/.openclaw/skills/sundial-org-awesome-openclaw-skills-apple-mail && rm -rf "$T"
skills/apple-mail/SKILL.mdApple Mail
Interact with Mail.app via AppleScript and SQLite. Run scripts from:
cd {baseDir}
Commands
| Command | Usage |
|---|---|
| Refresh | |
| List recent | |
| Search | |
| Fast search | |
| Read email | |
| Delete | |
| Mark read | |
| Mark unread | |
| Send | ¹ |
| Reply | |
| List accounts | |
| List mailboxes | |
Refreshing Mail
Force Mail.app to check for new messages:
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)
does NOT auto-refresh — callmail-list.sh
first if you need fresh datamail-refresh.sh
Output Format
List/search returns:
ID | ReadStatus | Date | Sender | Subject
= unread, blank = read●
Gmail Mailboxes
⚠️ Gmail special folders need
[Gmail]/ prefix:
| Shows as | Use |
|---|---|
| |
| |
| |
| |
Custom labels work without prefix.
Fast Search (SQLite)
✨ Now safe even if Mail.app is running — copies database to temp file first.
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 |
|---|---|---|
| ~50ms | SQLite query, fastest |
| <1s | Simple AppleScript |
| 1-3s | AppleScript, direct mailbox access |
| 1-2s | Creates and sends message |
| ~2s | Position-optimized lookup |
| ~0.5s | Position-optimized lookup |
| ~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:
- Read multiple (separator between each)mail-read.sh 123 456 789
- Delete multiplemail-delete.sh 123 456 789
- Mark multiple as readmail-mark-read.sh 123 456
- Mark multiple as unreadmail-mark-unread.sh 123 456
⚠️ No auto-refresh: Scripts read cached data. Call
mail-refresh.sh first if you need latest emails.
Managing Emails
Delete emails:
scripts/mail-delete.sh 12345 # Delete one scripts/mail-delete.sh 12345 12346 12347 # Delete multiple
Mark as read/unread:
scripts/mail-mark-read.sh 12345 12346 # Mark as read scripts/mail-mark-unread.sh 12345 # Mark as unread
Bulk operations example:
# 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
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 |
|---|---|
| Open Mail.app before running scripts |
| Invalid account — check mail-accounts.sh |
| Invalid/deleted ID — get fresh from mail-list.sh |
| Invalid name — check mail-mailboxes.sh |
| 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):
- Query SQLite for account UUID, mailbox path, and approximate position
- AppleScript accesses the specific account directly (no iteration)
- Search starts at the approximate position (±5 messages buffer)
- 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.