How to Give Your OpenClaw Agent Email with Dead Simple Email

OpenClaw is the open-source personal AI agent framework that took off in late 2025. With 247,000+ GitHub stars and a thriving ecosystem, it has become the default choice for developers who want to run an AI agent locally — one that can browse the web, write code, manage files, and interact with external services through the Model Context Protocol (MCP). But out of the box, OpenClaw can't do one of the most fundamental things in business communication: send and receive email.

That's where Dead Simple Email comes in. Dead Simple gives your agent a real email address backed by a REST API. No SMTP configuration, no OAuth flows, no Google Workspace seats. Just an API key and a few HTTP calls. In this guide, we'll build a complete integration that lets your OpenClaw agent create inboxes, send emails, read replies, and respond to incoming messages — all through a custom MCP server and an OpenClaw skill.

Why Your AI Agent Needs Email

AI agents are powerful at processing information and making decisions. But most agents live in a sandbox — they can reason, but they can't act in the outside world. Email is the universal connector. It's how businesses communicate with customers, how systems send notifications, how contracts get signed, and how support tickets get resolved. If your agent can't send or receive email, it's cut off from most real-world workflows.

Consider what becomes possible when your OpenClaw agent has email:

  • Customer support — receive support emails, draft context-aware replies, escalate when needed
  • Lead qualification — respond to inbound inquiries with personalized follow-ups
  • Report distribution — generate weekly summaries and email them to stakeholders
  • Workflow automation — trigger actions based on incoming emails (approvals, invoices, notifications)
  • Multi-agent coordination — agents can email each other to coordinate on complex tasks

Architecture Overview

Here's how the pieces fit together. OpenClaw communicates with external tools through MCP (Model Context Protocol) servers. We'll build a lightweight MCP server that wraps the Dead Simple Email REST API, then teach the agent how to use it with a skill file.

OpenClaw Agent
    |
    |  (MCP protocol)
    v
Dead Simple MCP Server  (Node.js, runs locally)
    |
    |  (HTTPS + Bearer token)
    v
Dead Simple Email API   (api.deadsimple.email)
    |
    |-- Creates/manages inboxes
    |-- Sends emails via KumoMTA
    |-- Receives emails via webhooks
    v
  Email  (recipient's mailbox)

The MCP server exposes four tools to OpenClaw: create_inbox, send_email, list_messages, and list_inboxes. When the agent decides it needs to send an email, it calls the appropriate tool. The MCP server translates that into a REST API call to Dead Simple, and the email goes out. Incoming emails hit a webhook, which can trigger the agent to read and respond.

Prerequisites

  • OpenClaw installed and running locally (v0.9+ recommended)
  • A Dead Simple Email accountsign up free (no credit card required)
  • An API key from your Dead Simple dashboard
  • Node.js 18+ for the MCP server

Step 1: Get Your Dead Simple API Key

If you don't have an account yet, head to app.deadsimple.email/signup and create one. The free tier gives you 5 inboxes and 5,000 emails per month — more than enough to build and test your integration.

Once you're in the dashboard, navigate to Settings → API Keys and click Create API Key. Give it a descriptive name like "openclaw-agent". Copy the key immediately — it starts with dse_ and you won't be able to see it again after closing the modal.

Set it as an environment variable so the MCP server can use it:

export DEADSIMPLE_API_KEY="dse_live_a1b2c3d4e5f6g7h8i9j0"

Add this to your shell profile (~/.bashrc, ~/.zshrc, or equivalent) so it persists across terminal sessions.

Step 2: Create a Dead Simple Email MCP Server

MCP (Model Context Protocol) is the standard that OpenClaw uses to communicate with external tools. An MCP server is a small program that exposes tools — functions with typed inputs and outputs — over a JSON-RPC transport. OpenClaw discovers these tools at startup and can call them during a conversation.

We'll build an MCP server in Node.js that exposes four Dead Simple Email operations as tools. Start by creating a new project:

mkdir deadsimple-mcp && cd deadsimple-mcp
npm init -y
npm install @modelcontextprotocol/sdk

Now create the server. This is the complete implementation — about 150 lines of code that give your agent full email capabilities:

index.js
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const API_BASE = "https://api.deadsimple.email/v1";
const API_KEY = process.env.DEADSIMPLE_API_KEY;

if (!API_KEY) {
  console.error("DEADSIMPLE_API_KEY environment variable is required");
  process.exit(1);
}

// Helper: make authenticated requests to the Dead Simple API
async function apiRequest(method, path, body = null) {
  const options = {
    method,
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
  };
  if (body) options.body = JSON.stringify(body);

  const res = await fetch(`${API_BASE}${path}`, options);
  const data = await res.json();

  if (!res.ok) {
    throw new Error(`API error ${res.status}: ${JSON.stringify(data)}`);
  }
  return data;
}

// Create the MCP server
const server = new McpServer({
  name: "deadsimple-email",
  version: "1.0.0",
});

// Tool: create_inbox
server.tool(
  "create_inbox",
  "Create a new email inbox. Returns the inbox ID and email address.",
  {
    name: { type: "string", description: "Display name for the inbox (e.g. 'support', 'billing')" },
  },
  async ({ name }) => {
    const inbox = await apiRequest("POST", "/inboxes", { name });
    return {
      content: [{ type: "text", text: JSON.stringify(inbox, null, 2) }],
    };
  }
);

// Tool: list_inboxes
server.tool(
  "list_inboxes",
  "List all email inboxes on the account.",
  {},
  async () => {
    const inboxes = await apiRequest("GET", "/inboxes");
    return {
      content: [{ type: "text", text: JSON.stringify(inboxes, null, 2) }],
    };
  }
);

// Tool: send_email
server.tool(
  "send_email",
  "Send an email from a specific inbox.",
  {
    inbox_id: { type: "string", description: "The inbox ID to send from (e.g. 'inb_abc123')" },
    to: { type: "string", description: "Recipient email address" },
    subject: { type: "string", description: "Email subject line" },
    body: { type: "string", description: "Plain text email body" },
  },
  async ({ inbox_id, to, subject, body }) => {
    const message = await apiRequest("POST", `/inboxes/${inbox_id}/messages`, {
      to, subject, body,
    });
    return {
      content: [{ type: "text", text: JSON.stringify(message, null, 2) }],
    };
  }
);

// Tool: list_messages
server.tool(
  "list_messages",
  "List messages in an inbox. Returns the most recent messages.",
  {
    inbox_id: { type: "string", description: "The inbox ID to list messages from" },
    limit: { type: "number", description: "Max messages to return (default 20)" },
  },
  async ({ inbox_id, limit = 20 }) => {
    const messages = await apiRequest("GET", `/inboxes/${inbox_id}/messages?limit=${limit}`);
    return {
      content: [{ type: "text", text: JSON.stringify(messages, null, 2) }],
    };
  }
);

// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);

Make sure your package.json includes "type": "module" for ES module support. You can test that the server starts correctly by running:

node index.js

It should start without errors and wait for MCP messages on stdin. Press Ctrl+C to stop it — OpenClaw will manage the process lifecycle from here.

Let's walk through the key design decisions in this server:

  • Bearer token auth — every request includes the API key in the Authorization header. No OAuth, no token refresh, no expiration to worry about.
  • JSON responses — the server returns raw JSON from the Dead Simple API. OpenClaw's LLM can parse and reason about JSON natively, so there's no need to transform it.
  • Error propagation — if the API returns an error (invalid inbox ID, rate limit exceeded, etc.), the error message gets passed back to the agent so it can decide what to do.
  • Stdio transport — OpenClaw launches the MCP server as a child process and communicates over stdin/stdout. No ports to configure, no networking to debug.

Step 3: Configure OpenClaw to Use the MCP Server

OpenClaw discovers MCP servers through its configuration file. Open your openclaw.json (typically at ~/.openclaw/openclaw.json or in your project root) and add the Dead Simple MCP server:

openclaw.json
{
  "mcpServers": {
    "deadsimple-email": {
      "command": "node",
      "args": ["/absolute/path/to/deadsimple-mcp/index.js"],
      "env": {
        "DEADSIMPLE_API_KEY": "dse_live_a1b2c3d4e5f6g7h8i9j0"
      }
    }
  }
}

A few things to note:

  • Use the absolute path to index.js. Relative paths resolve from OpenClaw's working directory, which may not be what you expect.
  • The env block passes your API key to the MCP server process. If you've already exported DEADSIMPLE_API_KEY in your shell, OpenClaw will inherit it and you can omit the env block entirely.
  • If you have other MCP servers configured, just add "deadsimple-email" alongside them. OpenClaw can run multiple MCP servers simultaneously.

Restart OpenClaw after changing the config. On startup, you should see a log line confirming the MCP server connected:

MCP server "deadsimple-email" connected (4 tools available)

Step 4: Create a Dead Simple Email Skill

OpenClaw skills are markdown files that teach the agent how to use a set of tools effectively. A skill includes metadata (in YAML frontmatter) and natural-language instructions that guide the agent's behavior. Think of it as a system prompt scoped to a specific capability.

Create a skill file in your OpenClaw skills directory:

skills/deadsimple-email/SKILL.md
---
name: Dead Simple Email
description: Send and receive email through Dead Simple Email API
version: 1.0.0
tools:
  - create_inbox
  - send_email
  - list_messages
  - list_inboxes
---

# Dead Simple Email

You have access to email through the Dead Simple Email API.

## Available Tools

- `create_inbox` — Create a new email inbox with a
  display name. Returns an inbox ID and email address.
- `list_inboxes` — List all inboxes on the account.
- `send_email` — Send an email from a specific inbox.
  Requires inbox_id, to, subject, and body.
- `list_messages` — List messages in an inbox. Use
  this to check for new replies or incoming messages.

## Workflow

1. Before sending email, check if an appropriate inbox
   exists using `list_inboxes`.
2. If no inbox exists, create one with `create_inbox`.
3. When sending email, always confirm the recipient
   address and subject with the user first.
4. After sending, report the message ID and status.
5. When asked to check for replies, use `list_messages`
   and summarize what came in.

## Rules

- Never send email without explicit user approval.
- Always use a professional, clear tone in emails.
- If the user asks to reply to a message, reference
  the original subject with "Re: " prefix.
- Keep email bodies concise unless instructed otherwise.

The skill file does two critical things. First, it tells OpenClaw which tools are relevant to this capability, so the agent knows to reach for send_email when you say "email that to Sarah." Second, it provides behavioral guardrails — the agent will confirm before sending, use professional language, and handle threading correctly.

Step 5: Test It — Send Your First Email

Time to take it for a spin. Start OpenClaw and have a conversation. Here's what a real interaction looks like:

OpenClaw conversation
You: Create an email inbox called "assistant"

OpenClaw: I'll create a new inbox called "assistant".

[Calling tool: create_inbox with name="assistant"]

Done. Here are the details:

  Inbox ID:    inb_r7k2m9x4p1
  Email:       assistant@yourco.deadsimple.email
  Status:      active
  Created:     2026-03-26T14:32:07Z

The inbox is live and ready to send and receive email.

You: Send an email to test@example.com with subject
     "Hello from OpenClaw" — just a quick intro message.

OpenClaw: I'll send this email from the assistant inbox:

  To:      test@example.com
  Subject: Hello from OpenClaw
  Body:    Hi — this is a quick note to let you know
           this inbox is live and managed by an AI
           assistant. Feel free to reply to this
           address any time.

Shall I send it?

You: Yes, send it.

OpenClaw: [Calling tool: send_email]

Sent. Message ID: msg_t3v8n2w5j6, status: delivered.

You: Check if there are any replies yet.

OpenClaw: [Calling tool: list_messages with inbox_id="inb_r7k2m9x4p1"]

One message in the inbox — the email you just sent.
No replies yet. I'll check again whenever you'd like.

Notice how the agent confirms the email content before sending, follows the skill instructions to use a professional tone, and gives you the message ID for tracking. This is the skill file doing its job.

Here's what the actual API response looks like when the MCP server calls Dead Simple to create that inbox:

POST /v1/inboxes response
{
  "id": "inb_r7k2m9x4p1",
  "name": "assistant",
  "email": "assistant@yourco.deadsimple.email",
  "status": "active",
  "created_at": "2026-03-26T14:32:07Z"
}

And the response when sending a message:

POST /v1/inboxes/inb_r7k2m9x4p1/messages response
{
  "id": "msg_t3v8n2w5j6",
  "inbox_id": "inb_r7k2m9x4p1",
  "from": "assistant@yourco.deadsimple.email",
  "to": "test@example.com",
  "subject": "Hello from OpenClaw",
  "body_text": "Hi — this is a quick note to let you know this inbox is live and managed by an AI assistant. Feel free to reply to this address any time.",
  "status": "delivered",
  "created_at": "2026-03-26T14:33:12Z"
}

Step 6: Build an Email-Powered Workflow

Sending one-off emails is useful, but the real power comes from automated workflows. Let's build something more ambitious: an OpenClaw agent that monitors an inbox, reads incoming emails, and sends intelligent replies — all without human intervention.

The workflow has three parts: a webhook to receive incoming emails, a processing function that calls OpenClaw, and a reply sent back through Dead Simple.

Set Up a Webhook

First, register a webhook so Dead Simple pushes incoming emails to your server in real time. You can do this through the API or the dashboard. Here's the API call:

Register a webhook
curl -X POST https://api.deadsimple.email/v1/webhooks \
  -H "Authorization: Bearer dse_live_a1b2c3d4e5f6g7h8i9j0" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhook/email",
    "events": ["message.received"],
    "inbox_id": "inb_r7k2m9x4p1"
  }'

