Skip to content

Email infrastructure for AI agents

Give your agent its own email.

Your agent gets a real @cherami.to address, and people write to it from their usual mail app. We receive, thread and store the mail and send what your agent writes back. Build it into your code with the HTTP API, SDKs and webhooks, or connect your agent over MCP.

Get an API keyConnect an agent
  1. import { Cherami } from "@cherami/sdk";
    
    const cherami = new Cherami({
      apiKey: process.env.CHERAMI_API_KEY!,
    });
    
    const { data: inbox } =
      await cherami.createInbox({
        body: { local_part: "hello" },
      });
    hello@cherami.to
  2. dana@example.com → hello@cherami.toIllustrative

    Quote 2207: 400 shipping boxes

    Quote attached, valid for 30 days. Lead time is three weeks from artwork approval. Where should we deliver?

    ▤ quote-2207.pdf

From new mail
to a sent reply.

Here’s Dana’s quote answered from start to finish. Each step shows what your code does and the MCP tool a connected agent calls for it.

  1. No. 3 Hear about it

    A signed webhook tells your code

    When mail reaches hello@cherami.to, we POST a signed event carrying its inbox and message IDs, and your code fetches the rest with its key. One webhook can cover every inbox on your account or just the ones you name.

    Over MCP Your agent calls list_messages each time it runs, so run it on a schedule to pick up new mail.

    POST https://api.example.com/hooks/cherami
    webhook-signature: v1,…
    
    {
      "id": "0b6e…",
      "type": "message.received",
      "timestamp": "2026-10-07T09:14:02.511Z",
      "data": {
        "inbox_id": "4c1d…",
        "message_id": "9a27…"
      }
    }
  2. No. 4 Read and answer

    Your worker reads it and replies

    The message comes back parsed: sender, recipients, subject, text and HTML, the new reply apart from the quoted history, and a list of its attachments.

    Reply with its ID, and we work out who it goes to, the subject and the threading.

    Over MCP Your agent calls get_message, then reply_message, and writes the reply itself.

    // In your worker,
    // for each message.received event:
    const { data: mail } =
      await cherami.getMessage({
        message_id: event.data.message_id,
      });
    
    // Your model, your rules, your words.
    const text = await draftReply(mail);
    
    const { data: receipt } =
      await cherami.replyMessage({
        inbox_id: event.data.inbox_id,
        body: {
          message_id: event.data.message_id,
          text,
        },
      });
  3. No. 5 Send it

    The reply goes out in Dana’s thread

    It leaves from hello@cherami.to under the sender name you set, with the one-line “Sent via Cherami” footer every message carries.

    The receipt tells your code the outcome, and a message.sent event follows once the message is accepted for delivery. Accepted isn’t proof it reached Dana’s inbox.

    Over MCP Your agent reads the outcome in the reply_message result.

    hello@cherami.to → dana@example.comIllustrative

    Re: Quote 2207: 400 shipping boxes

    Thanks, Dana. Please deliver to 14 Harbour Street, goods entrance, weekdays 8 to 4. I’ve passed the quote to Sam for sign-off and will confirm the order by Friday.Sent via Cherami

    receipt.message.status   "accepted"
    webhook event            message.sent

No public endpoint? In place of No. 3, list the inbox on a schedule. Poll for new mail ↗

Two ways in, one account.

Wire Cherami into your own code, or connect an agent that works the inbox itself. Both reach the same inboxes, the same mail and one allowance, so start with either and add the other later.

In your code

Run the inbox from your code

Create inboxes and read and send mail through the HTTP API or the TypeScript and Python SDKs, and hear about new messages by webhook. Get an API key in Account and make your first call from your backend.

# TypeScript · Node 24+, server-side
bun add @cherami/sdk

# Python 3.11+
pip install cherami
  • A method for every mail operation in both SDKs
  • An OpenAPI 3.1 contract for any other language
  • Idempotency keys for safe retries of sends, drafts and new inboxes
Get an API key

In your agent

Connect the agent you already run

Add the server to Claude Code or another client that supports remote MCP, and your agent works the inbox with Cherami’s tools, under the instructions you give it. The Cherami plugin brings the same tools, and an agent without MCP can start from the setup prompt below.

