Let Your AI Write the HTML — Then Just Send the Email

Your coding agent can generate the email body. Your app should still deliver it with one HTTP call — no MCP server required. Notify is the dumb, reliable pipe.

AI tools are great at writing HTML email. They are unnecessary as a transport.

If your agent can call fetch, it does not need an MCP server, a plugin marketplace, or a special “email agent runtime” to deliver a password reset. Put the API key in your app (or CI), generate the body however you like, and send.

That is Notify’s whole product stance: you (or your AI) write the HTML; we deliver it. Tongue-in-cheek version: /mcp.

The wrong architecture

Agent → MCP email tool → mystery wrapper → ESP

More moving parts, more auth surfaces, more “why did the agent send 400 emails?” stories.

The right architecture

Agent or app code → generate HTML string → POST /api/email/send → inbox

Your application remains the security boundary. The agent helps author content or suggest code; production sends go through your server with your rate limits.

Pattern A — AI helps you write the template once

  1. Ask Cursor (or any agent) to draft a receipt layout
  2. Commit the HTML/TS template to your repo
  3. Fill variables at runtime
  4. Send with Notify
const message = renderReceiptEmail({
  amount: '29.00',
  currency: 'USD',
  invoiceUrl
});

await fetch('https://notify.cx/api/email/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.NOTIFY_API_KEY!
  },
  body: JSON.stringify({
    from: 'billing@your-verified-domain.com',
    to: customer.email,
    subject: `Receipt — ${amount} ${currency}`,
    message
  })
});

Human review optional but wise for auth-critical copy.

Pattern B — Agent generates HTML at runtime (guarded)

Use only behind strict allowlists:

export async function sendAgentDraftedEmail(input: {
  to: string; // must be the current user’s email
  subject: string; // allowlisted prefixes only
  html: string; // run through sanitizer
}) {
  assertUserCanEmail(input.to);
  assertSubjectAllowed(input.subject);
  const message = sanitizeEmailHtml(input.html);

  await fetch('https://notify.cx/api/email/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.NOTIFY_API_KEY!
    },
    body: JSON.stringify({
      from: 'noreply@your-verified-domain.com',
      to: input.to,
      subject: input.subject,
      message
    })
  });
}

Never give an agent a raw API key in the browser. Never let it choose arbitrary to addresses in production.

What you do not need

  • An official MCP server to wrap one HTTP request
  • A template studio inside the ESP
  • A second “AI email product” for transactional mail

If a vendor’s main AI story is MCP install paths, ask whether fetch already solved the problem.

Security checklist

  • [ ] API key only on server / secret store
  • [ ] Recipients constrained to verified user emails
  • [ ] HTML sanitized if model-generated at runtime
  • [ ] Rate limits and audit logs on send endpoints
  • [ ] Verified domain for from

Bottom line

AI is a content accelerator. Transactional email is still a boring pipe. Notify keeps the pipe small on purpose: to, from, subject, message.

Quick start · Why email APIs should stay small · /mcp · Pricing