Skip to main content
Glama

Email rendering analysis for AI assistants

CI npm license MCP Registry Smithery GitHub stars

MCP server for email compatibility analysis. Analyze, preview, diff, and fix emails across 21 email clients, plus capture real screenshots and create shareable links with an optional API key.

Send HTML, MJML, Maizzle or React Email. Set format and the template is compiled before analysis, so what gets checked is the HTML your readers actually receive.

Why your assistant needs this: across the 298 CSS and HTML features we track, only 6 are fully supported in every major email client (see the data). Ask Claude to check your email before you send it.

Built on @emailens/engine. Also available as a GitHub Action.

Install

npx -y @emailens/mcp

Related MCP server: email-on-acid-mcp

Setup

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "emailens": {
      "command": "npx",
      "args": ["-y", "@emailens/mcp"]
    }
  }
}

Claude Code

claude mcp add emailens -- npx -y @emailens/mcp

With API Key (optional, unlocks screenshots + sharing)

{
  "mcpServers": {
    "emailens": {
      "command": "npx",
      "args": ["-y", "@emailens/mcp"],
      "env": {
        "EMAILENS_API_KEY": "ek_live_..."
      }
    }
  }
}

Get your free API key at emailens.dev/settings/api-keys.

Remote (no install)

Use the hosted endpoint: no npm or Node.js needed. API key required.

{
  "mcpServers": {
    "emailens": {
      "url": "https://app.emailens.dev/api/mcp",
      "headers": {
        "Authorization": "Bearer ek_live_..."
      }
    }
  }
}

Tools

Local Tools (no account needed)

preview_email

Full email compatibility preview: transforms HTML for 21 clients, analyzes CSS, generates scores, simulates dark mode, checks inbox preview and email size.

Parameter

Type

Required

Description

html

string

Yes

Email HTML source

clients

string[]

No

Filter to specific client IDs

format

enum

No

"html", "jsx", "mjml", "maizzle"

analyze_email

Quick CSS compatibility analysis; returns per-client scores and one finding per problem. Faster than audit_email when you only need CSS compatibility.

Parameter

Type

Required

Description

html

string

Yes

Email HTML source

format

enum

No

Input format

detail

enum

No

"summary" (default) or "full"

clients

string[]

No

Only report these client IDs

targetingPolicy

enum

No

"progressive" (default), "strict", or "lenient"

One finding per problem, not one per client. The engine reports per client because a score is per client, and per selector because a fix is per selector. On an ordinary newsletter border-radius arrives twelve times (two clients that drop it, six selectors that use it) with the same sentence in every copy. That was 286KB of JSON, about 73,000 tokens, for an 11KB email.

Findings group by property, severity and message, listing the clients affected, with positions merged across all of them. The same email now returns 40KB.

{
  "property": "border-radius",
  "severity": "warning",
  "clients": ["outlook-windows", "outlook-windows-legacy"],
  "message": "Does not support \"border-radius\". Round corners can be used in VML…",
  "fixType": "structural",
  "hasFix": true,
  "loc": { "line": 61, "column": 28, "offset": 2753, "length": 171 },
  "alsoAtLines": [62, 64, 75, 78, 87]
}

Fix snippets are not included; they were 93KB of that 286KB, and fix_email produces them for the issues you decide to act on. hasFix tells you one is available; fixType tells you whether the repair is markup or CSS.

Pass detail: "full" for the engine's per-client shape with snippets, and clients: ["gmail-web", "outlook-windows"] to report only what you care about: the fastest further saving, roughly halving the response for two clients. Scores stay whole-email either way: narrowing the report does not change what the email is worth elsewhere. An unknown client ID is rejected by name; an empty result would read as "this email is fine for that client".

Source positions. For HTML input, every warning carries loc (line, column, offset, length) for the first occurrence, plus alsoAtLines for any others, so an assistant can edit the exact source and knows where the rest are. audit_email positions its other findings the same way.

{
  "property": "border-radius",
  "loc": { "line": 7, "column": 8, "offset": 142, "length": 25 },
  "alsoAtLines": [12, 19]
}

Later occurrences are line numbers rather than full positions on purpose: this response is read by a model paying for every token, and a real newsletter can produce over a thousand occurrences; carrying them all in full nearly doubles the payload.

Positions are reported for html input only. JSX, MJML and Maizzle are compiled before analysis, so a line number would point into generated output rather than the file you have open: the tools omit it instead of returning one that looks authoritative.

audit_email

Comprehensive quality audit: CSS compatibility, spam scoring, link validation, accessibility, images, inbox preview, size (Gmail clipping), template variables, content overflow, visual bugs, dark-mode and mobile text contrast, design consistency, and client targeting.

The last three cover what a light desktop preview cannot show: text that disappears when a client forces dark mode or when the email's own dark block repaints a surface without re-colouring the text on it, contrast below the email's breakpoint, and colours that differ by value but not to a reader.

