-
Notifications
You must be signed in to change notification settings - Fork 104
Add AgentMail as an alternative email channel #7
Description
Summary
Add AgentMail as an alternative email channel for inbound email and two-way conversations, alongside the existing channels.
Phantom already has outbound email via Resend (one API key, works out of the box). For inbound email and two-way conversations, the current option is IMAP/SMTP via ImapFlow + Nodemailer, which requires 8 credentials and manual IMAP configuration.
AgentMail provides a simpler alternative: one API key for both sending and receiving, with native threading, webhook-based inbound delivery, and automatic deliverability (SPF/DKIM/DMARC).
Current email capabilities
| Capability | Current solution | Setup complexity |
|---|---|---|
| Outbound email | Resend (already built, one API key) | Easy |
| Inbound email | IMAP via ImapFlow (8 credentials) | Hard |
| Two-way threads | IMAP + SMTP + manual header threading | Hard |
AgentMail would replace the IMAP/SMTP path with a single API key for both directions, while Resend remains the default for outbound-only use cases.
Why
The IMAP/SMTP channel requires IMAP host/port/user/pass, SMTP host/port/user/pass, plus configuring your email provider to allow IMAP access. AgentMail reduces two-way email to one API key and handles deliverability automatically.
This is additive. Resend stays as the default outbound channel. IMAP/SMTP stays for users who want full control. AgentMail adds an easier path for two-way email conversations.
What to build
Create src/channels/agentmail.ts implementing the Channel interface from src/channels/types.ts. Use the agentmail npm package (TypeScript SDK, works with Bun).
Requirements
- Implement
AgentMailChannelclass with allChannelinterface methods - Use the AgentMail SDK for sending and receiving emails
- Add a
handleWebhook()method for inbound email via webhooks - Wire the channel in
src/index.ts(follow the pattern used forEmailChannel) - Add a webhook route in
src/core/server.tsat/agentmail/webhook - Add a config section in
config/channels.yaml(disabled by default) - Write tests in
src/channels/__tests__/agentmail.test.ts
Reference files
| File | What to learn from it |
|---|---|
src/channels/types.ts |
The Channel interface to implement (4 methods) |
src/channels/email.ts |
Existing IMAP/SMTP email channel (reference for email patterns) |
src/channels/webhook.ts |
Webhook handling pattern |
src/index.ts (channel registration block) |
How channels are wired at startup |
src/core/server.ts |
Where to add the webhook route |
CLAUDE.md |
Project standards, the Cardinal Rule, what NOT to do |
AgentMail resources
- Documentation
- TypeScript SDK on npm (v0.3.7, supports Bun)
- SDK source on GitHub
- Webhook setup guide
- Free tier: 3 inboxes, 3,000 emails/month (enough for development and testing)
Configuration
# config/channels.yaml
agentmail:
enabled: false # opt-in only
api_key: \${AGENTMAIL_API_KEY}
inbox_id: phantom@agentmail.to
webhook_secret: \${AGENTMAIL_WEBHOOK_SECRET}Environment variables
| Variable | Description |
|---|---|
AGENTMAIL_API_KEY |
API key from agentmail.to dashboard |
AGENTMAIL_WEBHOOK_SECRET |
Webhook verification secret (Svix-based) |
Acceptance criteria
-
AgentMailChannelimplements allChannelinterface methods - Inbound email via webhooks converts to
InboundMessagecorrectly - Outbound email sends via AgentMail SDK
- Threading works (replies go to the correct thread)
- Config-driven (disabled by default, enabled via channels.yaml)
- Tests pass with mocked AgentMail client
-
bun run lintclean,bun run typecheckclean,bun testpasses - No
anytypes, no@ts-ignore, files under 300 lines - Existing email channels (Resend, IMAP/SMTP) are unchanged
Estimated scope
- ~150-200 lines for
agentmail.ts - ~100-150 lines for tests
- ~15 lines in
index.ts(registration) - ~10 lines in
server.ts(webhook route) - ~5 lines in
channels.yaml(config section) - 1 line in
package.json(bun add agentmail)