Skip to content

StartEmail for AI agents

Give an AI agent its own email inbox

Shipmail is a business email provider with a REST API and an MCP server for AI agents. Your agent gets a real mailbox on your domain, like agent@yourdomain.com. It can send mail, read what comes in, reply in threads and react to webhooks. You and your team open the same mailbox in Shipmail or any mail client. You can read what the agent sent, send a draft it left, or answer a conversation yourself. Start with the starter kit, connect the MCP server, or call the API from your own code.

Still choosing an approach? Read the email API for AI agents guide for the REST API, webhook and MCP tradeoffs. If the agent will call email tools itself, go to the Shipmail email MCP server quick start. To send your first message from your own code, go to the API quick start.

Last updated

Starter kit

The starter is a Bun and TypeScript app. It receives signed Shipmail webhooks, triages allowed inbound mail with Claude, and writes reply drafts that fail if the conversation moved on. Six recipes reuse the same core for scheduling, follow-ups, meeting briefs, a morning digest, sign-up codes and lead capture. Sending stays off until you turn it on. Get the code from shipmail-to/agent-inbox-starter. Browse the email agent workflow gallery for eight ways to adapt it.

  • A Bun webhook server that verifies Shipmail signatures, deduplicates deliveries, and runs a handler per event type on a bounded queue.
  • Sender authentication. A message must pass DMARC before the model sees it, so a forged allowlisted address does not get through.
  • Shipmail's prompt-injection scan. A flagged or unscanned message goes to a person and never reaches the model.
  • A Claude triage agent. It reads reply_text, sorts mail into needs_reply, ignore or escalate, and drafts a reply against the current conversation version.
  • Recipes for a meeting scheduler, follow-up drafts on reply.overdue, meeting briefs on calendar.event_starting, a morning digest, agent sign-up codes, and a lead qualifier.
  • Examples for the Claude Agent SDK, the OpenAI Agents SDK, the Vercel AI SDK, LangGraph, and an MCP client.

Clone and run

  1. Clone the starter repository and open its directory.
  2. Copy .env.example to .env.local, then add your scoped Shipmail key, mailbox ID, Anthropic key, and allowed senders.
  3. Install dependencies and start the local webhook server.
  4. Expose port 3000 with cloudflared or ngrok, then run bun run webhook:create with that public /webhook URL. It scopes the webhook to the mailbox, copies the sender allowlist to Shipmail, and prints the signing secret for SHIPMAIL_WEBHOOK_SECRET.
cp .env.example .env.local
bun install --ignore-scripts
bun run dev
bun run webhook:create -- --url https://your-tunnel.example/webhook

Test without sending real mail

Sandbox inbound injection exercises the real mailbox and webhook path without sending mail over SMTP. Add sandbox-sender@example.com to SHIPMAIL_ALLOWED_SENDERS, or set SANDBOX_FROM to another allowed address, before running it.

bun run sandbox:e2e

Security model

Anyone can put any address in a From header, so an allowlist alone checks a value the sender chose. Shipmail returns SPF, DKIM and DMARC verdicts on every inbox message, and the starter calls the model only after a DMARC pass. DMARC is the check that matters, because it ties the visible From address to a domain that authorized the mail. SPF alone only covers the envelope sender, which the recipient never sees. Mail that fails goes to a person. It never reaches the model and never gets a draft. Shipmail's prompt-injection scan, signature verification, payload validation, mailbox pinning and draft-only defaults still apply on top.

  • Read authentication_results and security on any inbox message to apply the same checks in your own agent, whichever language you build in.
  • Set allowed_senders and authenticated_senders_only on the webhook so Shipmail drops other mail before it reaches your server.
  • Keep exact sender entries where possible. Use explicit *@domain entries only when every address at that domain should be accepted.
  • Allowlist only public HTTPS URL hosts the model needs. Every other URL is redacted before model input.
  • Keep AUTO_SEND=false until you have reviewed the policy, drafts, sender list and logs. Sender authentication turns on by itself with AUTO_SEND, because from then on a forged sender could get a reply nobody checked.
  • Send sensitive, legal, financial, security, credential and account-access messages to a person for review.

Deploy

The servers are long-lived processes. The webhook answers at once and finishes the work on a background queue, and a serverless function has nowhere to keep that queue.

  • On Railway, Fly, Render or a Docker host, run bun install --ignore-scripts, then bun run start or a recipe's script. Use the platform's PORT and point the health check at /health.
  • Set REDIS_URL before running more than one instance, so deduplication and the reply cap are shared.
  • Run the morning digest from cron or a scheduled job. It is a script, not a server.

Guides for your agent

  • Codex: Add the MCP server to the Codex CLI and IDE extension.
  • Hermes Agent: Add the MCP server to Nous Research's Hermes Agent.
  • OpenClaw: Add the MCP server to OpenClaw with one command.
  • LangChain: Load Shipmail tools into a LangChain or LangGraph agent.
  • Browser Use: Read sign-up codes and links from a mailbox on your domain.
  • Receive email in an AI agent: Duplicate webhooks, threading, spoofed senders and memory.

Connect without the starter kit

1. Create a Shipmail API key

  1. Sign up at shipmail.to and add your domain.
  2. Go to Developer, then API keys, and create a key. It looks like sm_live_...
  3. Give the key only the scopes it needs: messages:read to read mail, drafts:write for reply drafts, drafts:compose to save new emails to Drafts for review, and messages:send only if the agent may deliver mail.

2. Pick how the agent connects

  1. Hosted MCP server, the fastest path for chat agents. Point ChatGPT, Claude Code, Cursor or VS Code at https://shipmail.to/api/mcp with the API key as a bearer token. There is nothing to install.
  2. Local MCP server. Run npx -y shipmail-mcp over stdio for hosts like Claude Desktop.
  3. REST API, CLI or SDK, for agents and apps you build yourself in TypeScript or Python.
  4. All three use the same API key and the same account, so you can mix them.

3. Give the agent an inbox

  1. Create a mailbox on your domain, like agent@yourdomain.com.
  2. The agent can now send mail, read its inbox and reply, through the API or the MCP tools.
  3. Add a webhook to tell the agent as soon as new mail arrives.

Examples

Connect the hosted MCP server (ChatGPT, Claude Code, Cursor, VS Code)

{
  "mcpServers": {
    "shipmail": {
      "url": "https://shipmail.to/api/mcp",
      "headers": { "Authorization": "Bearer sm_live_..." }
    }
  }
}

Or run the MCP server locally (Claude Desktop)

{
  "mcpServers": {
    "shipmail": {
      "command": "npx",
      "args": ["-y", "shipmail-mcp"],
      "env": { "SHIPMAIL_API_KEY": "sm_live_..." }
    }
  }
}

Create a mailbox for the agent (TypeScript SDK)

import { ShipmailClient } from "shipmail";

const client = new ShipmailClient("sm_live_...");

// Look up the domain id from client.domains.list() or the dashboard.
await client.mailboxes.create({
  domain_id: "d290f1ee-6c54-4b01-90e6-d701748f0851",
  address: "agent",
  password: process.env.AGENT_MAILBOX_PASSWORD,
});

Send mail from the agent (cURL)

curl -X POST https://shipmail.to/api/v1/messages \
  -H "Authorization: Bearer sm_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": "agent@yourdomain.com",
    "to": ["customer@example.com"],
    "subject": "Following up",
    "text": "Thanks for reaching out. Here is what you asked for."
  }'

Get notified when mail arrives (webhook)

await client.webhooks.create({
  url: "https://your-agent.example.com/inbound",
  events: ["message.received"],
});

Scan a year and create a stale-safe reply draft (TypeScript)

const scan = await client.replyScans.create({
  mailbox_ids: ["f47ac10b-58cc-4372-a567-0e02b2c3d479"],
  after: new Date(Date.now() - 365 * 86400000).toISOString(),
});

// Poll client.replyScans.get(scan.id) with bounded backoff until completed.
const page = await client.replyScans.listResults(scan.id, { limit: 50 });
const candidate = page.data[0];
if (candidate) {
  // Store candidate.conversation_id. thread_id is deprecated and can be re-threaded.
  const thread = await client.mailboxes.getInboxThread(
    candidate.mailbox_id,
    candidate.conversation_id,
  );
  const text = await yourModelDraftFunction(thread.data);
  const draft = await client.mailboxes.createInboxReplyDraft(
    candidate.mailbox_id,
    candidate.conversation_id,
    { text, expected_version: candidate.version },
  );

  // Apply your approval policy before this call.
  await client.mailboxes.sendInboxReplyDraft(
    candidate.mailbox_id,
    candidate.conversation_id,
    draft.id,
  );
}

Key concepts

MCP vs the API

The MCP server turns the Shipmail API into agent tools, so an MCP client can manage email with no code. The REST API, CLI and SDKs are for software you build yourself. Both use the same account and the same key.

What the agent can do

Create and manage domains and mailboxes, send mail, read an inbox, reply in a thread, manage webhooks and handle suppressions. Each of these is a tool the agent can call.

Guardrails

Grant messages:read, drafts:write, drafts:compose and messages:send separately. Shipmail sets the recipients of a reply draft itself, and a draft for a conversation that has moved on fails with 409. New emails saved with drafts:compose wait in Drafts until a person sends them. The MCP server also caps risky actions per session.

Inbound mail

Use message.received for every inbound email, the attention queue for live work, and reply scans for a frozen historical window.

When Shipmail fits

Use Shipmail when your agent needs a real business mailbox on your own domain that a person can also open and check. You get a normal inbox with a REST API, webhooks and MCP tools on top. If you only need a throwaway inbox for high-volume sending with no person involved, an agent-only inbox product may suit you better.

Use these to compare an agent-owned Shipmail mailbox with MCP servers that work inside an existing account, and with APIs that connect many providers.

  • Shipmail AI agent inbox starter kit

    A Bun and TypeScript webhook server you can run, with sender checks, Shipmail's injection scan, Claude triage, stale-safe drafts, six recipes, sandbox injection and agent framework examples.

  • Model Context Protocol introduction

    Official MCP documentation for the standard that lets AI applications connect to external tools, data, and workflows.

  • Shipmail MCP source repository

    Public source for the official Shipmail MCP server, including package metadata, tool coverage, resources, prompts, and security notes.

  • Official MCP Registry entry

    Machine-readable registry listing for the Shipmail MCP server and its npm package.

  • Google Gmail MCP server

    Google's official Gmail MCP server, in Developer Preview, for agents that read and draft inside existing Gmail accounts. It cannot send.

  • Microsoft Work IQ MCP

    Microsoft's MCP endpoint, in preview, for agents that work on mail and other Microsoft 365 tenant data.

  • Nylas MCP server docs

    Nylas documentation for MCP tools across connected email, calendar, contacts, and Notetaker data.

  • Atomic Mail

    An agent-owned inbox product built around MCP, JMAP, and REST for autonomous agent workflows.

  • AgentMail inbox API

    An inbox API for agents that creates inboxes on demand, on agentmail.to or on a custom domain on paid plans.

Frequently asked questions

Is Shipmail a business email provider with a REST API and MCP server?

Yes. Shipmail is business email on your own domain, with a REST API, TypeScript and Python SDKs, webhooks and an official MCP server. Agents can use the MCP server from any compatible client or call the REST API.

Do I need to be a developer to use this?

Not for MCP. In Claude Desktop, Cursor or another MCP client, you paste a short config with your API key and the agent can manage email at once. The API and SDKs are for when you build your own app.

Which AI agents can connect?

Any MCP client, such as Claude Desktop, Cursor or Windsurf, can use the Shipmail MCP server. Any agent or app that can make HTTP requests can use the REST API.

Can the agent both send and receive email?

Yes. A mailbox is a real inbox on your domain. The agent can send mail, read what comes in and reply in the same thread, through the API or the MCP tools.

How do I stop an agent from sending too much mail?

Give the API key only the scopes it needs. The MCP server also caps sends, replies and deletes per session, and your plan's daily sending limits still apply, so a runaway agent cannot go past them.

Is this different from a transactional email API?

Yes. A transactional API only sends. Shipmail gives the agent a full mailbox of its own, so it can also receive, read and reply to real conversations.

Is Shipmail trying to replace agent-only inbox infrastructure?

No. Shipmail fits when the agent's inbox should be a normal business mailbox on your domain that people can open in the app, with IMAP and SMTP, REST, webhooks and MCP. If you need a throwaway inbox for high-volume sending with no person watching, an agent-only inbox product may fit better.