Parameter

Type

Required

Description

html

string

Yes

Email HTML source

format

enum

No

Input format

detail

enum

No

"summary" (default) or "full"

clients

string[]

No

Only report these client IDs

skip

string[]

No

Checks to skip (e.g. ["spam", "images"])

targetingPolicy

enum

No

"progressive" (default), "strict", or "lenient"

fix_email

Generate a structured fix prompt for compatibility issues. Returns markdown with fix instructions that the AI can apply directly.

Parameter

Type

Required

Description

html

string

Yes

Email HTML to fix

format

enum

No

Controls fix syntax

scope

enum

No

"all" or "current"

selectedClientId

string

No

Client ID for scoped fixes

list_clients

List all 21 supported email clients with IDs, names, engines, and dark mode support.

diff_emails

Compare two email HTML versions; shows score changes, fixed issues, and introduced issues per client.

Parameter

Type

Required

Description

before

string

Yes

Original email HTML

after

string

Yes

Modified email HTML

format

enum

No

Input format

check_deliverability

Check email deliverability for a domain: SPF, DKIM, DMARC, MX, BIMI records with a score and actionable issues.

Parameter

Type

Required

Description

domain

string

Yes

Domain to check (e.g. "company.com")

Hosted Tools (require EMAILENS_API_KEY)

capture_screenshots

Capture real email screenshots across 21 clients in real browsers. Screenshots are hosted on CDN.

Parameter

Type

Required

Description

html

string

Yes

Email HTML source

format

enum

No

Input format

clients

string[]

No

Filter clients

modes

string[]

No

["light"], ["dark"], or ["light", "dark"]

title

string

No

Name for the preview

Free plan: 30 previews/day. Sign up

share_preview

Create a shareable link. Recipients see the full analysis without an account.

Parameter

Type

Required

Description

html

string

Yes

Email HTML source

title

string

No

Display title

format

enum

No

Input format

Requires Dev plan ($9/mo). Share links expire after 7 days (Dev) or never (Pro).

Template formats

format accepts html (the default), mjml, maizzle and jsx (React Email). maizzle is an HTML template or a Vue single-file component. A pasted Vue file with no format is compiled as maizzle. Anything but html is compiled before analysis and also decides the syntax the fix snippets come back in.

Compiling matters more than it sounds. An email client renders the output, so that is what has to be checked: handed a raw <mjml> document, an HTML parser finds no CSS in it and reports a perfectly clean email. An answer like that is worse than an error, because an assistant will repeat it.

The compilers are not bundled. MJML alone pulls 56MB, and this server is usually started with npx, so the engine keeps them as optional peer dependencies:

npm install mjml                                              # MJML
npm install @maizzle/framework@5                             # Maizzle HTML
npm install @maizzle/framework@6                             # Maizzle Vue single-file components
npm install sucrase react @react-email/components @react-email/render  # React Email

They have to be installed where the server runs, which is not always somewhere you control. If it is not, compile the template yourself and send the resulting HTML with format: "html": the tools say so when they hit this.

Supported Email Clients (21)

Client

ID

Dark Mode

Notes

Gmail

gmail-web

Yes

Gmail Android

gmail-android

Yes

Gmail iOS

gmail-ios

Yes

Outlook 365

outlook-web

Yes

Outlook Windows

outlook-windows

No

Outlook Windows Legacy

outlook-windows-legacy

No

Deprecated Oct 2026

Outlook iOS

outlook-ios

Yes

New in v0.4.0

Outlook Android

outlook-android

Yes

New in v0.4.0

Outlook for Mac

outlook-macos

Yes

New in v0.10.0

Apple Mail

apple-mail-macos

Yes

Apple Mail iOS

apple-mail-ios

Yes

Yahoo Mail

yahoo-mail

Yes

Yahoo Mail Android

yahoo-mail-android

Yes

New in v0.10.0

Yahoo Mail iOS

yahoo-mail-ios

Yes

New in v0.10.0

Samsung Mail

samsung-mail

Yes

Thunderbird

thunderbird

No

HEY Mail

hey-mail

Yes

Proton Mail

protonmail

Yes

New in v0.10.0

AOL Mail

aol

Yes

New in v0.10.0

Fastmail

fastmail

Yes

New in v0.10.0

Superhuman

superhuman

Yes

Releasing

Two publishes: npm, and the MCP registry. The registry listing sat five releases behind because nothing pushed server.json, so that half is a workflow now. RELEASING.md has the details and the four places the version has to agree.

Development

bun install
bun run build
bun test
bun run typecheck

License

MIT


If this saved you from an Outlook surprise, a star helps other email developers find it.

Available Tools

13 tools
analyze_emailAnalyze EmailA
Read-onlyIdempotent
Inspect

