| name | agentmail |
| description | Use when the agent needs to send, receive, or manage email autonomously. Gives the agent its own dedicated email inbox via AgentMail SDK. Covers inbox creation, message send/reply/forward, thread management, attachments, and domain configuration.
|
| version | 1.0.0 |
| author | r0b0tlab |
| license | MIT |
| compatibility | Requires Python 3.10+ and an AgentMail API key (free at https://console.agentmail.to). |
| metadata | {"version":"1.0.0","author":"r0b0tlab","platform":"linux, macos","hermes":{"tags":["email","communication","agentmail","agent-inbox","sdk"],"related_skills":["himalaya","google-workspace"]}} |
AgentMail — Agent-Owned Email via Python SDK
Overview
AgentMail gives AI agents their own email inbox at @agentmail.to. This skill
uses the official agentmail-python SDK (not MCP) for direct, scriptable email
operations: create inboxes, send/reply/forward messages, manage threads, handle
attachments, and configure custom domains.
Key distinction: This is for the agent's own identity. The agent sends
email as itself (e.g. hermes@agentmail.to), not as the user. For the user's
personal email, use himalaya or Gmail.
Quick Install
pip install agentmail python-dotenv
Environment Setup
Set the API key (get one free at https://console.agentmail.to):
export AGENTMAIL_API_KEY="am_your_key_here"
Or in .env:
AGENTMAIL_API_KEY=am_your_key_here
Core Commands
Initialize Client
import os
from agentmail import AgentMail
client = AgentMail(api_key=os.environ["AGENTMAIL_API_KEY"])
Create Inbox
inbox = client.inboxes.create(username="my-agent")
Send Email
client.inboxes.messages.send(
inbox.inbox_id,
to="recipient@example.com",
subject="Hello from my agent",
text="Plain text body",
html="<p>HTML body</p>",
)
List Messages
response = client.inboxes.messages.list(inbox.inbox_id, limit=10)
for msg in response.messages:
print(f"{msg.subject} — {msg.extracted_text[:100]}")
Reply to Message
client.inboxes.messages.reply(
inbox.inbox_id,
message_id,
text="My reply",
)
Forward Message
client.inboxes.messages.forward(
inbox.inbox_id,
message_id,
to=["other@example.com"],
)
Send with Attachments
import base64
with open("report.pdf", "rb") as f:
attachment = {
"filename": "report.pdf",
"content": base64.b64encode(f.read()).decode(),
}
client.inboxes.messages.send(
inbox.inbox_id,
to="recipient@example.com",
subject="Report attached",
text="See attached.",
attachments=[attachment],
)
List Inboxes
for inbox in client.inboxes.list().inboxes:
print(f"{inbox.email_address} ({inbox.inbox_id})")
Manage Threads
threads = client.inboxes.threads.list(inbox.inbox_id, limit=5)
for t in threads.threads:
print(f"{t.subject} — {len(t.messages)} messages")
thread = client.inboxes.threads.get(inbox.inbox_id, thread_id)
for msg in thread.messages:
print(f" {msg.from_}: {msg.extracted_text[:80]}")
When to Use
- Agent needs to send outbound email (notifications, reports, outreach)
- Agent needs to receive and process incoming email
- Agent needs its own identity for service sign-ups
- Agent-to-agent or agent-to-human communication
- Automated follow-ups and email workflows
When NOT to Use
- Reading the user's personal email → use himalaya or google-workspace
- Sending email on behalf of the user (not the agent) → use himalaya
- Transactional email at scale → use SendGrid/Postmark
Pitfalls
-
Rate limits. AgentMail returns 429 with Retry-After header. Use
exponential backoff or check error.body for details.
-
extracted_text vs text. When reading messages, prefer
msg.extracted_text — it strips quoted history. msg.text includes the
full quoted thread.
-
Idempotent inbox creation. Pass client_id to inboxes.create() to
safely retry without duplicates:
inbox = client.inboxes.create(username="agent", client_id="my-agent-v1")
-
API key rotation. Calling agent.sign_up() again with the same email
rotates the API key. Store it securely after first use.
-
Free tier limits. 3 inboxes, 3,000 emails/month. Custom domains
require paid plans.
-
Attachment encoding. Attachments must be base64-encoded content, not
file paths. Use base64.b64encode(open(f,'rb').read()).decode().
-
OTP expiry. Agent verification OTP expires after 24 hours, max 10
attempts. Request a new one if needed.
-
Thread update limits. Threads with 100+ messages reject update requests
with 422.
Verification Checklist
References
references/api-reference.md — Full SDK endpoint reference. Load when you
need the exact parameters for any AgentMail API call.
references/workflows.md — Common workflow patterns (sign-up verification,
email parsing, cron-based inbox monitoring). Load when implementing complex
email automation.
references/troubleshooting.md — Error codes, debugging, and FAQ. Load when
hitting unexpected errors.