选项

使用 AgentMail API 为 AI 代理分配专属的电子邮件收件箱。适用于构建电子邮件代理、通过编程方式收发邮件、管理收件箱、处理附件、使用标签进行分类、创建待人工审批的草稿,或通过 webhook/WebSocket 设置实时通知。支持通过 pod 实现多租户隔离。

...展开全部
96
更新时间 2026-06-29

关于agentmail

AgentMail 是一款专为AI代理设计的API优先型电子邮件平台,通过开发者友好的SDK提供程序化电子邮件功能。它解决了为AI代理分配独立电子邮件身份,并使其能够自主发送、接收和管理电子邮件通信的难题。 开发者无需从头构建复杂的电子邮件基础设施,只需几行代码,即可快速为 AI 代理配置电子邮件收件箱,并将电子邮件功能集成到应用程序中。

该平台提供全面的电子邮件管理功能,包括可扩展的按需收件箱创建(支持自动生成或自定义电子邮件地址)、涵盖发送和回复功能的完整邮件生命周期管理、基于对话线程的群组分类、基于标签的组织管理以及附件处理。 该平台同时支持纯文本和 HTML 电子邮件格式,以确保最佳送达率,并支持通过 webhook 和 WebSocket 实现实时通知。SDK 适用于 TypeScript/Node.js 和 Python 环境,并在两种语言中提供一致的 API。

AgentMail 该平台非常适合开发人员构建基于 AI 的电子邮件代理、客户支持自动化系统、外联与沟通工具,或任何需要程序化电子邮件功能的应用程序。它支持基于 pod 的隔离的多租户架构,因此非常适合需要为多个代理或客户提供独立电子邮件环境的 SaaS 应用程序。 无论您是在构建需要监控收件箱的 AI 助手、自动化跟进系统,还是由 AI 准备邮件供人工审核的草稿审批工作流,AgentMail 都能提供高效处理这些用例的基础设施和 API。

常见问题

AgentMail 支持哪些编程语言?

AgentMail [email protected] 提供对 TypeScript/Node.js 和 Python 的官方 SDK 支持。这两种 SDK 均提供相同的核心功能,包括管理收件箱、收发邮件、使用标签进行整理以及处理邮件线程。

我可以在AgentMail 中使用自定义电子邮件域名吗?

可以,在创建收件箱时,您可以使用自定义用户名和域名。如果您未指定自定义参数,AgentMail 将使用默认的agentmail.to 域名为您自动生成一个电子邮件地址。

AgentMail 是如何组织邮件对话的?

AgentMail 它采用“线程”方式将相关邮件归类到同一对话中,这与现代邮件客户端的工作原理类似。您可以列出线程、按标签筛选,并检索线程内的所有邮件。此外,您还可以使用自定义标签对邮件进行分类,实现灵活的管理。

我需要同时发送纯文本和 HTML 格式的邮件吗?

是的,AgentMail 建议始终同时发送邮件的纯文本和 HTML 版本,以确保最佳送达率。这能保证与不同邮件客户端的兼容性,并提高邮件成功送达的几率。

AgentMail 是否支持实时通知?

是的,AgentMail 支持通过 Webhooks 和 WebSockets 进行实时通知,当有新消息到达或代理收件箱中发生其他事件时,您的应用程序将立即收到通知。

在 GitHub 上查看

AgentMail SDK

AgentMail is an API-first email platform for AI agents. Install the SDK and initialize the client.

Installation

# TypeScript/Nodenpm install agentmail# Pythonpip install agentmail

Setup

import { AgentMailClient } from "agentmail";const client = new AgentMailClient({ apiKey: "YOUR_API_KEY" });
from agentmail import AgentMailclient = AgentMail(api_key="YOUR_API_KEY")

Inboxes

Create scalable inboxes on-demand. Each inbox has a unique email address.

// Create inbox (auto-generated address)const autoInbox = await client.inboxes.create();// Create with custom username and domainconst customInbox = await client.inboxes.create({  username: "support",  domain: "yourdomain.com",});// List, get, deleteconst inboxes = await client.inboxes.list();const fetchedInbox = await client.inboxes.get("[email protected]");await client.inboxes.delete("[email protected]");
# Create inbox (auto-generated address)inbox = client.inboxes.create()# Create with custom username and domainfrom agentmail.inboxes.types import CreateInboxRequestinbox = client.inboxes.create(    request=CreateInboxRequest(username="support", domain="yourdomain.com"),)# List, get, deleteinboxes = client.inboxes.list()inbox = client.inboxes.get(inbox_id="[email protected]")client.inboxes.delete(inbox_id="[email protected]")

Messages

Always send both text and html for best deliverability.

// Send messageawait client.inboxes.messages.send("[email protected]", {  to: "[email protected]",  subject: "Hello",  text: "Plain text version",  html: "<p>HTML version</p>",  labels: ["outreach"],});// Reply to messageawait client.inboxes.messages.reply("[email protected]", "msg_123", {  text: "Thanks for your email!",});// List and get messagesconst messages = await client.inboxes.messages.list("[email protected]");const message = await client.inboxes.messages.get("[email protected]", "msg_123");// Update labelsawait client.inboxes.messages.update("[email protected]", "msg_123", {  addLabels: ["replied"],  removeLabels: ["unreplied"],});
# Send messageclient.inboxes.messages.send(    inbox_id="[email protected]",    to="[email protected]",    subject="Hello",    text="Plain text version",    html="<p>HTML version</p>",    labels=["outreach"])# Reply to messageclient.inboxes.messages.reply(    inbox_id="[email protected]",    message_id="msg_123",    text="Thanks for your email!")# List and get messagesmessages = client.inboxes.messages.list(inbox_id="[email protected]")message = client.inboxes.messages.get(inbox_id="[email protected]", message_id="msg_123")# Update labelsclient.inboxes.messages.update(    inbox_id="[email protected]",    message_id="msg_123",    add_labels=["replied"],    remove_labels=["unreplied"])

Threads

Threads group related messages in a conversation.

// List threads (with optional label filter)const threads = await client.inboxes.threads.list("[email protected]", {  labels: ["unreplied"],});// Get thread detailsconst thread = await client.inboxes.threads.get("[email protected]", "thd_123");// Org-wide thread listingconst allThreads = await client.threads.list();
# List threads (with optional label filter)threads = client.inboxes.threads.list(inbox_id="[email protected]", labels=["unreplied"])# Get thread detailsthread = client.inboxes.threads.get(inbox_id="[email protected]", thread_id="thd_123")# Org-wide thread listingall_threads = client.threads.list()

Attachments

Send attachments with Base64 encoding. Retrieve from messages or threads.

// Send with attachmentconst content = Buffer.from(fileBytes).toString("base64");await client.inboxes.messages.send("[email protected]", {  to: "[email protected]",  subject: "Report",  text: "See attached.",  attachments: [    { content, filename: "report.pdf", contentType: "application/pdf" },  ],});// Get attachmentconst fileData = await client.inboxes.messages.getAttachment(  "[email protected]",  "msg_123",  "att_456",);
import base64# Send with attachmentcontent = base64.b64encode(file_bytes).decode()client.inboxes.messages.send(    inbox_id="[email protected]",    to="[email protected]",    subject="Report",    text="See attached.",    attachments=[{"content": content, "filename": "report.pdf", "content_type": "application/pdf"}])# Get attachmentfile_data = client.inboxes.messages.get_attachment(    inbox_id="[email protected]",    message_id="msg_123",    attachment_id="att_456")

Drafts

Create drafts for human-in-the-loop approval before sending.

// Create draftconst draft = await client.inboxes.drafts.create("[email protected]", {  to: "[email protected]",  subject: "Pending approval",  text: "Draft content",});// Send draft (converts to message)await client.inboxes.drafts.send("[email protected]", draft.draftId, {});
# Create draftdraft = client.inboxes.drafts.create(    inbox_id="[email protected]",    to="[email protected]",    subject="Pending approval",    text="Draft content")# Send draft (converts to message)client.inboxes.drafts.send(inbox_id="[email protected]", draft_id=draft.draft_id)

Pods

Multi-tenant isolation for SaaS platforms. Each customer gets isolated inboxes.

// Create pod for a customerconst pod = await client.pods.create({ clientId: "customer_123" });// Create inbox within podconst inbox = await client.pods.inboxes.create(pod.podId, {});// List inboxes scoped to podconst inboxes = await client.pods.inboxes.list(pod.podId);
# Create pod for a customerpod = client.pods.create(client_id="customer_123")# Create inbox within pod (pods.inboxes.create accepts flat kwargs)inbox = client.pods.inboxes.create(pod_id=pod.pod_id)# List inboxes scoped to podinboxes = client.pods.inboxes.list(pod_id=pod.pod_id)

Idempotency

Use clientId for safe retries on create operations.

const inbox = await client.inboxes.create({  clientId: "unique-idempotency-key",});// Retrying with same clientId returns the original inbox, not a duplicate
from agentmail.inboxes.types import CreateInboxRequestinbox = client.inboxes.create(    request=CreateInboxRequest(client_id="unique-idempotency-key"),)# Retrying with same client_id returns the original inbox, not a duplicate

Real-Time Events

For real-time notifications, see the reference files:

  • webhooks.md - HTTP-based notifications (requires public URL)
  • websockets.md - Persistent connection (no public URL needed)

安装 agentmail

下载技能文件并将其解压到 .claude/skills/ 目录中。

下载ZIP

克隆仓库并复制技能文件到您的项目中。

git clone https://github.com/agentmail-to/agentmail-skills/blob/main/agentmail/SKILL.md # Copy SKILL.md to your .claude/skills/ directory

复制 复制
快速设置: 将技能文件夹复制到 .claude/skills/ 目录下,Claude 会自动检测并使用该技能

相关技能

web-search
更新时间 2026-06-29
webapp-testing
更新时间 2026-06-29
lark-base
更新时间 2026-07-05
computer-use
更新时间 2026-07-29
OR