Quick CSS compatibility analysis, returns per-client scores and one finding per problem, listing the clients it affects. For HTML input each finding carries loc (line, column, offset) and alsoAtLines, so you can edit the exact source. Narrow with clients, or pass detail:'full' for the per-client breakdown with fix snippets. Use audit_email for a full quality report (spam, links, a11y, images, etc.).

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesThe email source: HTML, or an MJML / Maizzle / React Email template when `format` says so
detailNo'summary' (default) returns one entry per problem, listing the clients it affects (roughly 10x smaller). 'full' returns one entry per client with fix snippets.
formatNoSource format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle.
clientsNoOnly report these client IDs (e.g. ['gmail-web','outlook-windows']). The fastest way to cut the response when you care about specific clients. Use list_clients for the IDs.
targetingPolicyNo'progressive' (default) suppresses compatibility false-positives inside client-targeted scopes and only flags deprecated or dangerous hacks. 'strict' treats targeting as non-standard and reports every hack. 'lenient' suppresses false positives and ignores non-fatal targeting warnings.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower, yet the description adds substantial behavior: findings carry loc (line, column, offset) and alsoAtLines for HTML input, detail:'full' yields fix snippets, non-html formats are compiled first, and an unlabeled pasted Vue file is compiled as maizzle. It also conveys the relative cost of summary vs full (~10x smaller).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, all informative, with the core purpose front-loaded and the sibling redirect last. Slight density and some overlap with schema text (detail summary vs full) keep it below a 5, but there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the return-format burden and does so: it describes per-client scores, one finding per problem, affected-client listings, and loc/alsoAtLines for source editing. For a 5-parameter tool with three enums, nothing needed to call or interpret it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already explains detail, format, clients, and targetingPolicy in detail, so the baseline is 3. The description mostly restates the detail/clients semantics and adds the format complication ('Anything but html is compiled') that the schema already covers, contributing little new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Quick CSS compatibility analysis') plus the shape of the output ('per-client scores and one finding per problem, listing the clients it affects'). It distinguishes itself from siblings by explicitly contrasting with audit_email.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the alternative explicitly ('Use audit_email for a full quality report (spam, links, a11y, images, etc.)') and gives the condition that selects the quick path. It also routes to detail:'full' and clients for narrowing, so an agent knows both when to use it and how to scope it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

audit_emailAudit EmailA
Read-onlyIdempotent
Inspect

Comprehensive email quality audit: CSS compatibility, spam scoring, link validation, accessibility, images, inbox preview, size (Gmail clipping), template variables, content overflow, visual fallbacks, dark-mode and mobile text contrast, design consistency, structural faults in Outlook-only VML (which lives inside conditional comments and is invisible to every other check), style survival: CSS a client parses correctly and then discards, such as a stylesheet past Gmail's 16 KB ceiling or every rule after a }}, which no support matrix can express, and client targeting: HowToTarget hacks such as Gmail u+.body or MSO conditionals, which do not score as css-hack. For HTML input, findings tied to a specific element carry loc (line, column, offset) so you can edit the exact source. Compatibility is collapsed to one finding per problem listing the clients it affects; pass detail:'full' for the per-client breakdown with fix snippets. Use skip to omit checks, targetingPolicy to change how targeted scopes affect scores, and clients to narrow which clients are reported.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesThe email source: HTML, or an MJML / Maizzle / React Email template when `format` says so
skipNoChecks to skip (e.g. ['spam', 'images'])
detailNo'summary' (default) returns one entry per problem, listing the clients it affects (roughly 10x smaller). 'full' returns one entry per client with fix snippets.
formatNoSource format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle.
clientsNoOnly report these client IDs (e.g. ['gmail-web','outlook-windows']). The fastest way to cut the response when you care about specific clients. Use list_clients for the IDs.
targetingPolicyNo'progressive' (default) suppresses compatibility false-positives inside client-targeted scopes and only flags deprecated or dangerous hacks. 'strict' treats targeting as non-standard and reports every hack. 'lenient' suppresses false positives and ignores non-fatal targeting warnings.

TDQS

A3.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, yet the description adds substantial behavioral context: how compatibility findings are collapsed, that detail:'full' yields per-client entries with fix snippets, that HTML findings carry loc (line, column, offset), and the non-obvious semantics of targetingPolicy. This is disclosure well beyond the annotation surface.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with the core purpose and the parameter guidance trails at the end, which is reasonable. But the middle is one sprawling run-on sentence listing every check plus lengthy parenthetical asides, so size and structure are only adequate, not tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-format burden and mostly does: it explains the collapsed compatibility shape, detail:'full' output, and loc metadata. It does not describe the overall response envelope (severity/score fields), leaving a small gap for a complex, 16-check audit tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters and three enums. The description largely restates these (detail summary/full, targetingPolicy values, clients narrowing) and adds only a little (the '16 KB ceiling'/'every rule after }}' rationale), so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening states a specific verb+resource ('Comprehensive email quality audit') and then enumerates the concrete check domains it covers, so an agent knows exactly what it does. It never names or differentiates itself from close siblings like analyze_email or check_deliverability, which an agent must disambiguate on its own, so it stops short of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives solid in-tool usage guidance for options ('pass detail:full for the per-client breakdown', 'use skip to omit checks', 'clients to narrow which clients are reported'). However it offers no when-to-use-this-vs-alternatives routing, and with analyze_email/check_deliverability present the agent gets no explicit selection rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_screenshotsCapture ScreenshotsBInspect

