A side-by-side look at the Domain Security and MCP Server Dns MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Domain Security for security work as a local process; choose MCP Server Dns for security as a local process. You can also run both side by side in one mcpServers block.
email_auth_audit, spf_check, dmarc_check.dns_lookup, reverse_dns, resolve_all.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Security | Security |
| Quality signal | 63/100 · Good | 59/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Local subprocess (stdio) |
| Auth | Not declared | No auth required |
| Pricing | Not declared | Free |
| Required env vars | None listed | None listed |
| Verified owner | Community listing | Community listing |
| GitHub stars | 1 | 3 |
| Directory activity | 1 views 0 installs 0 upvotes | 3 views 0 installs 0 upvotes |
| Tools | 19 | 5 |
| Full listing | View Domain Security | View MCP Server Dns |
email_auth_auditHeadline tool. Audits a domain's email-authentication posture in one call — SPF, DKIM, DMARC and MX — then returns a 0–100 score, an A–F grade and a prioritised list of fixes. Use this first; reach for the per-record tools (spf_check, dmarc_check, dkim_check) only when you need the full detail of one mechanism.
Args:
- domain (string): the domain to audit.
- dkim_selectors (string[], optional): DKIM selectors to probe. If omitted, common provider selectors are tried (absence is then inconclusive).
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns (JSON):
{
"domain": string,
"grade": "A".."F",
"score": number, // 0-100
"has_mx": boolean,
"mx_hosts": string[],
"spf": { found, record, all_qualifier, lookup_count, exceeds_lookup_limit, findings[] },
"dmarc":{ found, policy, tags, findings[] },
"dkim": { any_found, selectors[], findings[] },
"top_recommendations": string[]
}
Examples:
- "Is example.com protected against email spoofing?" -> email_auth_audit(domain="example.com")
- "Audit acme.com, our DKIM selector is 'k1'" -> email_auth_audit(domain="acme.com", dkim_selectors=["k1"])
Errors: returns an error only if the domain is malformed; missing records are reported as findings, not errors.spf_checkFetch and analyse a domain's SPF record. Detects: missing/multiple records, the trailing 'all' qualifier (+all/?all/~all/-all), and counts DNS-querying terms recursively against the RFC 7208 limit of 10.
Args:
- domain (string): the domain to check.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { found, record, multiple_records, all_qualifier, lookup_count, exceeds_lookup_limit, findings[] }.
Example: "Does sendgrid.net's SPF exceed the 10-lookup limit?" -> spf_check(domain="sendgrid.net").dmarc_checkFetch and parse a domain's DMARC record (_dmarc.<domain>). Reports the policy (p=), subdomain policy (sp=), reporting addresses (rua/ruf), pct and alignment (aspf/adkim), and warns on monitor-only or partial deployments.
Args:
- domain (string): the domain to check.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { found, record, policy, tags{}, findings[] }.
Example: "What is paypal.com's DMARC policy?" -> dmarc_check(domain="paypal.com").dkim_checkLook up DKIM public keys at <selector>._domainkey.<domain>. Because DKIM selectors are arbitrary and undiscoverable, you should pass the selector(s) your mail provider uses for a definitive answer; otherwise a curated list of common selectors is probed and a miss is inconclusive.
Args:
- domain (string): the domain to check.
- selectors (string[], optional): DKIM selectors to probe.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { any_found, probed_selectors, selectors[{selector, found, record, key_type}], findings[] }.
Examples:
- "Does acme.com publish a DKIM key for selector 'google'?" -> dkim_check(domain="acme.com", selectors=["google"])
- "Find any DKIM keys for acme.com" -> dkim_check(domain="acme.com")mta_sts_checkCheck a domain's MTA-STS deployment: the _mta-sts TXT record AND the policy file at https://mta-sts.<domain>/.well-known/mta-sts.txt. Reports the enforcement mode (enforce/testing/none) and the listed MX hosts. MTA-STS forces TLS for inbound SMTP and blocks downgrade attacks.
Args:
- domain (string): the domain to check.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { dns_record_found, policy_found, mode, policy{}, findings[] }.
Example: "Does gmail.com enforce MTA-STS?" -> mta_sts_check(domain="gmail.com").tls_rpt_checkCheck a domain's TLS-RPT record (_smtp._tls.<domain> TXT). TLS-RPT lets you receive reports about TLS delivery failures to your domain.
Args:
- domain (string): the domain to check.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { found, record, findings[] }.
Example: "Does microsoft.com publish TLS-RPT?" -> tls_rpt_check(domain="microsoft.com").bimi_checkCheck a domain's BIMI record (default._bimi.<domain> TXT), which points to the brand logo (and optional VMC) displayed next to authenticated mail. BIMI requires an enforced DMARC policy to take effect.
Args:
- domain (string): the domain to check.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { found, record, findings[] }.
Example: "Does cnn.com have BIMI set up?" -> bimi_check(domain="cnn.com").dns_lookupResolve all common DNS record types (A, AAAA, CNAME, MX, NS, TXT, SOA) for a domain in one call, using public resolvers (Cloudflare/Google/Quad9).
Args:
- domain (string): the domain to query, e.g. "example.com".
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: a map of record type -> list of records. Each record has { type, host, value, priority? }.
Examples:
- "What are the MX records for stripe.com?" -> dns_lookup(domain="stripe.com")
- Use ssl_certificate for TLS details, whois_lookup for registration data.
Errors: returns an error if the domain is malformed or has no resolvable records.reverse_dnsResolve the PTR (reverse DNS) records for an IP address — the hostname(s) the IP maps back to.
Args:
- ip (string): IPv4 or IPv6 address.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { ip, hostnames: string[] }.
Example: "What hostname does 8.8.8.8 reverse to?" -> reverse_dns(ip="8.8.8.8").
Errors: returns an error if the IP is invalid or has no PTR record.ip_geolocationGeolocate an IP address (country, region, city, coordinates, time zone) using the offline DB-IP Lite database, plus its reverse-DNS hostname. No external API.
Args:
- ip (string): IPv4 or IPv6 address.
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { ip, country_iso, country_name, region, city, latitude, longitude, time_zone, hostname }.
Example: "Where is 151.101.1.69 located?" -> ip_geolocation(ip="151.101.1.69").
Note: geolocation is approximate (city-level at best) and offline data may lag reality. The time zone is estimated from the coordinates.
Data: IP Geolocation by DB-IP (https://db-ip.com), licensed CC BY 4.0 — credit it when showing these results.ssl_certificateInspect the TLS certificate served by a host: issuer, subject, validity window, days-until-expiry, SANs, serial and SHA-256 fingerprint. Flags expired or soon-to-expire certificates.
Args:
- domain (string): host to connect to.
- port (number): TLS port (default 443).
- response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: certificate fields plus { days_until_expiry, expired, expires_soon, trusted, hostname_matches, authorization_error }. An untrusted certificate (self-signed, unknown root, wrong host) is still inspected and reported, never silently passed.
Example: "When does github.com's certificate expire?" -> ssl_certificate(domain="github.com").
Errors: returns an error if the host is unreachable or serves no certificate.whois_lookupLook up domain registration data over the raw WHOIS protocol (port 43): registrar, creation/update/expiry dates, name servers and domain status. Resolves the correct WHOIS server via IANA and follows registrar referrals. No API key.
Args:
- domain (string): the domain to look up.
- response_format ('markdown' | 'json'): output format (default 'markdown'). JSON includes the raw WHOIS text.
Returns: { domain, registrar, created, updated, expires, name_servers[], status[], whois_server }.
Example: "Who is the registrar for openai.com and when does it expire?" -> whois_lookup(domain="openai.com").
Errors: returns an error if no WHOIS server answers (some ccTLDs restrict or rate-limit WHOIS).dns_lookupLook up DNS records for a domain. Returns A, AAAA, MX, TXT, NS, CNAME, SOA, SRV, or PTR records.reverse_dnsPerform a reverse DNS (PTR) lookup on an IP address.resolve_allResolve all common DNS record types (A, AAAA, MX, TXT, NS, CNAME) for a domain in one call.check_nameserversGet the nameserver (NS) records for a domain.whoisQuery WHOIS data for a domain. Uses IANA and follows referrals to registrar WHOIS servers.Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"domain-security": {
"command": "npx",
"args": [
"-y",
"domain-security-mcp-server"
]
}
}
}
{
"mcpServers": {
"ofershap-mcp-server-dns": {
"command": "npx",
"args": [
"-y",
"mcp-server-dns"
]
}
}
}