AI Agents
AI coding agents (Claude Code, Cursor, Codex) need to send emails — for notifications, onboarding sequences, confirmations. Most email APIs weren't built with agents in mind. Here's what matters and how to set it up.
AI agents aren't just writing code anymore — they're building and running production systems. That means they need to send emails: onboarding sequences, password resets, order confirmations, system alerts. But most email APIs were designed for developers sitting at a terminal, not for autonomous agents executing tasks in a loop. The requirements are different in ways that matter.
When an AI agent builds and deploys a SaaS application, it's not just writing code — it's wiring up the whole product stack. That includes email. Users expect welcome emails when they sign up. They expect password reset links, receipts, weekly digests, and system alerts. If the agent can't configure email sending, it produces an incomplete product.
There are also meta-level use cases: agents reporting on their own work, sending status updates to human supervisors, or notifying a product team when a background job finishes. Email is the most reliable async communication channel — it works regardless of whether the recipient is using a specific app.
The agents most likely to need email today:
Agents have different constraints than human developers. Here's what actually matters:
Agents retry. Whether from a network timeout, a hallucination loop, or a tool call that didn't return a clear response — agents will sometimes call the same endpoint twice. Without idempotency, you get duplicate emails. A good email API lets you send an idempotency key with each request so the second call is a no-op, not a second send.
POST https://api.tinysend.co/v1/emails
X-Idempotency-Key: onboarding-{user_id}-welcome-v1
{
"to": "[email protected]",
"from": "[email protected]",
"subject": "Welcome to the app",
"html": "<p>Thanks for signing up!</p>"
} Agents don't always have the full npm ecosystem available. They may be running in sandboxed environments, Docker containers, or minimal serverless runtimes. An email API that requires a heavyweight SDK (with 15 transitive dependencies) is a problem. Prefer APIs you can call with a plain fetch() or curl.
When a human gets a vague error, they can Google it. When an agent gets a vague error, it may hallucinate a fix or get stuck in a retry loop. Email APIs should return structured JSON errors with clear codes — invalid_recipient, domain_not_verified, rate_limit_exceeded — not HTML error pages or generic 500s.
Agents read docs. When a coding agent is trying to integrate your email API, it'll pull your API reference into context. APIs with dense, well-structured documentation (with curl examples and full JSON schemas) are significantly easier for agents to work with than APIs that bury examples in prose or require navigating a GUI to find the API key.
Model Context Protocol (MCP) lets Claude, Cursor, and other agents call tools natively — without writing HTTP code at all. If an email provider publishes an MCP server, an agent can send email with a single tool call. This is the lowest-friction integration for agentic workflows.
There are three ways an AI agent can integrate email sending, in order of least to most friction:
The agent calls a send_email tool directly. No HTTP code, no API keys in prompts. The MCP server handles auth and formatting. Best for Claude Code, Cursor with MCP support.
The agent installs a package and uses a typed client. Still requires API key management, but the agent gets type-safety and doesn't need to know the HTTP details. Works in any Node.js, Python, or Ruby environment.
Plain fetch() or curl calls. Maximum portability — works in any language, any runtime, no dependencies. Slightly more boilerplate but easiest to audit.
With the tinysend MCP server installed, an agent can send email without writing any HTTP code:
<tool: send_email> to: [email protected] subject: Your report is ready html: <p>Your weekly analytics report is attached.</p> idempotency_key: weekly-report-{user_id}-2026-W13 </tool>
For an agent writing application code, a direct API call is the most robust approach. Zero dependencies, works in any runtime:
async function sendEmail({ to, subject, html, idempotencyKey }) {
const response = await fetch('https://api.tinysend.co/v1/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TINYSEND_API_KEY}`,
'Content-Type': 'application/json',
...(idempotencyKey ? { 'X-Idempotency-Key': idempotencyKey } : {}),
},
body: JSON.stringify({
from: process.env.EMAIL_FROM,
to,
subject,
html,
}),
})
if (!response.ok) {
const error = await response.json()
// Structured error — agent can parse and handle
throw new Error(`Email failed: ${error.code} — ${error.message}`)
}
return response.json()
}
// Usage
await sendEmail({
to: '[email protected]',
subject: 'Welcome to the app',
html: '<h1>You\'re in!</h1><p>Click below to get started.</p>',
idempotencyKey: `welcome-${userId}`,
})import os
import httpx
def send_email(to: str, subject: str, html: str, idempotency_key: str = None) -> dict:
headers = {
"Authorization": f"Bearer {os.environ['TINYSEND_API_KEY']}",
"Content-Type": "application/json",
}
if idempotency_key:
headers["X-Idempotency-Key"] = idempotency_key
response = httpx.post(
"https://api.tinysend.co/v1/emails",
headers=headers,
json={
"from": os.environ["EMAIL_FROM"],
"to": to,
"subject": subject,
"html": html,
}
)
response.raise_for_status()
return response.json()
# Agent calling it
send_email(
to="[email protected]",
subject="Your order shipped",
html="<p>Your order #1234 is on its way.</p>",
idempotency_key=f"order-shipped-1234",
)Agents can also trigger multi-step email sequences — not just one-off sends. Useful for onboarding drips where timing matters:
await fetch('https://api.tinysend.co/v1/sequences/{sequence_id}/enroll', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TINYSEND_API_KEY}`,
'Content-Type': 'application/json',
'X-Idempotency-Key': `onboard-${userId}`,
},
body: JSON.stringify({
email: '[email protected]',
variables: {
first_name: 'Alex',
product_url: 'https://app.example.com',
}
})
})Not all email APIs are equally agent-friendly. Here's how the major ones compare on the dimensions that matter for agentic use:
| Provider | MCP server | Idempotency | Structured errors | SDK quality | Sequences |
|---|---|---|---|---|---|
| tinysend | ✓ Native | ✓ Yes | ✓ Yes | ✓ Excellent | ✓ Built-in |
| Resend | Community | ✓ Yes | ✓ Yes | ✓ Good | ✗ No |
| SendGrid | ✗ No | ✗ No | Partial | Verbose | ✓ Yes |
| Postmark | ✗ No | ✗ No | ✓ Yes | ✓ Good | ✗ No |
| Mailgun | ✗ No | Partial | Partial | Dated | ✗ No |
| Amazon SES | ✗ No | ✓ Via SDK | AWS format | Complex | ✗ No |
The biggest gap for agentic use: most providers have no MCP server, no idempotency, and no built-in sequences. An agent has to implement retry deduplication itself and can't easily build drip campaigns without a separate tool.
See the full comparison: tinysend vs Resend · tinysend vs SendGrid · tinysend vs Postmark
tinysend was built with a few principles that happen to align well with agentic workflows:
The tinysend-mcp package gives Claude Code and Cursor direct tool access to send email, trigger sequences, and check delivery status — without the agent needing to write HTTP code or manage auth.
Pass X-Idempotency-Key with any send. tinysend deduplicates within a 24-hour window — so agent retries never cause duplicate emails in production.
Agents can enroll users into drip campaigns with a single API call. The timing, templating, and unsubscribe handling are all managed by tinysend — the agent doesn't need to build a queue.
Agents can connect any SMTP provider (SES, Mailgun, Postmark) as the delivery backend, and tinysend handles all the API abstraction. You keep control of your sender reputation and deliverability — tinysend is just the API layer.
Agents building new products often start with low volume. tinysend charges per email sent — no monthly minimums. A product that sends 200 emails/month costs essentially nothing to run.
To give Claude Code or Cursor email-sending capabilities via MCP:
npm install -g tinysend-mcp
{
"mcpServers": {
"tinysend": {
"command": "tinysend-mcp",
"env": {
"TINYSEND_API_KEY": "your_api_key_here",
"EMAIL_FROM": "[email protected]"
}
}
}
}Once configured, Claude Code can send email, trigger sequences, and check delivery status without writing any HTTP code. The agent just calls the tool.
MCP server, idempotent API, built-in sequences. Set up in under 5 minutes.
Get started free