email-deliverability
Why mail bounces or lands in spam, read in the order that stops you changing the wrong record.
Save as .claude/skills/email-deliverability/SKILL.md in a repository, or under ~/.claude/skills/email-deliverability/SKILL.md to have it everywhere. The copy button takes the whole file, frontmatter included.
---
name: email-deliverability
description: Diagnose why mail from a domain is bouncing, being rejected, or landing in spam. Use when a user reports bounced mail, messages going to spam, a DMARC failure, mail rejected by Gmail or Microsoft, or asks about SPF, DKIM, DMARC, MTA-STS or an IP blocklist.
---
# Email deliverability triage
Look every record up. Never state a record's contents from memory, and never
infer a record from the domain's other records.
Work in this order. Each step can end the investigation, so do not read ahead.
## Requires
The toolhq MCP server, for `mx_lookup`, `dns_lookup`, `reverse_dns` and
`ip_reputation`:
claude mcp add --transport http toolhq https://toolhq.io/api/mcp
If those checks are unavailable, say so and stop. Do not describe what a
record probably contains.
## 1. Is there a mail route at all
`mx_lookup` on the domain.
No MX records means no inbound mail, and nothing below matters. Report that
and stop.
If MX records point at a host that does not resolve, that is the fault. Check
with `dns_lookup`.
## 2. SPF
`dns_lookup` for the TXT records on the domain. The SPF record is the one
starting `v=spf1`.
Three faults, in order of how often they are the cause:
- **More than one SPF record.** This is a hard failure, not a warning.
Receivers are required to treat it as permerror, so the domain is handled as
having no SPF at all. Two records usually means someone added a provider
without merging. You must read every TXT record to see this, not just the
first that matches.
- **Over ten DNS lookups.** Each `include:`, `a`, `mx`, `ptr` and `exists`
costs a lookup, and `include:` is recursive, so one provider's own record can
spend five by itself. Over ten is permerror. Count it, do not estimate it.
- **Ends in `+all`.** This authorises the entire internet to send as the
domain. Treat as critical.
A record ending `~all` (softfail) rather than `-all` (fail) is not a bug. It is
a deliberate and common choice, and it is not the cause of a rejection.
## 3. DKIM
DKIM lives at `<selector>._domainkey.<domain>` and selectors cannot be
enumerated from DNS. Establish which selectors the sender actually uses before
concluding anything.
If a message is available, read the `s=` tag in its DKIM-Signature header.
Otherwise ask, or try the provider's documented defaults.
A selector that does not resolve and a selector that was never configured look
identical from outside. State which you established and which you assumed.
## 4. DMARC
Read this last. It depends on SPF and DKIM, and reading it first leads to
recommending a policy change when the real fault is below it.
`dns_lookup` for TXT on `_dmarc.<domain>`.
- `p=none` is monitoring only and does not cause rejection. If mail is being
rejected and the policy is `p=none`, DMARC is not the cause.
- `p=reject` with a broken SPF and DKIM pair is the classic bounce.
- Alignment is what catches people. SPF must align on the envelope domain and
DKIM on the signing domain. A provider that sends with its own envelope
domain passes SPF and still fails DMARC alignment. Compare the domains, not
just whether the checks passed.
## 5. Transport and reputation
Only once the records above are correct.
- MTA-STS: fetch the policy at
`https://mta-sts.<domain>/.well-known/mta-sts.txt` and confirm the
`_mta-sts` TXT record exists. A policy in `enforce` mode that omits a live MX
host will break mail.
- `ip_reputation` on the sending address, for blocklist and proxy status.
- `reverse_dns` on the sending address. A missing or mismatched PTR is a common
cause of filtering by large receivers.
## Report back
1. The cause, in one sentence.
2. The evidence: the record as it actually reads, and the count if a limit was
exceeded.
3. The fix: the exact record to publish.
4. Anything you assumed rather than verified, named explicitly.what it needs
This one looks things up rather than describing them, so it needs live checks. Instructions cannot reach the network on their own, and a skill running through the Claude API has no network access at all. Add the toolhq MCP server and these become real: mx_lookup, dns_lookup, reverse_dns, ip_reputation.
the instructions, in full
Email deliverability triage
Look every record up. Never state a record's contents from memory, and never infer a record from the domain's other records.
Work in this order. Each step can end the investigation, so do not read ahead.
Requires
The toolhq MCP server, for mx_lookup, dns_lookup, reverse_dns and
ip_reputation:
claude mcp add --transport http toolhq https://toolhq.io/api/mcp
If those checks are unavailable, say so and stop. Do not describe what a record probably contains.
1. Is there a mail route at all
mx_lookup on the domain.
No MX records means no inbound mail, and nothing below matters. Report that and stop.
If MX records point at a host that does not resolve, that is the fault. Check
with dns_lookup.
2. SPF
dns_lookup for the TXT records on the domain. The SPF record is the one
starting v=spf1.
Three faults, in order of how often they are the cause:
- More than one SPF record. This is a hard failure, not a warning. Receivers are required to treat it as permerror, so the domain is handled as having no SPF at all. Two records usually means someone added a provider without merging. You must read every TXT record to see this, not just the first that matches.
- Over ten DNS lookups. Each
include:,a,mx,ptrandexistscosts a lookup, andinclude:is recursive, so one provider's own record can spend five by itself. Over ten is permerror. Count it, do not estimate it. - Ends in
+all. This authorises the entire internet to send as the domain. Treat as critical.
A record ending ~all (softfail) rather than -all (fail) is not a bug. It is
a deliberate and common choice, and it is not the cause of a rejection.
3. DKIM
DKIM lives at <selector>._domainkey.<domain> and selectors cannot be
enumerated from DNS. Establish which selectors the sender actually uses before
concluding anything.
If a message is available, read the s= tag in its DKIM-Signature header.
Otherwise ask, or try the provider's documented defaults.
A selector that does not resolve and a selector that was never configured look identical from outside. State which you established and which you assumed.
4. DMARC
Read this last. It depends on SPF and DKIM, and reading it first leads to recommending a policy change when the real fault is below it.
dns_lookup for TXT on _dmarc.<domain>.
p=noneis monitoring only and does not cause rejection. If mail is being rejected and the policy isp=none, DMARC is not the cause.p=rejectwith a broken SPF and DKIM pair is the classic bounce.- Alignment is what catches people. SPF must align on the envelope domain and DKIM on the signing domain. A provider that sends with its own envelope domain passes SPF and still fails DMARC alignment. Compare the domains, not just whether the checks passed.
5. Transport and reputation
Only once the records above are correct.
- MTA-STS: fetch the policy at
https://mta-sts.<domain>/.well-known/mta-sts.txtand confirm the_mta-stsTXT record exists. A policy inenforcemode that omits a live MX host will break mail. ip_reputationon the sending address, for blocklist and proxy status.reverse_dnson the sending address. A missing or mismatched PTR is a common cause of filtering by large receivers.
Report back
- The cause, in one sentence.
- The evidence: the record as it actually reads, and the count if a limit was exceeded.
- The fix: the exact record to publish.
- Anything you assumed rather than verified, named explicitly.
check its answers by hand
A skill that reasons well about wrong data is still wrong. For the first few cases, run the same question through a tool that cannot be mistaken.
Grade a domain’s email setup: MX, SPF, DKIM, DMARC, blacklists, and BIMI in one scored report.
Open the toolBuild a valid SPF TXT record from includes, IP addresses, and an all mechanism.
Open the toolBuild a DMARC TXT record for _dmarc with policy, reporting, and alignment options.
Open the toolTrace the delivery path, read SPF, DKIM, and DMARC verdicts, and spot spoofing signs in raw email headers. Parsed entirely in your browser.
Open the toolwhy it is written this way
A complete SKILL.md for mail deliverability triage: the order to read records in, the traps that cause wrong diagnoses, and the live checks it depends on.
An agent skill for DNS and email debugging