Dead Simple will respond with a webhook object including a secret field. Save this — you'll use it to verify that incoming webhook payloads are authentic via HMAC-SHA256 signature.

Build the Auto-Reply Handler

Now build a small server that receives the webhook, passes the email content to OpenClaw for processing, and sends the reply back through Dead Simple. Here's a complete implementation in Node.js:

auto-reply-server.js
import http from "node:http";
import crypto from "node:crypto";

const API_BASE = "https://api.deadsimple.email/v1";
const API_KEY = process.env.DEADSIMPLE_API_KEY;
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

function verifySignature(payload, signature) {
  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

async function generateReply(emailBody) {
  // Call your LLM here — OpenAI, Anthropic, local model, etc.
  // This is a placeholder that returns a simple response.
  return `Thank you for your message. I've received it and will follow up shortly.\n\nOriginal message:\n> ${emailBody}`;
}

async function sendReply(inboxId, to, subject, body) {
  const res = await fetch(`${API_BASE}/inboxes/${inboxId}/messages`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ to, subject, body }),
  });
  return res.json();
}

const server = http.createServer(async (req, res) => {
  if (req.method !== "POST" || req.url !== "/webhook/email") {
    res.writeHead(404);
    return res.end();
  }

  const chunks = [];
  for await (const chunk of req) chunks.push(chunk);
  const rawBody = Buffer.concat(chunks);

  // Verify HMAC signature
  const signature = req.headers["x-deadsimple-signature"];
  if (!verifySignature(rawBody, signature)) {
    res.writeHead(401);
    return res.end("Invalid signature");
  }

  const event = JSON.parse(rawBody);
  const msg = event.data;

  console.log(`Received email from ${msg.from}: ${msg.subject}`);

  // Generate and send a reply
  const replyBody = await generateReply(msg.body_text);
  await sendReply(
    msg.inbox_id,
    msg.from,
    `Re: ${msg.subject}`,
    replyBody
  );

  res.writeHead(200);
  res.end(JSON.stringify({ status: "ok" }));
});