Capture real email screenshots across 21 clients (Gmail, Outlook, Apple Mail, etc.) with light and dark mode variants. Screenshots are rendered in real browsers and hosted on CDN. Requires EMAILENS_API_KEY env var — free plan at emailens.dev?ref=mcp.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesThe email source: HTML, or an MJML / Maizzle / React Email template when `format` says so
modesNoScreenshot modes (default: ['light'])
titleNoName for the hosted preview
formatNoInput format
clientsNoFilter to specific client IDs

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, openWorldHint=true, idempotentHint=false — the agent knows this is a mutating, non-idempotent, external-calling operation. The description adds useful context (real browsers, CDN hosting, API key requirement) but doesn't explain cost, rate limits, or latency implications of rendering 21 clients.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core capability, then supporting context, then the API-key prerequisite. The '?ref=mcp' affiliate suffix at the end is promotional noise that slightly dilutes the otherwise tight structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a non-idempotent, open-world tool that renders and hosts content on a CDN, the description covers what it does and where it runs, but omits output shape (no output schema exists), pagination for 21 clients, and failure modes when the API key is missing or quota is exhausted.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five params are documented in the schema. The description adds no parameter-specific detail beyond noting clients and modes exist. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb+resource (capture email screenshots) with impressive specificity: 21 clients named, light/dark variants, real browsers, CDN hosting. This distinguishes it from preview_email and other siblings, though it doesn't explicitly name the difference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance. The description doesn't say when to call this vs preview_email or audit_email, nor does it specify prerequisites beyond an API key. The agent is left to infer routing from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_deliverabilityCheck DeliverabilityA
Read-onlyIdempotent
Inspect

Check email deliverability for a domain: SPF, DKIM, DMARC, MX, and BIMI records. Returns a score (0-100) and actionable issues. Uses DNS lookups (no API key needed).

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check (e.g. 'company.com')

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds genuinely new context beyond that: it discloses the mechanism (DNS lookups) and the absence of an API-key/auth requirement, which matters for invocation. It stops short of noting lookup latency or DNS failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste, and the highest-value information (what it checks and what it returns) is front-loaded. The no-API-key note is a compact, useful trailing clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully compensates by stating the return shape (score 0-100 plus actionable issues). For a single-parameter, read-only tool that is nearly complete, though it leaves unclear how the score is weighted or what form the 'issues' take.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already supplies an example ('company.com') and a regex pattern. The description only echoes that a domain is the target, adding no format, normalization, or subdomain-handling guidance beyond the structured field.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Check email deliverability for a domain') and enumerates the exact records examined (SPF, DKIM, DMARC, MX, BIMI). It does not explicitly differentiate itself from siblings like audit_email or analyze_email, though the domain-level DNS scope implicitly separates it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by naming the record types and noting 'no API key needed', but gives no explicit when-to-use guidance or alternatives. An agent must infer whether this is a pre-send check, a domain audit, or a substitute for audit_email.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diff_emailsDiff EmailsA
Read-onlyIdempotent
Inspect

Compare two email HTML versions, shows score changes, fixed issues, and newly introduced issues per client. Use after making fixes to verify improvements.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterYesModified email source, in the same format
beforeYesOriginal email source
formatNoSource format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds value beyond that by disclosing the shape of the result (score deltas, fixed vs newly introduced issues, broken down per client), which matters because there is no output schema. It does not discuss permissions, sizes, or limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The core comparison behavior leads and the usage trigger follows, which is the right front-loading for a tool whose main differentiation is what it produces.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 100% parameter coverage, the description's job is mainly to explain the return value, and it does list the diff categories per client. It could be more complete about the structure/format of that report or whether the comparison is order-sensitive, but nothing essential for calling it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the format enum is documented thoroughly in the schema (including compile behavior and the pasted Vue fallback). The description only implies the two-version input ('two email HTML versions') and adds no ordering or format guidance beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (compare/diff) and resource (two email HTML versions) and enumerates the diff outputs: score changes, fixed issues, and newly introduced issues per client. This is unambiguous and clearly separable from siblings like analyze_email (single input) or fix_email (mutation), so an agent can route without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives an explicit trigger: 'Use after making fixes to verify improvements.' That is real when-to-use guidance. It stops short of naming alternatives or when-not conditions (e.g., use analyze_email for a single unreviewed version), so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fix_emailFix EmailA
Read-onlyIdempotent
Inspect

Generate a structured fix prompt for email compatibility issues. Returns markdown with the original code, detected issues (CSS or structural), fix snippets, and format-specific instructions. Use after preview_email or analyze_email.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesThe email source: HTML, or an MJML / Maizzle / React Email template when `format` says so: the source to fix
scopeNo'all' (default) or 'current' (requires selectedClientId)
formatNoSource format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle.
selectedClientIdNoClient ID to scope fixes to (e.g. 'outlook-windows')

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a read-only, idempotent, non-destructive operation, and the description is consistent with that ('Generate a fix prompt' rather than mutating code). It adds genuinely useful return-value context — markdown containing original code, detected issues, fix snippets, and format-specific instructions — which matters because there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with zero filler; the artifact/return shape is front-loaded, followed by the workflow cue. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies the return contract, and the schema plus annotations fully cover inputs and safety. An agent has everything needed to select and call this correctly after analysis.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the parameter descriptions are rich (format enum semantics, scope/selectedClientId dependency, compiled-vs-pasted Vue behavior). The description adds nothing beyond the schema for parameters, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource: 'Generate a structured fix prompt for email compatibility issues', and it explicitly clarifies the artifact type (markdown with original code, detected issues, fix snippets). It implicitly distinguishes itself from siblings by being the 'fix' step after preview/analyze, though it doesn't name what it is *not* for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit sequencing guidance: 'Use after preview_email or analyze_email', naming the two upstream siblings. No when-not or exclusion conditions are given, but the workflow position is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_clientsList Email ClientsA
Read-onlyIdempotent
Inspect

List every supported email client with IDs, names, engines, and dark mode support.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds value beyond them by disclosing the shape of the returned data (IDs, names, engines, dark mode support), which matters since no output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the resource is stated first and the returned fields follow compactly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-param, read-only list tool with no output schema, the description supplies exactly the missing piece: what the list contains. Nothing an agent needs to invoke it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the rubric the baseline is 4. There is nothing for the description to disambiguate, and it correctly implies no inputs are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('every supported email client') and enumerates the fields returned (IDs, names, engines, dark mode support). An agent can tell immediately what this does, and none of the siblings (check_deliverability, preview_email, etc.) overlap with it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: as a zero-parameter enumeration tool it is obviously for looking up available clients, but the description never states when to call it (e.g., before other client-keyed calls) or any alternative. Adequate but with a clear gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_emailPreview EmailB
Read-onlyIdempotent
Inspect

Full email compatibility preview, transforms HTML for 21 email clients (Gmail, Outlook, Apple Mail, Yahoo, Samsung, Thunderbird, HEY, Proton Mail, AOL, Fastmail, Superhuman), analyzes CSS, generates scores, simulates dark mode, checks inbox preview and email size.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesThe email source: HTML, or an MJML / Maizzle / React Email template when `format` says so
formatNoSource format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle.
clientsNoOptional client ID filter (e.g. ['gmail-web', 'outlook-windows'])
targetingPolicyNo'progressive' (default) suppresses compatibility false-positives inside client-targeted scopes and only flags deprecated or dangerous hacks. 'strict' treats targeting as non-standard and reports every hack. 'lenient' suppresses false positives and ignores non-fatal targeting warnings.

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, non-destructiveHint, openWorldHint=false), so the bar is lower, and the description usefully adds that this compiles/transforms source across 21 named clients, simulates dark mode, and checks inbox preview and size. 'Transforms HTML' could momentarily read as a mutation, but in context (preview, readOnly annotation) it clearly means render-time transformation, so it is not contradictory. It does not say what the response contains, which is the only remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is correctly front-loaded in the opening clause, and each listed clause carries information. But the whole body is one comma-spliced run-on sentence with no grouping, making the feature list dense to parse for a tool with this many distinct capabilities.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, four-parameter tool with no output schema and a rich annotation set, the description covers what is computed but not what is returned, and gives no routing context against the many overlapping sibling tools. Adequate as a minimum viable definition, but an agent still lacks the material needed to choose this tool over analyze_email or audit_email.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the enum semantics of format, targetingPolicy, and clients are fully documented in the schema itself, establishing a baseline of 3. The description only gestures at parameters indirectly (the 21-client list maps loosely to `clients`), adding no format, ID, or policy syntax beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Full email compatibility preview') and enumerates the concrete analyses it performs (client transforms, CSS analysis, scoring, dark mode, inbox preview, size). However, it never distinguishes itself from close siblings like analyze_email, audit_email, or capture_screenshots, and the 'analyzes CSS'/'generates scores' clauses actively overlap with those tools, leaving an agent to guess which one to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use, when-not-to-use, or alternative-routing guidance at all, despite a crowded sibling set (analyze_email, audit_email, fix_email, capture_screenshots, check_deliverability). The description implies it is the broad preview step but never says when an agent should prefer one of the narrower tools instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sandbox_get_inboxGet Sandbox InboxAInspect

