Experimental. Shouldn't be considered production ready yet.
A Deno CLI for reading and managing Apple Mail on macOS.
Uses JXA (JavaScript for Automation) to control Mail.app. Human-readable text by default, --json for structured output.
./install.shThis creates a wrapper script at ~/bin/nanomail.
- macOS 14 (Sonoma) or later
- Deno 2.0+
~/binin yourPATH
Grant your terminal app in System Settings > Privacy & Security > Automation:
- Mail — allow automation (prompted on first run)
# List email accounts
nanomail accounts
# List mailboxes for an account
nanomail mailboxes -a "iCloud"
# List messages in a mailbox
nanomail list -a "iCloud" -m "INBOX" --limit 10
nanomail list -a "iCloud" -m "INBOX" --unread
nanomail list -a "iCloud" -m "INBOX" --flagged
nanomail list -a "iCloud" -m "INBOX" --since "2025-12-01"
# Show full message
nanomail show -a "iCloud" -m "INBOX" --id 12345
# Search by subject/sender
nanomail search "invoice" -a "iCloud"
nanomail search "meeting" -a "iCloud" --from "boss@example.com"
# Unread messages (all accounts or one)
nanomail unread
nanomail unread -a "iCloud"
# Messages received today
nanomail today
nanomail today -a "iCloud"
# Flagged messages
nanomail flagged
nanomail flagged -a "iCloud" -m "INBOX"
# Send an email
nanomail send -a "iCloud" --to "user@example.com" --subject "Hi" --body "Hello"
# Create a draft (saved to Drafts folder for review)
nanomail draft -a "iCloud" --to "user@example.com" --subject "Hi" --body "Hello"
# Reply to a message (saves as draft by default, quotes original)
nanomail reply -a "iCloud" -m "INBOX" --id 12345 --body "Thanks!"
nanomail reply -a "iCloud" -m "INBOX" --id 12345 --body "Thanks!" --all
nanomail reply -a "iCloud" -m "INBOX" --id 12345 --body "Thanks!" --send
# Forward a message (saves as draft by default, attachments not included)
nanomail forward -a "iCloud" -m "INBOX" --id 12345 --to "user@example.com" --body "FYI"
nanomail forward -a "iCloud" -m "INBOX" --id 12345 --to "user@example.com" --send
# Reply/forward via draft sub-command (always draft, no --send)
nanomail draft reply -a "iCloud" -m "INBOX" --id 12345 --body "Thanks!"
nanomail draft forward -a "iCloud" -m "INBOX" --id 12345 --to "user@example.com"
# Mark read/unread/flagged/unflagged
nanomail mark -a "iCloud" -m "INBOX" --id 12345 --read
nanomail mark -a "iCloud" -m "INBOX" --id 12345 --flagged
# Move to another mailbox
nanomail move -a "iCloud" -m "INBOX" --id 12345 --to "archive"
# Mark as junk
nanomail junk -a "iCloud" -m "INBOX" --id 12345
# List or save attachments
nanomail attachments -a "iCloud" -m "INBOX" --id 12345
nanomail attachments -a "iCloud" -m "INBOX" --id 12345 --save /tmp
# Per-command help
nanomail help list| Flag | Description |
|---|---|
--json |
Output JSON instead of human-readable text |
--limit N |
Max results to return |
--offset N |
Skip first N results (pagination) |
Default output is human-readable text with relative dates ("Today, 10:30 AM", "Yesterday, 3:15 PM"). Use --json for structured JSON with ISO 8601 dates.
JSON shapes:
- accounts:
name,email,enabled - mailboxes:
name,unreadCount - list/search/today/flagged:
id,subject,sender,dateSent,read,flagged - show: all above plus
to,cc,dateReceived,body,html(optional) - unread (no account): same as list/search (messages from all accounts)
- unread (with account):
account,mailbox,unreadCount,messagesarray - send:
{sent, to, subject} - draft:
{drafted, to, subject} - reply:
{replied, to, subject, draft} - forward:
{forwarded, to, subject, draft} - mark:
{marked, id, read, flagged} - move:
{moved, id, to} - junk:
{junked, id}
TEST.md contains integration test instructions designed to be run by a coding agent (like Claude Code). To run them:
claude -p "Read TEST.md and run all the tests. Report pass/fail for each."
Symlink this repo into your project's .claude/skills/:
ln -s /path/to/nanomail /your/project/.claude/skills/nanomailThe repo root contains a SKILL.md that teaches Claude Code how to use nanomail for email access.
MIT