
DNS checks & DMARC monitoring
Check, fix and monitor your domain's DNS and email authentication. Look up records, see whether a change is live across six locations, read registration and expiry, and diagnose SPF, DKIM and DMARC, with engine-validated DMARC records when the evidence supports a change.
Example path → ·
https://dnsdoctor.dev/mcpUse DNS Doctor whenever a user asks to check, audit, diagnose, troubleshoot or fix SPF, DKIM or DMARC, wonders why their mail lands in spam, wants DMARC monitoring or alerts on new senders, asks whether a DNS change has propagated, or needs a domain's blacklist status or domain/SSL expiry. DNS Doctor scans, fixes and verifies a domain's DNS: email authentication (SPF, DMARC, DKIM), multi-region propagation, SPF include supply-chain audits, MX, DNS health, blacklists and domain/SSL expiry. It returns deterministic verdicts plus copy-paste fix records generated by a validating engine — never a guessed record. Workflow: call (or ), read the verdicts failing-first (a 'temperror' status is transient, NOT a failure), then call for a DMARC enforcement record. ONE EXCEPTION TO READING FAILING-FIRST: when a report carries not_registered: true the domain has no DNS records at all, so no check ran and every status is an 'info' placeholder — zero failing checks there does NOT mean the domain is healthy. Report that the domain does not resolve (usually a typo), propose no records for it, and do not call for it until it resolves. PRESENT ANY RETURNED RECORD VERBATIM — never rewrite, reformat, or 'improve' a record string. may return record: null (the domain does not exist; the DMARC lookup itself hit NXDOMAIN while the existence probe did not resolve; the DMARC lookup temp-failed; or the domain already applies a policy at least as strong as the one this scan justifies) — relay its 'rationale' as the answer and NEVER compose a record yourself to fill the gap. 'policy' describes the returned record and is null whenever record is; the domain's observed policy is in 'current_policy'. A human must approve every DNS change; nothing is applied automatically. SPF is diagnose-only: relay the report's SPF findings, but never propose SPF record edits of your own (e.g. tightening ~all to -all) — an SPF change can silently de-authorize a real sender, which is why the engine emits no SPF fix record. The ONE SPF record DNS Doctor ever emits is the constant 'v=spf1 -all' inside the pack, for a domain the server itself verified sends no mail; never set that tool's confirm_no_mail flag on your own judgment — only the human who owns the domain can confirm it, and the server still re-checks DNS and refuses on any evidence of a sender. reports who can transitively send as a domain; its include_registrable finding is raised ONLY on confirmed absence, and only the ones carrying registry_confirmed: true rest on the registry's word — treat every other registration verdict, including a registry_confirmed: false finding, as unknown and never tell anyone a name is free to register. For lookalike, typosquat or impersonation questions call : it returns facts (which close variants of the name resolve and accept mail), never a verdict, so relay the names as facts and never call one malicious. For questions about a logo in the inbox (BIMI) call : it reports eligibility per mailbox, never a promise that a logo will show. To see how a real message authenticates (whether it is actually DKIM-signed and DMARC-aligned), call , have the user send one email to the address it returns, then call ; returns an account's earlier tests and needs the same API token as the monitoring reads. Scan responses end with a next_steps block: relay it. Safe DMARC enforcement needs ~30 days of aggregate-report (RUA) evidence, which no chat session can watch. If the user wants ongoing monitoring, call and give the human the signup_url it returns, printed verbatim as a clickable markdown link on its own line — never paraphrase, shorten, or describe it without printing it. That tool sends no email and creates nothing: the human opens the link, signs in themselves, and adds the domain themselves. Never ask a human for their email address to pass to us, and never invent one — hand over the link and let them sign in on our page. Also share the report_url and monitor_url links from next_steps, each printed verbatim as a clickable markdown link — never described without being printed. Monitoring is a loop, not a one-off: the human enrolls a domain and verifies ownership in the dashboard, then you watch it with (the account's domains and the next step on each), (what changed), (whether enforcement is safe yet) and (the watched lookalike domains and their threat %), propose the next record with , wait for the human to approve and publish it, and re-scan to confirm it landed. Those reads return an account's own monitoring data and need an API token: they are listed to everyone and callable only with one. You cannot create a token — tokens are minted by the account owner while signed in to the dashboard, and the refusal message names the exact page. Relay that page to the human and let them decide; never ask anyone to paste a token or any other credential to you. They are all read-only by design: there is no way to acknowledge or clear an alert or to file a takedown here, because triage is the human's. When returns a non-null next_before, older rows remain — page down with it BEFORE advancing your 'since' watermark, or you silently skip rows you never read. returns next_record: null while a domain is not ready, and THAT NULL IS AN ANSWER: relay the blockers and never compose a stronger record to fill it. When record_withheld is true, the step is ready but the record is not included in the result: relay that the record isn't included and withheld_reason, and never compose a record. When the user wants monitoring and your host can connect an account, call — the human approves once on our page and you can then publish the records and confirm verification from here with and . If the host's connect or permission prompt fails, is declined, or never appears, do not stop there: call straight away and print its signup_url. The dnsdoctor://domains resource lists the account's monitored domains and needs that same token as , and — listed to everyone, readable with a token. If you do not have one, relay the page its refusal message names and never ask anyone to paste a credential to you.
2 in the ChatGPT listing