skills/apple-mail/mail-read/SKILL.md
Read the full content of a specific email by ROWID, subject search, or description. Shows headers, body, and any attachment names. Use when user wants to read a specific email, see the full text of a message, or asks "what does that email say". Arguments: ROWID number, subject keywords, or a description of the email to find.
npx skillsauth add aashari/ai-agent-skills mail-readInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Looking for: $ARGUMENTS
ROWID="$ARGUMENTS"
DB="$HOME/Library/Mail/V10/MailData/Envelope Index"
sqlite3 "$DB" "
SELECT datetime(m.date_received,'unixepoch','localtime') as dt,
s.subject, a.address as sender, a.comment as name,
mb.url as mailbox, m.ROWID, m.read, m.flagged
FROM messages m
JOIN subjects s ON m.subject = s.ROWID
JOIN addresses a ON m.sender = a.ROWID
JOIN mailboxes mb ON m.mailbox = mb.ROWID
WHERE m.ROWID = ${ROWID};" 2>/dev/null
sqlite3 "$DB" "
SELECT datetime(m.date_received,'unixepoch','localtime') as dt,
s.subject, a.address as sender, mb.url, m.ROWID
FROM messages m
JOIN subjects s ON m.subject=s.ROWID
JOIN addresses a ON m.sender=a.ROWID
JOIN mailboxes mb ON m.mailbox=mb.ROWID
WHERE (s.subject LIKE '%QUERY%' OR a.address LIKE '%QUERY%' OR a.comment LIKE '%QUERY%')
AND m.deleted=0
AND mb.url NOT LIKE '%Spam%'
ORDER BY m.date_received DESC LIMIT 5;" 2>/dev/null
If multiple matches, show options and ask which one.
sqlite3 "$DB" "
SELECT a.address, a.comment, r.type
FROM recipients r
JOIN addresses a ON r.address = a.ROWID
WHERE r.message = <ROWID>
ORDER BY r.type, r.position;" 2>/dev/null
sqlite3 "$DB" "
SELECT att.name FROM attachments att
WHERE att.message = <ROWID>;" 2>/dev/null
First check summaries table for fast-path (no file I/O, available for ~5% of recent emails):
sqlite3 "$DB" "SELECT su.summary FROM messages m JOIN summaries su ON m.summary = su.ROWID WHERE m.ROWID = <ROWID>;" 2>/dev/null
If no summary, parse the emlx:
python3 ~/.claude/skills/_mail-shared/parser.py <ROWID>
find ~/Library/Mail/V10/ -name "<ROWID>.emlx" 2>/dev/null | head -1
# If not found, try partial (IMAP lazy-load — body is still readable):
find ~/Library/Mail/V10/ -name "<ROWID>.partial.emlx" 2>/dev/null | head -1
The parser handles partial fallback automatically. Use raw find only for debugging.
Email Details
From: [name] <address>
To: [recipients]
CC: [if any]
Date: [datetime]
Subject: [subject]
Account: [derived from mailbox URL]
Attachments: [filenames if any]
[Full body text, formatted naturally]
Offer:
data-ai
Show work emails only, filtered to Exchange/EWS accounts and corporate email domains. Digest with priorities. Use when user asks about work email, work inbox, or wants to separate work from personal mail. Arguments: optional date range or "today", "yesterday", "this week".
testing
Intelligent inbox triage — surface the most important emails across all accounts, prioritized by urgency and requiring attention. Use when user wants a smart overview of what needs their attention, asks "what's important in my email", or wants help deciding what to read first. Arguments: optional time window (default: last 48 hours) or account filter.
data-ai
Find flight bookings, hotel reservations, travel itineraries, and booking confirmations from email. Use when user asks about upcoming trips, travel plans, booking references, flight details, or hotel reservations. Arguments: optional destination, airline, date range, or booking service.
testing
Show who sends the most email, communication frequency analysis, and relationship mapping. Use when user asks who emails them most, top contacts, communication patterns, or wants to understand their email social graph. Arguments: optional time range (default: last 90 days), account filter, or "humans only" to exclude automated senders.