server.listen(3001, () => {
  console.log("Webhook handler running on port 3001");
});

This is a minimal example. In production, you'd replace the generateReply function with a call to your LLM of choice, add a queue for reliability, and store conversation history so the agent has context across multiple exchanges. But the structure stays the same: receive webhook, process content, send reply.

Create an Email Monitoring Skill

For more advanced workflows, you can create a dedicated skill that combines email monitoring with autonomous decision-making. Here's an example skill that tells the agent to periodically check for new emails and handle them based on content:

skills/email-monitor/SKILL.md
---
name: Email Monitor
description: Monitor inbox and auto-respond to emails
version: 1.0.0
tools:
  - list_messages
  - send_email
  - list_inboxes
---

# Email Monitor

You are an email monitoring assistant. Your job is to
check the inbox for new messages and handle them.

## Behavior

When asked to monitor email:
1. Call `list_inboxes` to find the target inbox.
2. Call `list_messages` to get recent messages.
3. For each unread message, analyze the content and:
   - If it's a question: draft a helpful reply.
   - If it's a request: summarize it for the user.
   - If it's spam or irrelevant: flag it and skip.
4. Send approved replies using `send_email`.

## Reply Guidelines

- Keep replies under 200 words unless the question
  requires a detailed answer.
- Always acknowledge what the sender asked.
- If you're unsure about something, say so — don't
  make up information.
- Sign off as "AI Assistant" unless told otherwise.

