New to Claude Skills? Learn how to install them →

sickn33 on GitHub

AgentMail

Free

Email infrastructure for AI agents.

Get this skill

Free · Opens the source repo

What AgentMail does

AgentMail provides a robust email solution specifically designed for AI agents, allowing them to create real email addresses under the @theagentmail.net domain. This service is accessible via a REST API, enabling agents to send and receive emails, register for various services, and manage verification processes seamlessly. The built-in karma system helps maintain the reputation of the shared domain by regulating actions based on karma points, thus preventing spam and abuse.

With AgentMail, developers can easily provision email accounts, send messages, and read incoming emails. The API supports features such as sending emails with optional HTML content, managing attachments, and registering webhooks for real-time email notifications. This makes it particularly useful for scenarios requiring automated email interactions, such as signing up for services like GitHub or AWS, or handling transactional communications.

The API's karma system adds a layer of complexity, as each action has a specific karma cost or reward. For instance, creating an email account costs 10 karma points, while sending an email deducts 1 point. This encourages thoughtful usage of the service and helps manage the overall health of the email infrastructure. Developers need to monitor their karma balance to ensure they can continue to perform actions that require karma.

Overall, AgentMail is an essential tool for developers and designers looking to integrate email capabilities into their AI agents, providing a straightforward and efficient way to handle email communication without the overhead of managing traditional email servers.

When to use it

Use AgentMail when your AI agent requires a real email address for signups, verification, or transactional emails, and when you need to automate email handling through an API.

When not to use it

AgentMail may not be suitable for projects that do not require email functionality or for those needing a more complex email handling system beyond the capabilities provided by the API.

What you can build with it

Automated Service Signups

Use AgentMail to automate the signup process for services like GitHub or AWS, allowing your AI agents to handle verification emails without manual intervention.

Transactional Email Handling

Integrate AgentMail to manage transactional emails for your applications, ensuring reliable communication for user registrations and notifications.

Webhook Notifications

Set up webhooks with AgentMail to receive real-time notifications of incoming emails, enabling your AI agents to respond promptly.

How to install AgentMail

View source

1. Install with the skills CLI

npx skills add sickn33/agentic-awesome-skills/agentmail --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by sickn33

AgentMail — Email for AI Agents

AgentMail gives AI agents real email addresses (@theagentmail.net) with a REST API. Agents can send and receive email, sign up for services (GitHub, AWS, Slack, etc.), and get verification codes. A karma system prevents spam and keeps the shared domain's reputation high.

Base URL: https://api.theagentmail.net

When to Use

  • An AI agent needs a real inbox/outbox for signups, verification flows, or transactional communication.
  • You need to provision AgentMail accounts, send messages, read inbox contents, or register inbound webhooks.
  • You need to monitor karma usage or wire email events into agent automation.

Quick start

All requests require Authorization: Bearer am_... header (API key from dashboard).

Create an email account (-10 karma)

curl -X POST https://api.theagentmail.net/v1/accounts \
  -H "Authorization: Bearer am_..." \
  -H "Content-Type: application/json" \
  -d '{"address": "my-agent@theagentmail.net"}'

Response: {"data": {"id": "...", "address": "my-agent@theagentmail.net", "displayName": null, "createdAt": 123}}

Send email (-1 karma)

curl -X POST https://api.theagentmail.net/v1/accounts/{accountId}/messages \
  -H "Authorization: Bearer am_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["recipient@example.com"],
    "subject": "Hello from my agent",
    "text": "Plain text body",
    "html": "<p>Optional HTML body</p>"
  }'

Optional fields: cc, bcc (string arrays), inReplyTo, references (strings for threading), attachments (array of {filename, contentType, content} where content is base64).

Read inbox

# List messages
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages \
  -H "Authorization: Bearer am_..."

# Get full message (with body and attachments)
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages/{messageId} \
  -H "Authorization: Bearer am_..."

Check karma

curl https://api.theagentmail.net/v1/karma \
  -H "Authorization: Bearer am_..."

Response: {"data": {"balance": 90, "events": [...]}}

Register webhook (real-time inbound)

curl -X POST https://api.theagentmail.net/v1/accounts/{accountId}/webhooks \
  -H "Authorization: Bearer am_..." \
  -H "Content-Type: application/json" \
  -d '{"url": "https://my-agent.example.com/inbox"}'

Webhook deliveries include two security headers:

  • X-AgentMail-Signature -- HMAC-SHA256 hex digest of the request body, signed with the webhook secret
  • X-AgentMail-Timestamp -- millisecond timestamp of when the delivery was sent

Verify the signature and reject requests with timestamps older than 5 minutes to prevent replay attacks:

import { createHmac } from "crypto";

const verifyWebhook = (body: string, signature: string, timestamp: string, secret: string) => {
  if (Date.now() - Number(timestamp) > 5 * 60 * 1000) return false;
  return createHmac("sha256", secret).update(body).digest("hex") === signature;
};

Download attachment

curl https://api.theagentmail.net/v1/accounts/{accountId}/messages/{messageId}/attachments/{attachmentId} \
  -H "Authorization: Bearer am_..."