Get your active Emailens sandbox test address (or create a new one). Send emails here via SMTP (smtp.emailens.dev:2525) or inbound domain routing. Requires EMAILENS_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOptional inbox name (e.g. 'Auth E2E Test')

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and idempotentHint=false, and the description is consistent with that by disclosing the possible side effect ('or create a new one'). It further adds value beyond the annotations by naming the auth requirement (EMAILENS_API_KEY) and the exact SMTP host/port for sending test mail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences, front-loaded with the core action, followed by the practical connection and auth details. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description adequately conveys what is returned (an active test address) and how to use it. It is slightly thin on what happens when a new inbox is created (e.g., lifetime, reuse behavior), but nothing critical to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single optional 'name' parameter is fully documented in the schema. The description adds nothing about the name parameter's effect (e.g., whether it changes the address or just a label), so it sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get your active Emailens sandbox test address') and explicitly notes the get-or-create duality, which is the key behavioral distinction. It is clearly separable from siblings like sandbox_list_messages and sandbox_wait_for_email.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains how to use the returned address (SMTP endpoint smtp.emailens.dev:2525 or inbound routing) and the API key prerequisite, which is genuinely useful context. However, it never states when to prefer this tool over the sibling sandbox tools or when an agent should call it in a workflow, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sandbox_get_messageGet Sandbox MessageA
Read-onlyIdempotent
Inspect

Get complete captured email details including HTML/text parts, extracted OTP, magic links, headers, and spam analysis. Requires EMAILENS_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageIdYesID of the sandbox message

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds genuinely new context: the exact content returned (HTML/text parts, extracted OTP, magic links, headers, spam analysis) and the API-key auth requirement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly packed sentences with zero redundancy; the return-value enumeration is front-loaded and the auth requirement trails as a short qualifier. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully enumerates what comes back and flags the credential requirement, which is enough for a single-parameter read tool. Only the missing sibling differentiation keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with a single parameter ('messageId' documented as 'ID of the sandbox message'), so the schema does the heavy lifting. The description adds nothing about where that ID comes from or its format, which is the expected baseline when coverage is complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get complete captured email details') and enumerates the payload (HTML/text parts, OTP, magic links, headers, spam analysis). It does not, however, distinguish itself from the very similar siblings sandbox_list_messages and sandbox_wait_for_email, leaving the agent to infer that this fetches one full message by ID.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The only guidance is a prerequisite ('Requires EMAILENS_API_KEY'). There is no statement of when to use this versus sandbox_list_messages to enumerate an inbox or sandbox_wait_for_email to poll for a new arrival, which are the obvious alternatives an agent must choose between.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sandbox_list_messagesList Sandbox MessagesB
Read-onlyIdempotent
Inspect

List recently received test emails in your sandbox inboxes. Requires EMAILENS_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
inboxIdNoOptional inbox ID filter

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety profile is covered. The description usefully adds the auth prerequisite and the 'recently received' recency scoping, but says nothing about result count limits, ordering, or pagination behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core purpose front-loaded and the auth requirement trailing. No wasted words, though it is terse enough that it omits information the agent would benefit from.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description could reasonably say something about the shape or volume of results (list of messages, recency window, ordering). Annotations cover safety, but the listing semantics remain underspecified for a tool whose main value is its return payload.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single inboxId parameter is already documented as an optional filter. The description's plural 'sandbox inboxes' implies multi-inbox results but adds no filtering syntax or semantics beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (recently received test emails in sandbox inboxes), which is clearly distinguishable from write-oriented siblings like fix_email or sandbox_wait_for_email. It does not explicitly name the sibling it differs from (e.g. sandbox_get_message for a single message), so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The only guidance is a prerequisite ('Requires EMAILENS_API_KEY'), not a when-to-use condition. There is no statement of when to choose this over sandbox_get_inbox, sandbox_get_message, or sandbox_wait_for_email, leaving the agent to infer the routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sandbox_wait_for_emailWait for Sandbox EmailA
Read-only
Inspect

Poll and wait for a matching incoming test email in the sandbox. Automatically extracts 4-8 digit OTP codes and action links for zero-regex test assertions. Requires EMAILENS_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
senderNoSubstring match for sender address (case-insensitive)
inboxIdNoOptional inbox ID filter
subjectNoSubstring match for email subject (case-insensitive)
timeoutSecondsNoMax seconds to wait (default: 30, max: 60)

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, non-destructive, open-world, and non-idempotent. The description adds genuinely new behavior: this call polls/blocks until a match arrives, auto-extracts 4-8 digit OTP codes and action links, and requires EMAILENS_API_KEY auth. It stops short of describing what happens on timeout or how results are shaped.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core blocking behavior, then the value-add (OTP/link extraction), then the prerequisite. No filler; every sentence carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully signals what the agent gets back (OTP codes, action links) and flags the auth prerequisite. It omits timeout/failure semantics, which matters for a polling tool, but the schema covers the timeout parameter itself.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so sender, inboxId, subject, and timeoutSeconds are fully documented in the schema. The description adds no syntax, matching semantics, or default/max hints beyond what the schema already provides; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Poll and wait for a matching incoming test email in the sandbox.' The blocking/polling nature distinguishes it from read-once siblings like sandbox_get_message, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the phrase 'zero-regex test assertions' and the required API key, which suggest an end-to-end test flow. There is no explicit when-to-use, when-not-to-use, or routing to alternatives such as sandbox_list_messages for non-blocking checks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

