Email CLI
Send, receive, and manage email from your terminal. Built for AI agents.
A single binary that gives your AI agent a real email address. Send, receive, reply, draft, sync, and manage contacts, broadcasts, segments, and topics through Resend -- all from the command line. No IMAP. No browser inbox. No MCP server. Just a local SQLite mailbox and a command surface agents discover at runtime.
Why | Install | How It Works | Commands | Agent Integration | Configuration | Contributing
Why
AI agents need email. The existing options are bad:
- IMAP/SMTP requires complex server configuration, credential management, and connection handling. Agents struggle with it.
- Email APIs work for sending, but agents need a local mailbox to track threads, drafts, and read state.
- Browser-based inboxes are not scriptable. Agents cannot use them.
Email CLI wraps the Resend API in a local-first CLI. Your agent gets a verified email address, a local SQLite mailbox, and structured JSON output with semantic exit codes. It calls agent-info once to learn every command, then works from memory.
It works just as well for humans.
Install
One-line install (pre-built binary, no Rust required)
|
Homebrew
Cargo
Update
Quick Start
# 1. Add your Resend API key
# 2. Register a sending identity
# 3. Send an email
# 4. Sync and read incoming mail
# 5. Reply (threads correctly with In-Reply-To + References)
How It Works
Three concepts:
- Profile -- a Resend API key. You can have multiple profiles for different Resend accounts.
- Account -- a sender/receiver identity (
agent@yourdomain.com). Each account belongs to a profile. - Local mailbox -- a SQLite database that stores messages, drafts, attachments, and sync cursors.
Resend handles delivery. Email CLI handles the local operating model: read tracking, threading, drafts, batch sends, and structured output.
┌────────────────────────────────┐
│ Your Agent / You │
│ (Claude, Codex, Gemini) │
└──────────────┬─────────────────┘
│ CLI commands
▼
┌────────────────────────────────┐
│ email-cli │
│ structured JSON output, │
│ semantic exit codes │
└──────────┬─────────┬───────────┘
│ │
┌─────▼──┐ ┌───▼────────┐
│ SQLite │ │ Resend API │
│ local │ │ (send, │
│ store │ │ receive, │
│ │ │ domains) │
└────────┘ └────────────┘
Every outgoing email gets a unique Message-ID; reply and send --reply-to-msg set In-Reply-To and References per RFC 5322, so threads display correctly in Gmail, Outlook, and Apple Mail.
Commands
Email CLI groups its commands by area:
- Email --
send,reply,forward,sync,inbox,draft,attachments - Identity --
profile,account,signature,domain,api-key - Audience (mailing lists) --
contact,segment,contact-property,topic,broadcast - Delivery --
outbox(durable send queue),webhook listen,events,email list,batch send - Daemon --
daemon(macOS menu bar with native notifications and live sync) - Agent tooling --
agent-info,skill install,completions - Ops --
update(self-update),log(command audit trail)
The canonical, always-current reference -- every command, subcommand alias, flag, and exit code -- lives in the CLI itself:
Audience primitives: Resend renamed "Audiences" to Segments in November 2025. Contacts are flat -- each contact can belong to zero, one, or multiple segments. Topics drive granular per-contact subscription preferences for broadcasts. Contact properties are typed custom fields for merge tags. Use
segment,topic, andcontact-propertyrespectively.
Agent Integration
Email CLI follows the agent-cli-framework patterns. Any agent that speaks structured JSON can use it.
Capability Discovery
Returns a JSON manifest of every command, flag, exit code, and output format. An agent calls this once and works from memory.
Structured Output
All commands produce JSON when piped or when you pass --json:
Errors include actionable suggestions:
Semantic Exit Codes
| Code | Meaning | Agent action |
|---|---|---|
| 0 | Success | Continue |
| 1 | Transient error (network) | Retry |
| 2 | Configuration error | Fix setup |
| 3 | Bad input | Fix arguments |
| 4 | Rate limited | Wait and retry |
Skill Self-Install
Writes a skill file to ~/.claude/skills/email-cli/, ~/.codex/skills/email-cli/, and ~/.gemini/skills/email-cli/. The skill tells agents the CLI exists and to run agent-info for full details.
Configuration
Local State
All data lives in ~/.local/share/email-cli/email-cli.db (override with --db <path>). Sibling directories:
draft-attachments/-- snapshots of files attached to draftsdownloads/-- fetched attachments (configurable via--output)
SQLite runs with WAL mode, busy timeout, and foreign keys enabled.
Security
- API keys live in the local SQLite database. Treat
email-cli.dbas sensitive. - Prefer
--api-key-env VAR_NAMEor--api-key-file pathover passing keys directly. - Attachment filenames are sanitized before writing to disk.
- Every send is written to a durable outbox with a stable
Idempotency-Keybefore delivery is attempted; retry withoutbox retryoroutbox flush.
Requirements
- A Resend API key with sending enabled
- A verified Resend domain (enable receiving on the domain for inbox sync)
- Rust 1.85+ if building from source (edition 2024)
Contributing
Contributions are welcome. See CONTRIBUTING.md for guidelines.
License
MIT -- see LICENSE.
Built by Boris Djordjevic at 199 Biotechnologies | Paperfoot AI
If this is useful to you: