TamingDNS MCP Server
This endpoint is a live Model Context Protocol server. Point an AI agent at it and the agent can run the same DNS and email-authentication checks you run on this site. It is the same engine code returning the same grades, as structured JSON instead of a web page. You don't need an account or an API key, and it costs nothing.
The short version
- Endpoint:
https://tamingdns.com/mcp. Streamable HTTP, JSON-RPC 2.0 over POST, stateless. - Auth: none. Rate limits apply per IP (see below).
- Tools:
check_spf,check_dkim,check_dmarc,check_dnssec,check_dane,check_mx,check_mta_sts,check_tls_rpt,check_bimi, andanalyze_email_headers. The rest of the TamingDNS diagnostics follow in later phases. - One prompt:
audit_email_auth. It runs the four email-auth checks against a domain and consolidates the result. - Discovery: server card · llms.txt · finding-code registry.
Connect your client
Any MCP client that speaks Streamable HTTP can attach. Add the server once; after that your agent calls the tools by name.
Claude Code?
claude mcp add --transport http tamingdns https://tamingdns.com/mcp
Claude Desktop or claude.ai?
Settings → Connectors → Add custom connector. Paste https://tamingdns.com/mcp as the URL. Leave authentication blank; the server doesn't use any.
Cursor?
Add this to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"tamingdns": { "url": "https://tamingdns.com/mcp" }
}
}
Raycast?
Open Raycast → search "Manage MCP Servers" → Add Server. Choose HTTP as the transport and paste the endpoint URL. Then ask Raycast AI something like "@tamingdns check the DMARC record for example.co.za". MCP servers in Raycast sit behind Raycast AI, which needs a Pro plan.
A client that only speaks stdio?
Bridge it with mcp-remote:
npx mcp-remote https://tamingdns.com/mcp
No MCP client? curl works
The server is plain JSON-RPC 2.0 over HTTPS POST, so anything that can make an HTTP request can use it. A weekly cron job that checks your clients' DMARC records is a one-liner. List the tools:
curl -sS -X POST https://tamingdns.com/mcp \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Run a check and pull out the grade and finding codes with jq:
curl -sS -X POST https://tamingdns.com/mcp \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"check_spf","arguments":{"domain":"google.com"}}}' \
| jq '.result.structuredContent | {grade, status, findings: [.findings[].code]}'
The same call shape works for check_dmarc, check_dnssec, check_dane, check_mx, check_mta_sts, check_tls_rpt and check_bimi. check_dkim also wants a selector argument, and analyze_email_headers takes a headers string instead of a domain; see the table below.
The tools
| Tool | Input | What it checks |
|---|---|---|
| check_spf | { domain } | The SPF record, the expanded include/redirect tree, the RFC 7208 lookup count, and the terminal all qualifier resolved through any redirect= chain. |
| check_dkim | { domain, selector } | One DKIM public key at <selector>._domainkey.<domain>: key type, length, revocation, test mode. For the 500-selector sweep, use the /dkim page. The remote tool validates one key at a time. |
| check_dmarc | { domain } | The DMARC policy via dual discovery: the RFC 7489 org-domain ladder receivers enforce today, and the RFC 9989 DNS Tree Walk. Emits a DISCOVERY_DIVERGENCE warning when the two pick different records. Parses DMARCbis tags (t=, np=, psd=) and checks external RUA/RUF authorisation. |
| check_tls_rpt | { domain } | The TLS-RPT record at _smtp._tls.<domain> per RFC 8460 §3 (case-sensitive leading v=TLSRPTv1, multiple records mean receivers treat it as not implemented), every rua= destination's syntax, and whether MTA-STS or DANE gives senders anything to report against. |
| check_mta_sts | { domain } | MTA-STS per RFC 8461: the _mta-sts TXT record (strict §3.1 selection), the policy file fetched without following redirects, the policy-host certificate (grade-bearing: a failed cert means senders fetch no policy), and live MX coverage against the mx: patterns. |
| check_bimi | { domain } | The BIMI record at default._bimi.<domain>, SVG Tiny-PS logo validation, the full VMC certificate chain (expiry, EKU, SCT, issuer), and the DMARC enforcement prerequisite. |
| check_mx | { domain } | The apex MX RRset (priority-sorted), and per host the A/AAAA addresses, PTR + forward-confirmed reverse DNS (FCrDNS), DANE TLSA, IP-literal (RFC 5321 §5) and CNAME (RFC 2181 §10.3) violations, and the mail provider. Detects the null MX (RFC 7505) and the implicit MX via the apex address. Probes the MTA-STS / TLS-RPT prerequisites. |
| check_dnssec | { domain } | The DNSSEC chain of trust, walked zone by zone (root → TLD → domain): DS, DNSKEY and RRSIG over binary DoH, each DS digest recomputed against the published keys (RFC 4034 §5.1.4), and the AD bit cross-checked across Cloudflare, Google, Quad9 and OpenDNS. Unsigned is the common case and returns info, not a failure; a published-but-broken chain returns fail. |
| check_dane | { domain } | SMTP DANE / TLSA records (RFC 7672): the TLSA record at _25._tcp.<mx-host> over binary DoH, each record classified by usage / selector / matching (RFC 7671 §2.1), and the DNSSEC AD bit confirmed, since an unsigned TLSA answer is the dominant failure mode. DNS-only: it never opens a port-25 handshake. |
| analyze_email_headers | { headers } | A pasted block of raw email headers, judged for spoofing and phishing: SPF/DKIM/DMARC alignment, Microsoft compauth reason codes, ARC chain integrity, homoglyph From domains, duplicate singleton headers, display-name spoofing, backward Received timestamps, and link display-vs-href mismatches. Returns a phishing verdict; the echoed input is a digest only, so raw headers never come back. |
There is also one prompt, audit_email_auth, which fans out across the four email-auth tools (SPF, DKIM, DMARC, BIMI) and returns a consolidated audit for a domain.
What comes back?
Every tool returns the same canonical envelope, in structuredContent and duplicated as a JSON text block:
status:pass/warn/fail/info. The one-word answer.grade: A to F, withgrade_reasons[]explaining each deduction in plain language.findings[]: structured issues with stable codes (POLICY_NONE,NEAR_LOOKUP_LIMIT,TESTING_MODE, and so on), severity, and remediation text. The full registry lives at /mcp/resources/finding-codes and via MCPresources/read.records[]: the raw DNS records the verdict was computed from, so an agent can show its work.analysis: tool-specific detail such as the SPF include tree, the DMARC discovery ladder, or the VMC chain.error: present only when the check itself could not run. If the DNS resolvers were unreachable, the tool returns anerrorwith a code (DOH_TIMEOUT,DKIM_LOOKUP_FAILED), a message, andretriable: trueinstead of a grade-F "no record" verdict. The tools only report a missing record from a confirmed DNS answer. Whenretriableis true, retry after the 60-second cache window.
The MCP server, the browser tools on this site, and the in-page WebMCP tools all run the same engine code. An agent calling check_dmarc gets byte-identical grading to a human using /dmarc. There is no "API version" that lags the website.
Practical details
What are the rate limits?
Per IP, a few dozen calls a minute, enough for interactive use and scheduled checks, not for bulk scanning. Results are cached for 60 seconds per input, so a retry inside that window is free. If you need more for a legitimate use case, talk to us.
Is there really no authentication?
None. Every tool is read-only and idempotent: it looks up public DNS records and grades them. There is nothing an API key would protect.
Where is the machine-readable description?
The SEP-2127 server card is at /.well-known/mcp/server-card.json. Site-wide context for LLMs is in /llms.txt and /llms-full.txt.
Looking for the v=MCPv1 DNS-key checker?
The DNS signing-key checker that used to live at /mcp moved to /mcp-keys on 2026-06-07. Same tool, new home. This path now belongs to the MCP server itself.