share_previewShare PreviewAInspect

Create a shareable link for an email preview. Recipients see the full analysis without needing an account. Requires EMAILENS_API_KEY env var and Dev plan ($9/mo).

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesThe email source: HTML, or an MJML / Maizzle / React Email template when `format` says so
titleNoDisplay title for the share page
formatNoInput format

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare non-read-only, non-idempotent, open-world, non-destructive, but disclose nothing about requirements. The description adds genuinely useful context beyond them: the EMAILENS_API_KEY env var dependency, the paid Dev plan gate, and the fact that recipients view the analysis unauthenticated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action, then the recipient benefit, then the prerequisites. No filler; the pricing detail is arguably incidental but small.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does cover the return concept ('shareable link') and the recipient-side view, plus auth/plan prerequisites. It lacks any note on link lifetime, revocation, or whether repeated calls produce distinct links, which for a non-idempotent open-world tool is a minor remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with 3 well-documented params including an enum for `format`, so the schema carries the burden. The description adds no parameter-level detail (e.g., whether `title` is optional or how `format` interacts with `html`), so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Create a shareable link for an email preview.' This distinguishes it from sandbox/preview siblings that generate previews rather than share them, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated — the agent can infer you call this when you want to share a preview externally, but there is no explicit when-to-use vs. when-not or named alternative (e.g., preview_email vs. share_preview). Prerequisites (API key, Dev plan) are given, which helps but is not the same as routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv0.10.1
    • Changedanalyze_email5 fields changed
      • addedInput schema / properties / clients
        Added value: +{
        +  "description": "Only report these client IDs (e.g. ['gmail-web','outlook-windows']). The fastest way to cut the response when you care about specific clients. Use list_clients for the IDs.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "'summary' (default) returns one entry per problem, listing the clients it affects (roughly 10x smaller). 'full' returns one entry per client with fix snippets.",
        +  "enum": [
        +    "summary",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / format / description
        Previous value: -"Input format for framework-specific fix snippets"New value: +"Source format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle."
      • changedInput schema / properties / html / description
        Previous value: -"The email HTML source code"New value: +"The email source: HTML, or an MJML / Maizzle / React Email template when `format` says so"
      • addedInput schema / properties / targetingPolicy
        Added value: +{
        +  "description": "'progressive' (default) suppresses compatibility false-positives inside client-targeted scopes and only flags deprecated or dangerous hacks. 'strict' treats targeting as non-standard and reports every hack. 'lenient' suppresses false positives and ignores non-fatal targeting warnings.",
        +  "enum": [
        +    "progressive",
        +    "strict",
        +    "lenient"
        +  ],
        +  "type": "string"
        +}
    • Changedaudit_email6 fields changed
      • addedInput schema / properties / clients
        Added value: +{
        +  "description": "Only report these client IDs (e.g. ['gmail-web','outlook-windows']). The fastest way to cut the response when you care about specific clients. Use list_clients for the IDs.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "'summary' (default) returns one entry per problem, listing the clients it affects (roughly 10x smaller). 'full' returns one entry per client with fix snippets.",
        +  "enum": [
        +    "summary",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / format / description
        Previous value: -"Input format for framework-specific fix snippets"New value: +"Source format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle."
      • changedInput schema / properties / html / description
        Previous value: -"The email HTML source code"New value: +"The email source: HTML, or an MJML / Maizzle / React Email template when `format` says so"
      • changedInput schema / properties / skip / items / enum
        Previous value: -[
        -  "spam",
        -  "links",
        -  "accessibility",
        -  "images",
        -  "compatibility",
        -  "inboxPreview",
        -  "size",
        -  "templateVariables"
        -]New value: +[
        +  "spam",
        +  "links",
        +  "accessibility",
        +  "images",
        +  "compatibility",
        +  "inboxPreview",
        +  "size",
        +  "templateVariables",
        +  "overflow",
        +  "visual",
        +  "darkContrast",
        +  "mobileContrast",
        +  "design",
        +  "vml",
        +  "styleSurvival",
        +  "targeting"
        +]
      • addedInput schema / properties / targetingPolicy
        Added value: +{
        +  "description": "'progressive' (default) suppresses compatibility false-positives inside client-targeted scopes and only flags deprecated or dangerous hacks. 'strict' treats targeting as non-standard and reports every hack. 'lenient' suppresses false positives and ignores non-fatal targeting warnings.",
        +  "enum": [
        +    "progressive",
        +    "strict",
        +    "lenient"
        +  ],
        +  "type": "string"
        +}
    • Changedcapture_screenshots1 field changed
      • changedInput schema / properties / html / description
        Previous value: -"The email HTML source code"New value: +"The email source: HTML, or an MJML / Maizzle / React Email template when `format` says so"
    • Changeddiff_emails3 fields changed
      • changedInput schema / properties / after / description
        Previous value: -"Modified email HTML"New value: +"Modified email source, in the same format"
      • changedInput schema / properties / before / description
        Previous value: -"Original email HTML"New value: +"Original email source"
      • changedInput schema / properties / format / description
        Previous value: -"Input format for framework-specific analysis"New value: +"Source format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle."
    • Changedfix_email2 fields changed
      • changedInput schema / properties / format / description
        Previous value: -"Input format — controls fix syntax"New value: +"Source format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle."
      • changedInput schema / properties / html / description
        Previous value: -"The email HTML source code to fix"New value: +"The email source: HTML, or an MJML / Maizzle / React Email template when `format` says so: the source to fix"
    • Changedpreview_email3 fields changed
      • changedInput schema / properties / format / description
        Previous value: -"Input format: 'html' (default), 'jsx', 'mjml', or 'maizzle'"New value: +"Source format: 'html' (default), 'jsx' (React Email), 'mjml', or 'maizzle' (HTML template or Vue single-file component). Anything but 'html' is compiled before analysis and sets the syntax of the fix snippets. A pasted Vue file with no format is compiled as maizzle."
      • changedInput schema / properties / html / description
        Previous value: -"The email HTML source code"New value: +"The email source: HTML, or an MJML / Maizzle / React Email template when `format` says so"
      • addedInput schema / properties / targetingPolicy
        Added value: +{
        +  "description": "'progressive' (default) suppresses compatibility false-positives inside client-targeted scopes and only flags deprecated or dangerous hacks. 'strict' treats targeting as non-standard and reports every hack. 'lenient' suppresses false positives and ignores non-fatal targeting warnings.",
        +  "enum": [
        +    "progressive",
        +    "strict",
        +    "lenient"
        +  ],
        +  "type": "string"
        +}
    • Addedsandbox_get_inbox
    • Addedsandbox_get_message
    • Addedsandbox_list_messages
    • Addedsandbox_wait_for_email
    • Changedshare_preview1 field changed
      • changedInput schema / properties / html / description
        Previous value: -"The email HTML source code"New value: +"The email source: HTML, or an MJML / Maizzle / React Email template when `format` says so"
  2. 9 tool updatesv0.4.1
    • First observedanalyze_email
    • First observedaudit_email
    • First observedcapture_screenshots
    • First observedcheck_deliverability
    • First observeddiff_emails
    • First observedfix_email
    • First observedlist_clients
    • First observedpreview_email
    • First observedshare_preview

TDQS

A3.8/5.0

Scored across 13 tools

Disambiguation4/5

The three analysis tools (preview_email, analyze_email, audit_email) overlap in CSS-compatibility scoring, which could cause misselection. However, descriptions explicitly differentiate scope (quick vs. full preview vs. comprehensive audit) and cross-reference each other, and the remaining tools (deliverability, fix, diff, screenshots, sandbox ops) are clearly distinct.

Naming Consistency4/5

Almost everything follows a clean verb_noun snake_case pattern (check_deliverability, analyze_email, diff_emails, share_preview). The sandbox_ namespace prefix is a minor, internally consistent deviation rather than a break in convention.

Tool Count5/5

13 tools is well within the ideal 3-15 range and each one earns its place: deliverability, layered analysis, fixing, diffing, rendering, sharing, and sandbox testing. No filler tools are present.

Completeness4/5

The surface covers a full lifecycle — preflight deliverability, multi-depth compatibility analysis, fix generation, before/after diffing, screenshots, sharing, and sandbox receive/OTP extraction. Coverage is strong, with only minor gaps (e.g., no send-scheduling or list/template management).

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An advanced email security analysis MCP server for real-time phishing detection, comprehensive header analysis, and threat intelligence integration. It enables users to extract indicators of compromise and validate email authentication protocols like DKIM, SPF, and DMARC.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server exposing every documented Email on Acid API v5 request as a tool — 24 tools across authentication, email client lists, email rendering testing, and spam testing.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Comprehensive email validation MCP server that checks syntax, MX records, disposable domains, role-based accounts, SPF/DKIM, typo suggestions, and risk scoring.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server providing email client compatibility data from caniemail.com, enabling agents to lint HTML/CSS for email client support, check feature support across clients, and search for features by keyword, with verdicts including supported, unsupported, mitigated, and untested.
    1
    MIT