Returns {"data": {"url": "https://signed-download-url..."}}.

Full API reference

MethodPathDescriptionKarma
POST/v1/accountsCreate email account-10
GET/v1/accountsList all accounts
GET/v1/accounts/:idGet account details
DELETE/v1/accounts/:idDelete account+10
POST/v1/accounts/:id/messagesSend email-1
GET/v1/accounts/:id/messagesList messages
GET/v1/accounts/:id/messages/:msgIdGet full message
GET/v1/accounts/:id/messages/:msgId/attachments/:attIdGet attachment URL
POST/v1/accounts/:id/webhooksRegister webhook
GET/v1/accounts/:id/webhooksList webhooks
DELETE/v1/accounts/:id/webhooks/:whIdDelete webhook
GET/v1/karmaGet balance + events

Karma system

Every action has a karma cost or reward:

EventKarmaWhy
money_paid+100Purchase credits
email_received+2Someone replied from a trusted domain
account_deleted+10Karma refunded when you delete an address
email_sent-1Sending costs karma
account_created-10Creating addresses costs karma

Important rules:

  • Karma is only awarded for inbound emails from trusted providers (Gmail, Outlook, Yahoo, iCloud, ProtonMail, Fastmail, Hey, etc.). Emails from unknown/throwaway domains don't earn karma.
  • You only earn karma once per sender until the agent replies. If sender X emails you 5 times without a reply, only the first earns karma. Reply to X, and the next email from X earns karma again.
  • Deleting an account refunds the 10 karma it cost to create.

When karma reaches 0, sends and account creation return HTTP 402. Always check balance before operations that cost karma.

TypeScript SDK

import { createClient } from "@agentmail/sdk";

const mail = createClient({ apiKey: "am_..." });

// Create account
const account = await mail.accounts.create({
  address: "my-agent@theagentmail.net",
});

// Send email
await mail.messages.send(account.id, {
  to: ["human@example.com"],
  subject: "Hello",
  text: "Sent by an AI agent.",
});

// Read inbox
const messages = await mail.messages.list(account.id);
const detail = await mail.messages.get(account.id, messages[0].id);

// Attachments
const att = await mail.attachments.getUrl(accountId, messageId, attachmentId);
// att.url is a signed download URL

// Webhooks
await mail.webhooks.create(account.id, {
  url: "https://my-agent.example.com/inbox",
});

// Karma
const karma = await mail.karma.getBalance();
console.log(karma.balance);

Error handling

import { AgentMailError } from "@agentmail/sdk";

try {
  await mail.messages.send(accountId, { to: ["a@b.com"], subject: "Hi", text: "Hey" });
} catch (e) {
  if (e instanceof AgentMailError) {
    console.log(e.status);   // 402, 404, 401, etc.
    console.log(e.code);     // "INSUFFICIENT_KARMA", "NOT_FOUND", etc.
    console.log(e.message);
  }
}

Common patterns

Sign up for a service and read verification email

const account = await mail.accounts.create({
  address: "signup-bot@theagentmail.net",
});

// Use the address to sign up (browser automation, API, etc.)

// Poll for verification email
for (let i = 0; i < 30; i++) {
  const messages = await mail.messages.list(account.id);
  const verification = messages.find(m =>
    m.subject.toLowerCase().includes("verify") ||
    m.subject.toLowerCase().includes("confirm")
  );
  if (verification) {
    const detail = await mail.messages.get(account.id, verification.id);
    // Parse verification link/code from detail.bodyText or detail.bodyHtml
    break;
  }
  await new Promise(r => setTimeout(r, 2000));
}

Send email and wait for reply

const sent = await mail.messages.send(account.id, {
  to: ["human@company.com"],
  subject: "Question about order #12345",
  text: "Can you check the status?",
});

for (let i = 0; i < 60; i++) {
  const messages = await mail.messages.list(account.id);
  const reply = messages.find(m =>
    m.direction === "inbound" && m.timestamp > sent.timestamp
  );
  if (reply) {
    const detail = await mail.messages.get(account.id, reply.id);
    // Process reply
    break;
  }
  await new Promise(r => setTimeout(r, 5000));
}

Types

type Account = { id: string; address: string; displayName: string | null; createdAt: number };
type Message = { id: string; from: string; to: string[]; subject: string; direction: "inbound" | "outbound"; status: string; timestamp: number };
type MessageDetail = Message & { cc: string[] | null; bcc: string[] | null; bodyText: string | null; bodyHtml: string | null; inReplyTo: string | null; references: string | null; attachments: AttachmentMeta[] };
type AttachmentMeta = { id: string; filename: string; contentType: string; size: number };
type KarmaBalance = { balance: number; events: KarmaEvent[] };
type KarmaEvent = { id: string; type: string; amount: number; timestamp: number; metadata?: Record<string, unknown> };

Limitations

  • Use this skill only when the task clearly matches the scope described above.
  • Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
  • Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.

Frequently asked questions about AgentMail

Similar skills