Now you can tell OpenClaw "check my email and handle anything straightforward" and it will read through recent messages, draft responses, and ask for your approval before sending. The skill provides the judgment framework while the MCP tools provide the capability.

Dead Simple API Reference

Here's a quick reference for the endpoints used in this guide. All endpoints require a Bearer token in the Authorization header.

Method Endpoint Description
POST /v1/inboxes Create a new inbox
GET /v1/inboxes List all inboxes
POST /v1/inboxes/{id}/messages Send an email
GET /v1/inboxes/{id}/messages List messages in an inbox
POST /v1/webhooks Create a webhook

Create an Inbox

Request
POST /v1/inboxes
Authorization: Bearer dse_live_...
Content-Type: application/json

{
  "name": "assistant"
}
Response (201 Created)
{
  "id": "inb_abc123def456",
  "name": "assistant",
  "email": "assistant@yourco.deadsimple.email",
  "status": "active",
  "created_at": "2026-03-26T14:00:00Z"
}

Send an Email

Request
POST /v1/inboxes/inb_abc123def456/messages
Authorization: Bearer dse_live_...
Content-Type: application/json

{
  "to": "recipient@example.com",
  "subject": "Hello from my AI agent",
  "body": "This email was sent by an OpenClaw agent using the Dead Simple Email API."
}
Response (201 Created)
{
  "id": "msg_p4q7r2s9t1",
  "inbox_id": "inb_abc123def456",
  "from": "assistant@yourco.deadsimple.email",
  "to": "recipient@example.com",
  "subject": "Hello from my AI agent",
  "body_text": "This email was sent by an OpenClaw agent using the Dead Simple Email API.",
  "status": "delivered",
  "created_at": "2026-03-26T14:05:00Z"
}

Why Dead Simple Over Gmail or Outlook for Agents

You might be wondering why you'd use Dead Simple instead of connecting OpenClaw to Gmail or Outlook. Here's the honest comparison:

Authentication. Gmail and Outlook require OAuth 2.0 — a multi-step flow involving redirect URIs, consent screens, token refresh, and scope management. Dead Simple uses a single API key. Set it once, and it works forever. No tokens to refresh, no sessions to manage, no re-authentication flows to handle in your agent.

Sandboxing. When you give an agent access to your Gmail, it can see your calendar, your Drive files, your contacts — everything in the Google Workspace. Dead Simple is email only. There's no attack surface beyond the inbox you created. If the agent misbehaves, the blast radius is contained to a sandboxed address, not your entire work account.

Cost. Five Google Workspace seats cost $42/month at the Business Starter tier. Five Dead Simple inboxes cost $0/month on the free plan. Even the Pro plan at $29/month gives you 50 inboxes and 50,000 emails. For agent use cases where you need many disposable inboxes, the economics aren't close.

Account safety. Google and Microsoft actively suspend accounts that show automated sending patterns. Their terms of service prohibit bot-driven email activity on consumer accounts. Dead Simple is purpose-built for programmatic use. There's no risk of your agent getting its email address banned because it sent 100 messages in an hour.

Webhooks. Gmail's push notifications require Pub/Sub setup on Google Cloud. Outlook uses Microsoft Graph subscriptions with complex renewal logic. Dead Simple gives you HMAC-signed webhooks on every plan, including free. Register a URL, and incoming emails hit your server in real time.

What's Next

You now have an OpenClaw agent with full email capabilities. Here are some next steps to take it further:

  • Explore the full API docs — attachments, HTML emails, threading, batch sends, and more are covered in the API documentation.
  • Try the Python SDK — if you prefer Python over raw HTTP calls, the Dead Simple Python SDK wraps every endpoint with type hints and automatic retries.
  • Watch for the native OpenClaw skill — we're working on publishing an official Dead Simple Email skill to skills.sh so you can install it with a single command instead of building the MCP server yourself.
  • Set up a custom domain — send from agent@yourcompany.com instead of the shared deadsimple.email domain for a more professional presence.
  • Read more on the blog — check out Why AI Agents Need Their Own Email, Webhooks for AI Email, and Getting Started with Dead Simple Email for more integration ideas.

Questions or feedback? Reach out at hello@deadsimple.email or join the Discord community. We read every message.

Ready to build?

Create a free account and give your OpenClaw agent email superpowers in minutes.

Create Free Account

5 inboxes · 5,000 emails/mo · Free forever