DomainRef
Remote MCP server for domain and email-security checks. domain_check returns a graded pass/warn/fail report for SPF, DKIM, DMARC, MX, TLS certificate, Microsoft 365 tenant, DNSSEC, BIMI and a UCEPROTECT blocklist check, with the exact DNS fix for each issue. domain_age returns registrar plus creation and expiry dates. Paid per call ($0.01 / $0.005) with an API key; listed on the official MCP Registry as dev.domainref/domainref. MCP endpoint: https://domainref.dev/mcp (streamable HTTP).
Hosted MCP Server
npx add-mcp 'https://domainref.dev/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
What it checks
-
SPF
Which servers are allowed to send email as your domain. SPF guide -
DKIM
A signature on your mail that proves it really came from you. DKIM guide -
DMARC
What receivers should do with mail that fakes your domain, and who gets the reports. DMARC guide -
MX
Whether your domain can receive email, and which servers take it. -
Website certificate
Whether the HTTPS certificate on your site is valid, matches the name and is not about to expire. -
Microsoft 365 tenant
Whether the domain runs on Microsoft 365, and whether its signing keys are switched on. -
DNSSEC
Whether your DNS answers are signed so nobody can forge them on the way. DNSSEC guide -
BIMI
The record that puts your logo next to your mail in some inboxes, and its certificate. BIMI guide -
Blocklist
Whether your mail servers' addresses are on the UCEPROTECT Level 1 blocklist. Blocklist guide -
Domain age
Who the registrar is, when the domain was registered and when it expires. Very new domains are a fraud signal.
Also MTA-STS, TLS-RPT and CAA, which protect mail in transit and control who may issue certificates for you. 13 checks in all. Optional features you have not set up show as info with the record to add. They never lower the score.
Technical detail of every check
| Check | What is graded |
|---|---|
| SPF | One record, at most 10 DNS lookups and 2 void lookups, no ptr. ~all passes when DMARC enforces. |
| DKIM | 46 common selectors probed in parallel, including Microsoft 365 selector1 / selector2, Google, Zoho, Proton, Fastmail, Mandrill, Mailjet, SendGrid, Amazon SES and Mimecast. Flags every key under 2048 bits by selector, with the provider's rotation step. |
| DMARC | Policy, sp=, pct, reports (rua) and external report authorisation. A hostname falls back to its organisational domain (Public Suffix List). |
| MX | Present and resolvable. Only an explicit null MX (0 .) counts as no mail. |
| MTA-STS | The _mta-sts TXT record and the HTTPS policy on mta-sts.<domain>: mode, mx coverage, max_age. A policy senders cannot apply (unreadable, invalid, duplicate TXT or mode: none) is info like no MTA-STS; mx lines that miss an MX fail in enforce mode. |
| TLS-RPT | A _smtp._tls record with a valid rua. |
| DNSSEC | Validated by both Cloudflare and Google (they must agree): broken signatures (SERVFAIL that answers with checking off) fail, with the resolver's own error text. Also flags a signed zone with no DS at the registrar, RSA/SHA-1 algorithms 5 and 7 and SHA-1 DS digests (RFC 8624). |
| CAA | Which CAs may issue, and whether the current certificate's CA is allowed. |
| Website certificate | The HTTPS certificate on port 443: issuer, days to expiry, hostname match, chain. A small part of the score. |
| Registration | Registrar (name and IANA ID only), age, expiry and hold flags from the registry's RDAP. A domain under six months old is reported as info here, since only time changes it; the age endpoint grades it. If the registry does not answer, the summary says it was not checked. |
| Microsoft 365 | Tenant detection from Microsoft's public sign-in discovery endpoints. Info only. |
| BIMI | default._bimi record and its mark certificate: VMC or CMC, issuer, expiry, domain match, and whether the chain leads to a DigiCert, GlobalSign or SSL.com Mark Verifying Authority root (otherwise it is reported as a claim). Also whether DMARC enforces. Info only, never scored. |
| Blocklist | MX and SPF sending IPs (IPv4, up to 10) on UCEPROTECT Level 1, looked up only while the list's own test entry answers correctly. Level 1 lists single IPs seen hitting UCEPROTECT spamtraps or other abuse, automatically or manually; entries expire 7 days after the last incident. Info or warn, never scored. Copyright © 2001-2021 UCEPROTECT-Network http://www.uceprotect.net, used under the UCEPROTECT licence. |
See an example report
This is what a typical small business on Microsoft 365 gets back. The domain is made up (.example is reserved for examples), but every line is written by the real check.
D
yourbusiness.example
Score 45/100. 1 fail, 2 warn, 3 pass, 7 info.
Example
- FAIL DMARC No DMARC record, here or at the organisational domain. Receivers have no policy for mail that fails SPF and DKIM, and you get no reports. Fix: Publish TXT at _dmarc.yourbusiness.example: "v=DMARC1; p=none; rua=mailto:[email protected] ", read the reports for two to four weeks, then move to p=quarantine. [email protected] is a placeholder: replace it with a real mailbox you read (create it first).
- WARN SPF SPF is valid (2 of 10 lookups) but ends in ~all and DMARC does not enforce, so spoofed mail is only soft-failed. Fix: Enforce DMARC (p=quarantine or reject), or change ~all to -all once every sender is listed. "v=spf1 include:spf.protection.outlook.com -all"
- WARN DKIM No DKIM key at the 46 common selectors. A custom selector cannot be discovered from DNS, so this may be a false alarm. Fix: In the Microsoft Defender portal (Email & collaboration > Policies & rules > Threat policies > Email authentication settings, DKIM tab, or https://security.microsoft.com/authentication?viewid=DKIM) enable signing for this domain and publish the two CNAME records it shows for selector1._domainkey and selector2._domainkey.
- PASS MX 1 MX host, all resolvable.
- PASS Website certificate (HTTPS on 443) Valid certificate from Let's Encrypt R11, 71 days left.
- PASS Registration (registrar and age) Registered 2014-03-02 via Example Registrar, 4615 days old, expires 2027-03-02. 7 optional extras (info, not scored)
- INFO Microsoft 365 tenant Microsoft 365 tenant 00000000-0000-0000-0000-000000000000 (cloud sign-in). Mail goes to Exchange Online but DKIM selector1/selector2 are not published. Fix: Enable DKIM for the domain in the Microsoft Defender portal and publish its selector1 and selector2 CNAME records.
- INFO MTA-STS No MTA-STS. Sending servers will deliver over plain text if a TLS downgrade is forced. Fix: Publish TXT at _mta-sts.yourbusiness.example: "v=STSv1; id=2026102001" and serve https://mta-sts.yourbusiness.example/.well-known/mta-sts.txt as text/plain containing: version: STSv1 mode: testing mx: *.mail.protection.outlook.com max_age: 604800 Move to mode: enforce once TLS-RPT reports are clean.
- INFO TLS-RPT No TLS-RPT record, so you get no reports when senders fail to reach you over TLS. Fix: Publish TXT at _smtp._tls.yourbusiness.example: "v=TLSRPTv1; rua=mailto:[email protected] ". [email protected] is a placeholder: replace it with a real mailbox you read (create it first).
- INFO DNSSEC DNSSEC is not enabled. DNS answers for this domain can be spoofed on the path. Fix: Turn on DNSSEC at your DNS host, wait until it serves the DNSKEY, then publish the DS record it gives you at the registrar for yourbusiness.example (algorithm 13, digest type 2). Publish the DS last: a DS that does not match the zone takes the domain offline for validating resolvers until the DS TTL runs out.
- INFO CAA No CAA record, so any public CA may issue certificates for this domain. Fix: Publish CAA at yourbusiness.example: 0 issue "letsencrypt.org", plus one 0 issue record for every other CA that issues for you (check your CDN, e.g. Cloudflare or AWS, and any second CA), and 0 iodef "mailto:[email protected] ". A CA left off the list cannot renew. [email protected] is a placeholder: replace it with a real mailbox you read (create it first).
- INFO BIMI No BIMI record (optional: shows your logo in Gmail, Apple Mail and Yahoo).
- INFO Blocklist (UCEPROTECT Level 1) Not listed on UCEPROTECT Level 1 (1 mail IP checked).
FAILBroken or missing. Fix this first. WARNWorks, but weaker than it should be. PASSSet up correctly. INFOOptional or informational. Never lowers the score.
How to run a check
- Get a way to pay. Buy card credit for an Afriref API key at afriref.dev/pricing, or use any wallet or AI agent that pays x402 or MPP. There is no account to create here.
- Ask for the report. Run one command, with your own domain in place of yours.com:
curl -H "X-API-Key: YOUR_KEY" "https://domainref.dev/v1/domain/check?domain=yours.com" - Fix what it finds. Start with FAIL, then WARN. Each line carries its fix, and the guides below walk through each record.
Only need the age and registrar? GET /v1/domain/age?domain=example.com is $0.005. Not for registries without RDAP, e.g..za/.co.za,.me,.de,.io,.eu: the age lookup is refused free (422). A bad domain name, a domain that does not exist, a private-only domain, a DNS outage or a rate limit is refused free, before any charge.
How to fix what it finds
Short guides with example records, free to read:
-
SPF
Fix SPF step by step: one v=spf1 record, the 10 DNS lookup limit, Microsoft 365 and Google Workspace includes, ~all vs -all, and domains that send no mail. -
DKIM
Set up DKIM signing: Microsoft 365 selector1 and selector2 CNAMEs, the Google Workspace google._domainkey key, other senders, 2048-bit keys and how to check them. -
DMARC
Roll out DMARC safely: publish p=none with reports, align SPF and DKIM for every sender, then move to p=quarantine and p=reject. Example records included. -
MTA-STS and TLS-RPT
Set up MTA-STS so sending servers must use TLS to your MX, plus TLS-RPT reports: the _mta-sts TXT record, the policy file, testing then enforce mode. -
DNSSEC
Turn on DNSSEC safely (sign at your DNS host, then publish the DS at the registrar) and fix the SERVFAIL caused by a DS that no longer matches your keys. -
BIMI
Set up BIMI step by step: DMARC at enforcement, an SVG Tiny PS logo, the default._bimi TXT record, and a VMC or CMC mark certificate with its full chain. -
Blacklist check
Check whether your mail server IP is on a DNS blocklist (DNSBL): find your sending IPs, query the list over DNS, read the answer, and get delisted.
For developers and AI agents
- API:
GET /v1/domain/check?domain=($0.01) andGET /v1/domain/age?domain=($0.005). See /openapi.json. - MCP:
https://domainref.dev/mcp(streamable HTTP) with two tools, domain_check and domain_age. Pass api_key; per-call x402 and MPP payment is HTTP only. - For LLMs: /llms.txt. x402 discovery: /.well-known/x402.
Call it without payment and you get the x402 price challenge:
$ curl -si "https://domainref.dev/v1/domain/check?domain=example.com" | grep -iE "^HTTP|^payment-required"
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi...
Any x402 client reads that 402, pays $0.01 in USDC on Base (eip155:8453) and retries. No key, no signup.
The response is JSON. Real output for example.com, trimmed to three checks:
{
"domain": "example.com",
"score": 100,
"letter": "A",
"summary": "example.com scores 100/100 (A): 6 pass, 0 warn, 0 fail, 7 info. Nothing to fix.",
"checks": [
{ "check": "dmarc", "label": "DMARC", "grade": "pass",
"finding": "DMARC enforces p=reject on 100% of mail.", "fix": null },
{ "check": "mta_sts", "label": "MTA-STS", "grade": "info",
"finding": "Not applicable: the domain publishes a null MX, so it takes no mail.", "fix": null },
{ "check": "registration", "label": "Registration (registrar and age)", "grade": "pass",
"finding": "Registered 1995-08-14 via RESERVED-Internet Assigned Numbers Authority (IANA 376), 11390 days old, expires 2027-08-13.", "fix": null }
]
}
Non-intrusive and private. Only the ordinary requests a browser or mail server makes: public DNS, the registry's RDAP, Microsoft's public discovery endpoints, one TLS handshake on port 443 and, when published, the MTA-STS policy on port 443. No port scans. The DomainRef app does not store queried domains; our firewall log keeps request URLs (with the domain) for about 6 months. The DNS resolvers, Microsoft and the registry see the domain but never who asked. Our CDN necessarily sees your IP and the request. See privacy and terms.