Skip to main content
Glama
HuluWZ
by HuluWZ

resend-email-lint

Lint email HTML before you send it. One rule set, three interfaces:

  • a library for your code,

  • a CLI for CI,

  • an MCP server so an AI agent can check an email before sending it.

Email clients are unforgiving. Missing alt text, relative image URLs, javascript: links, <script> tags and messages over Gmail's ~102 KB clipping limit all fail silently. This tool catches them with clear messages and line numbers.

It works with any sender. It does not call any email API.

CLI

npx resend-email-lint ./emails
examples/bad.html
  1:1  warning  Missing <!DOCTYPE html>.  (missing-doctype)
  3:3  error    Image has no alt attribute. Add alt="" if it is decorative.  (img-alt)
  3:3  error    Image src "/logo.png" is relative. Use an absolute https:// URL or a cid: reference.  (img-src-relative)
  5:3  error    Link has an empty href.  (link-href)
  6:3  error    <script> is not supported in email and will be removed.  (no-script)

4 errors, 4 warnings

Exit codes: 0 clean, 1 lint errors (or too many warnings), 2 usage or I/O error.

Option

Meaning

-f, --format text|json

Output format

--marketing

Also run bulk-mail rules (unsubscribe link)

-i, --ignore <rule>

Skip a rule (repeatable)

--max-warnings <n>

Fail if warnings exceed n

--list-rules

Print every rule

Read from stdin with -: cat email.html | npx resend-email-lint -

React Email: lint the rendered HTML, not the .tsx. Render first (for example with email export, or render() from @react-email/render), then point the CLI at the output.

In CI

- run: npx resend-email-lint ./out/emails --max-warnings 0

Related MCP server: mail7-mcp

Library

import { lintHtml } from "resend-email-lint";

const { diagnostics, errorCount } = lintHtml(html, { marketing: false, ignore: ["html-lang"] });
if (errorCount > 0) throw new Error(diagnostics.map((d) => d.message).join("\n"));

Example with Resend, checking before you send:

import { Resend } from "resend";
import { lintHtml } from "resend-email-lint";

const resend = new Resend(process.env.RESEND_API_KEY);
const { errorCount, diagnostics } = lintHtml(html);
if (errorCount > 0) throw new Error(JSON.stringify(diagnostics));
await resend.emails.send({ from, to, subject, html });

lintHtml is pure and synchronous: no I/O, no network.

MCP server

Add to your MCP client config (Claude Desktop, Cursor, and so on):

{
  "mcpServers": {
    "email-lint": {
      "command": "npx",
      "args": ["-y", "-p", "resend-email-lint", "resend-email-lint-mcp"]
    }
  }
}

Tools:

  • lint_email_html: takes html (and optional marketing, ignore) and returns diagnostics with rule id, severity, line and column.

  • list_rules: lists every rule.

Designed for agents as users. Tool descriptions say when to call them ("before sending"). Errors name the valid rule ids so an agent can self-correct. Diagnostics are structured JSON an agent can act on. The server is also deliberately pure: it has no filesystem, network or environment access, and caps input at 2 MB, so handing it to an agent adds no new permissions.

Rules

Rule

Severity

Checks

img-alt

error

<img> has an alt attribute

img-src-relative

error

Image URL is absolute (or cid: / data:)

link-href

error

Links have a real href (not empty, # or javascript:)

no-script

error

No <script>

link-https

warning

Links use https

no-external-css

warning

No external stylesheets

html-size

warning

Under Gmail's 102 KB clipping limit

missing-doctype

warning

Documents declare a doctype

html-lang

warning

<html lang> is set

missing-title

warning

<title> is present

missing-unsubscribe

warning

Unsubscribe link present (--marketing only)

Document-level rules only run when the input contains an <html> tag, so fragments are not flagged.

Contributing

New rules are the easiest way in. See CONTRIBUTING.md.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides email validation and domain configuration auditing tools for AI assistants, enabling single address checks, bulk list cleaning, SPF verification, and full mail setup grading (A-F) with actionable fixes.
    4
    36 npm
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to verify email addresses in real-time, checking syntax, DNS, MX records, and SMTP handshake, returning verdicts and deliverability scores without sending actual emails.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Lets developers and MCP agents run deterministic local HTML audits, turning inline HTML into structured findings for missing labels, unnamed buttons, skipped headings, ambiguous links, duplicate IDs, and missing landmarks. It also exposes a rule list and returns stable, actionable reports without external API keys.
    2
    MIT