https://cherami.to/mcp

An illustrative routine

Each morning, your agent calls list_messages on hello@cherami.to and get_message for anything new. It answers delivery and scheduling questions from your notes with reply_message. Anything that would commit money, it writes up with create_draft and sends with send_draft only once you approve. It files what it handled with update_message_labels.

  • No key to paste: you approve access in your browser
  • Tools to create inboxes, read threads and attachments, reply, draft and label mail
  • Clients that can’t approve in a browser, or that only run local servers, connect with an API key

No MCP? If your agent makes HTTP requests, paste this into its chat.

Set up a Cherami email inbox you can work from by following https://cherami.to/docs-markdown/quickstart. If Cherami tools are already connected, use them. Otherwise, ask me to approve your access as the guide describes. List my inboxes and check with me which one to use for this work. If none fits, agree the address with me before you create one. Then I'll send the inbox a test message. Read it, show me your reply, and send it once I approve.

Beyond
the first reply.

What your code or agent can do as the conversation goes on, through the API or MCP.

Threads

Every reply finds its conversation

Replies join their conversation on their own, within each inbox, so your code or agent reads the exchange as one thread.

HTTP
GET /v1/threads/{thread_id}
MCP
get_thread

Replies

Reply to all, or pass it on

Reply-all answers everyone on the message and never reuses Bcc. A forward carries the original attachments into a new thread.

HTTP
POST /v1/inboxes/{inbox_id}/reply-all
POST /v1/inboxes/{inbox_id}/forward
MCP
reply_all_message
forward_message

Attachments

Files in, files out

Each attachment downloads as its original file, and any received message is also available as raw MIME. Mail can arrive at up to 25 MiB and go out at up to 5 MiB as sent, attachments included.

HTTP
GET /v1/messages/{message_id}/attachments/{attachment_id}
MCP
read_attachment

Drafts

Hold a reply for a person

Your agent saves a draft, revises it and sends it once a person approves.

HTTP
POST /v1/drafts/{draft_id}/send
MCP
send_draft

Rules

Boundaries you set per inbox

Let an inbox send only to the addresses and domains you list, and block senders by their From address. Your agents can read the rules; only you change them, in Account. A send outside the list is refused and costs nothing, and mail from a blocked sender doesn’t arrive.

HTTP
GET /v1/inboxes/{inbox_id}/sending-policy
MCP
get_sending_policy

Search and labels

Find it, file it

Search subjects and bodies, filtered by sender, recipient, date and label and ordered by date or relevance. Labels are your own tags, shared across the account: put them on a message, a batch of messages or a whole thread.

HTTP
GET /v1/inboxes/{inbox_id}/messages?query=…
PATCH /v1/messages/{message_id}
MCP
list_messages
update_message_labels

Several agents

One account, many agents

Give each agent or service its own key, and revoke one without stopping the rest. Every key and connection reaches every inbox on the account.

HTTP
GET /v1/inboxes
MCP
list_inboxes

Deletion

Clear out what you’re done with

Delete messages, threads, drafts and inboxes. Deleted messages can be restored from Trash for seven days, then they’re gone for good. Deleting a draft or an inbox is final.

HTTP
POST /v1/messages/{message_id}/restore
MCP
restore_message

Docs for agents

Docs your agent can read

Every docs page has a Markdown twin, and /llms.txt indexes them all, so your agent can read the guide before it acts.

Fetch
GET /llms.txt

Currently
free.

Every account starts with these, shared by every inbox, key and agent on it.

Two inboxes

Pick addresses you’ll keep. Deleting an inbox frees its slot and retires the address for everyone, you included.

25 recipients per rolling 24 hours

Each To, Cc and Bcc entry counts as one. When they run out, your agents can still receive, read, organize and draft.

Need more? Tell us what your inboxes are for and how much you expect to send. Email us, or have your code or agent ask with POST /v1/feedback or submit_feedback, and our replies go to your account email.

Will it fit
your agent?

What decides whether Cherami fits the work you have in mind.

Something else? hello@cherami.to

Good things
find their way.