Skill instructions
dns-doctor68.4 KB
View saved version →
---
name: dns-doctor
description: Use when the user wants to look up DNS records, verify a DNS change, check propagation across regions, read domain registration or expiry, or diagnose SPF, DKIM, DMARC and email deliverability problems. Also covers provider-issued email DNS verification, reverse DNS, blacklists, parked-domain hardening, BIMI logo setup and linked-account monitoring. Returns observed DNS evidence and engine-validated fix records; never invents a record.
license: Apache-2.0
compatibility: Talks to the DNS Doctor MCP server at https://dnsdoctor.dev/mcp (hosted) or via the local `@dnsdoctor/mcp` stdio client; needs outbound HTTPS.
metadata:
{
"homepage": "https://dnsdoctor.dev/methodology",
"author": "DNS Doctor"
}
---
# DNS Doctor — the DNS, DMARC, SPF and DKIM skill
DNS Doctor looks up and verifies DNS records, checks propagation and registration,
and diagnoses email authentication and DNS health. It returns observed evidence
and **copy-paste fix records generated by a validating engine**, never an LLM
guess. Explain the result and relay records exactly as returned; do not author
a DNS record yourself.
## Choose the shortest workflow for the user's request
Ask for a missing domain, exact record name or type before calling a tool. Use
this router first; the full scan workflow below is for a broad diagnosis, not a
prerequisite for every lookup. Stop when the requested question is answered.
Two jobs have their own short skills: **verify-change** (did my change land,
has it propagated, look again after the TTL) and **fix-dmarc** (scan, the next
DMARC record, re-check).
| User's question | First tool and boundary |
|---|---|
| One record, or did my change land? | `check_record` for the requested type/name, with `expected_value` when checking an edit. Preserve subdomains such as `www`; use `host` where applicable. Relay `verdict`; on `wait`, wait `check_again_after_seconds` before checking again. An empty answer is absence; a lookup failure is unknown. |
| Tell me when my change is live? | `watch_record_change` (linked account) with the same arguments as the `check_record` call. Relay `watch.note`: one email to the account's own address. Without a linked account, share the `check_record` result's `watch.url` instead. Never ask for an email address. |
| Which domains does the account monitor? | `list_my_domains` (token). Never guess the list from alerts. |
| Has it propagated across regions? | `check_propagation` with the exact FQDN and record type; use the supplied `expected_value` when present. Report actual coverage, not a worldwide claim from a local read. |
| Registrar, registration, expiry or locks? | `lookup_registration`; `unknown` is never proof a name is available. |
| Choosing a domain name: which candidates are taken, or what do they cost? | Suggest candidates, then call `check_domain_names` ONCE with up to 20 of them. Relay `not_registered` as "the registry has no registration", never "available", and relay `caveat` as given (premium status is not checked). For cost questions, point to the result card: for names with no registration it shows standard prices for each ending; you do not see those numbers, so never quote or guess a price. `unknown` is never absence. |
| Is this DKIM selector published? | `check_dkim_selector` with the selector the user or provider supplied. Never fabricate a key or selector. |
| Broad email-authentication or DNS diagnosis? | `scan_domain`, then focused follow-up only as needed. It publishes a public report; do not scan a domain the user wants kept private. |
| Does a real email actually authenticate (signed, aligned, why it lands in spam)? | `start_email_test`, then the "Test a real email" playbook below. A published DKIM key does not prove the sender signs; one test message does. |
| Logo in the inbox (BIMI): how to get it, does it work, why it doesn't show? | `check_bimi`, then the "Logo in the inbox (BIMI)" playbook below. Its `mailboxes` are eligibility, Preview of the first 4,000 characters. Read full instructions →
fix-dmarc18.7 KB
View saved version →
---
name: fix-dmarc
description: Use when the user wants to fix, add, tighten or move up their DMARC record, asks how to get from p=none to quarantine or reject, or why DMARC fails. Scans the domain with DNS Doctor, gets the next validated DMARC record from build_dmarc_upgrade, has the user publish it, then re-checks it. Relays the engine's reason when there is no record; never composes one.
---
# Fix my DMARC
Scan, get the one next record, the user publishes it, check it. Each step ends
on the next action, so the user never has to ask "what now?".
## Rules
- **Never compose or edit a DMARC record.** Every record comes from a DNS
Doctor tool result and is printed **verbatim**, host and value exactly as
returned. Never rewrite, reformat or "improve" it.
- **The ladder is `p=none` → `p=quarantine` → `p=reject`**, one step at a time,
never with `pct`. A scan can justify at most `p=quarantine`, and only with
alignment evidence. `p=reject` needs weeks of aggregate-report evidence
that every real sender passes; no scan gives it.
- **SPF is diagnose-only.** Relay SPF findings; never propose an SPF record or
edit (not even `~all` to `-all`).
- The user publishes every DNS change; you never change DNS for them.
- Plain words for a non-expert: see "Explain it for a non-expert" at the end of
this skill.
## Flow
1. **Scan.** Call `scan_domain`. It publishes a public report page, and so
does `build_dmarc_upgrade` (it scans fresh too): if the user wants the
domain kept private, run neither and say why. Read DMARC, SPF and DKIM failing-first: `temperror` is a lookup
that did not complete, never a failure; `info` is "not found", never a
failure. If the report has `not_registered: true`, the domain does not
resolve: propose no records and ask which domain they meant.
2. **Get the record.** Call `build_dmarc_upgrade` with the domain. It scans
fresh and decides the step itself.
- **`record` present:** print it verbatim and where it goes
(`_dmarc.<domain>`, a TXT record). It replaces their current DMARC record;
a domain must have only one. Say in one line what this step changes. End
with: "Publish it at your DNS host and tell me when it's done; I'll check
it."
- **`record` is `null`:** relay its `rationale` as the answer and stop
there. Never fill the gap with a record of your own. `policy` describes
the returned record, so it is `null` too; the domain's observed policy is
in `current_policy`. Common reasons: already at least as strong as the
evidence allows, no alignment signal yet (reporting comes first), the
DMARC lookup did not complete (try again shortly), the domain does not
exist, or the domain is on Automatic DMARC (DNS Doctor serves the record
and the owner applies steps from the dashboard).
3. **Re-check.** When they say it is published, call `check_record` with
`kind: dmarc` and `expected_value` set to the record. On `done`, call
`scan_domain` once more and say whether DMARC now passes. On `wait`, say
when to look again (`check_again_after_seconds`) and ask them to tell you
then. On `edit`, relay `found_at` if it names where the value landed instead.
For "has it reached everywhere?" use `check_propagation` on
`_dmarc.<domain>`, type `TXT` (see the verify-change skill).
4. **Next step.** After `p=quarantine`, say plainly that `p=reject` needs about
30 days of aggregate-report evidence, which a chat cannot collect. If the
user owns the domain and wants that evidence gathered, offer DNS Doctor
monitoring, set up as the dns-doctor skill describes; never promise a date.
If a domain's DKIM is missing, the key comes from the sending provider: point
the user to that provider's DKIM setup and never invent a key or selector.
## Explain it for a non-expert
The user is usually a small-business owner or someone who built their site with
an AI tool, not a sysadmin. Say in ONE plain sentence what the result means for
their Preview of the first 4,000 characters. Read full instructions →
setup23 KB
View saved version →
---
name: setup
description: First-run setup for DNS Doctor. Runs once when the user installs the plugin. Asks which domain they manage, scans its email authentication (SPF, DKIM, DMARC) and DNS with the DNS Doctor tools, explains what is failing first, gives the exact fix record, and, only for a domain the user says they own, offers DMARC monitoring that starts with one DNS record. Every reply ends on the next concrete step.
---
# DNS Doctor setup
Run this once, right after install. Keep it short: one domain, one scan, one
clear next step. **End every reply on the next concrete action** (a question
the user can answer yes to, or "publish it and tell me"): never stop at a
summary and wait for "what next?".
## Hard rules (they apply here exactly as everywhere else)
- **Never compose or edit a DNS record.** Every record you show comes from a
DNS Doctor tool result and is printed **verbatim**, host and value exactly as
returned. If a tool returns no record, say why (relay its `rationale`) and
stop; never fill the gap yourself.
- **A human publishes every DNS change.** You never sign in, publish a record or
change DNS on the user's behalf. You show the record; they publish it.
- **SPF is diagnose-only.** Relay the scan's SPF findings; never propose an SPF
record or an edit to one (not even `~all` to `-all`).
- **DMARC moves one step at a time:** `p=none` → `p=quarantine` → `p=reject`,
never with `pct`. A scan (and `build_dmarc_upgrade`) goes no further than
`p=quarantine`. `p=reject` is never derived from a scan: only `get_readiness`
on a monitored domain, from its DMARC report evidence, can give that step,
and when its record is withheld you relay `withheld_reason`, never compose it.
- A scan result is a public report page at `https://dnsdoctor.dev/scan/<domain>`.
If the user wants a domain kept private, do not scan it.
## Explain it for a non-expert
The person installing this is usually a small-business owner or someone who
built their site with an AI tool, not a sysadmin.
- After each finding, ONE plain sentence on what it means for their email: who
could send mail pretending to be them, whether their mail may land in spam,
or what would stop working.
- Gloss a technical word the first time, in 3-6 words, for example "DKIM (a
signature that proves the mail is really yours)" or "SPF (the list of servers
allowed to send your mail)".
- At most one short fact per reply, taken only from the heading below that
matches the finding you are explaining. Never state a fact, number or date
beyond the tool results and that heading.
- Don't lecture and don't scare: a missing record is something to fix, not an
emergency, and the record plus the next step stay the main part of the reply.
<!-- fact-bank:start (generated from backend/dns_doctor/education/facts.py by `python -m tests.mcp_server.regen_fact_bank`; never edit by hand) -->
### Facts you may use
Pick a fact only from the heading for the finding you are explaining, and use
at most one per reply. Quote it as written or shorter and never add a number it
does not state. Each fact names its source in the comment after it. "Our
numbers" are DNS Doctor's own scans: aggregates only, the domains we last
checked in October 2026 that have email set up (they publish MX records).
Where the DNS Doctor result card is shown it may carry its own short tip from
this list, so add no fact of your own there.
#### No DMARC record (`No DMARC record found`)
- DMARC is how you tell mail providers what to do with mail that fakes your address.
<!-- source: RFC 7489 §6.3, https://www.rfc-editor.org/rfc/rfc7489.html#section-6.3 -->
- Gmail requires DMARC from anyone sending more than 5,000 messages a day to Gmail; `p=none` is enough.
<!-- source: Google, 2024, https://support.google.com/a/answer/81126 -->
- Yahoo has required DMARC (at least `p=none`) from bulk senders since February 2024.
<!-- source: Yahoo, 2024, https://senders.yahooinc.com/best-practices/ -->
Preview of the first 4,000 characters. Read full instructions →
verify-change18.6 KB
View saved version →
---
name: verify-change
description: Use when the user has just published or edited a DNS record (DMARC, SPF, DKIM, MX, TXT, CNAME, A) and asks whether it worked, landed, is live or has propagated. Reads the record from the domain's own nameservers with DNS Doctor, then checks propagation from six vantage points, and says when to look again after the TTL. Observation only; never composes a record.
---
# Verify a DNS change
The user changed a record and wants to know it worked. Three reads, in order,
each ending on the next one. Stop when the user's question is answered.
## Rules
- **Observation only.** No record is ever composed here. If the user needs a
record, it comes from a DNS Doctor tool result, printed verbatim.
- An empty answer is absence; a lookup failure (`cant_tell`, `transient`,
`unavailable`) is unknown, never "the record is missing".
- SPF is diagnose-only: if the SPF read looks wrong, relay what was found and
never propose an SPF edit of your own.
- Plain words for a non-expert: see "Explain it for a non-expert" at the end of
this skill.
## Flow
1. **Did it land?** Call `check_record` with the domain, the `kind`
(`spf`, `dmarc`, `txt`, `mx`, `cname`, `a`, `aaaa`), `host` for a label such
as `selector1._domainkey` or `www` (txt, cname, a and aaaa only), and `expected_value` set to the value
they published (exactly as they gave it, or as the tool that issued it
returned it). Relay `verdict`:
- `done`: their nameservers serve it and both caches agree. End with:
"Want me to check it has reached every region?" and, on yes, go to step 2.
- `wait`: it is published, caches are still catching up. Say when to look
again (`check_again_after_seconds`, said in minutes) and end with: "Tell
me then and I'll check again."
- `edit`: their nameservers do not serve it. If `found_at` names another
place, say the value was published there instead (often the domain typed
twice in the host field). End with: "Fix that, then tell me and I'll check
again."
- `not_registered: true`: the domain does not exist (usually a typo). Ask
which domain they meant.
Two resolvers is the whole sample of this read: never call it worldwide.
If the user wants to be told when it lands (on `wait` or `edit`), call
`watch_record_change` with the same arguments: one email to their linked
account. Relay `watch.note`; never ask for an email address.
2. **Has it propagated?** Call `check_propagation` with the exact name the
record lives at (`_dmarc.example.com` for DMARC, `selector._domainkey.example.com`
for DKIM, the apex for SPF and MX), `record_type` (`TXT` for SPF, DMARC and
DKIM), and the same `expected_value`. You have one network vantage point; this
reads six. Report `vantage_reached` of `vantage_total`. An `unavailable` cell
is a probe that did not answer, never absence there. A `verdict` of
`unknown` means coverage was too thin to call: say so, never round it up.
If some regions still show the old value, end with when to look again (the
record's TTL) and "tell me then and I'll check again".
3. **Confirm the effect.** When the change was a fix from a DNS Doctor scan,
once step 1 says `done` call `scan_domain` again and say whether the check
now passes. When it was a DNS Doctor verification record, call
`check_domain_verification` instead.
One tap of "check again" from the user is one call. Never loop calls while
waiting; ask the user to come back after the wait.
The page <https://dnsdoctor.dev/tools/dns-propagation-checker> runs the same
propagation check for the user; if you offer it, print the link as is.
## Explain it for a non-expert
The user is usually a small-business owner or someone who built their site with
an AI tool, not a sysadmin. Say in ONE plain sentence what the result means for
their mail, gloss any technical word in 3-6 words (for example "DKIM (a
signature that proves the mail is really yours)"), and don't lecturePreview of the first 4,000 characters. Read full instructions →