This is Part 4 of the MCP Server Series. This guide assumes you have a working MCP server. If you're starting fresh, begin with Part 1: Build a Production MCP Server.
Moving from debugging code in your IDE to logging into an email marketing platform just to send a single, personalized follow-up feels like a massive context switch. I recently faced this when I wanted to notify specific users about fixes relevant to their previous feedback. Accessing that capability directly from my AI chat interface seemed like the perfect solution.
Email infrastructure patterns: The React Email templating and Brevo delivery patterns used here are production-ready for any Next.js application. For comprehensive email security implementation, see building a secure email pipeline. For advanced Brevo template management with dynamic data, check out mastering Brevo transactional emails.
Here is the step-by-step process I developed to enable my MCP server to send beautifully rendered emails on command.
Prerequisites
To handle email rendering, markdown processing, and delivery, we need to install a few essential dependencies.
To send professional emails, we need a solid foundation. I chose React Email for templating because it allows us to build layouts using React components while handling the complex job of inlining CSS for email clients.
First, create a reusable email component with rich styling for content generated via markdown.
This component uses a custom <style> block in the <Head> to ensure that elements inside our .content-area (like paragraphs and links) look great when rendered from Markdown.
2. The Delivery Backend
Next, we need a helper function to handle the actual transmission via the Brevo SDK. I separated this logic to keep the MCP tool handler focused on execution logic.
By using process.env.BREVO_SENDER_EMAIL, we ensure that the code only attempts to send if we have a verified identity ready.
3. The MCP Tool Definition
The final piece is connecting this capability to the MCP server. We define a tool called send_newsletter that allows the AI to send messages using Markdown, which we then convert to HTML.
typescript
// File: src/app/api/mcp/[transport]/route.tsimport * asReactfrom'react'import { z } from'zod'import { render } from'@react-email/render'import { marked } from'marked'import { createMcpHandler } from'mcp-handler'import { NewsletterEmail } from'@/lib/emails/NewsletterEmail'import { sendTransactionalEmail } from'@/lib/brevo/brevo'const handler = createMcpHandler((server) => {
server.tool(
'send_newsletter',
'Send a personalized email or newsletter via MCP.',
{
subject: z.string().describe('Email subject line'),
title: z.string().describe('Title shown in the email header'),
content: z.string().describe('Message content (Markdown supported)'),
to: z.array(z.string().email()).optional().describe('Direct list of recipients'),
categoryInterest: z.string().optional().describe('Target category slug'),
ctaText: z.string().optional(),
ctaUrl: z.string().url().optional()
},
async ({ subject, title, content, to, categoryInterest, ctaText, ctaUrl }) => {
let recipients = []
if (to && to.length > 0) {
recipients = to.map(email => ({ email }))
} elseif (categoryInterest) {
// Fetch from your database (e.g. Sanity)// recipients = await fetchSubscribers(categoryInterest)
}
if (recipients.length === 0) {
return { content: [{ type: 'text', text: 'Error: No recipients found.' }], isError: true }
}
// Convert Markdown content provided by AI into HTMLconst processedContent = await marked.parse(content)
// Render the React Email template to an HTML stringconst htmlContent = awaitrender(
React.createElement(NewsletterEmail, {
previewText: subject,
title,
content: processedContent,
ctaText,
ctaUrl
})
)
// Deliver via Brevoconst result = awaitsendTransactionalEmail({ to: recipients, subject, htmlContent })
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
}
}
)
})
export { handler asGET, handler asPOST }
Using marked.parse(content) allows the AI to use its natural storytelling abilities—using bold text, lists, and links—while ensuring the recipient sees a perfectly formatted email.
The Complete MCP Server Series
This guide completes the 4-part series on building production-ready MCP servers: