Audit a domain's email and web security: SPF, DKIM, DMARC, MTA-STS, DNSSEC, TLS, WHOIS. No API keys.
Runs on your machine from its package; the steps are below.
At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
npx -y domain-security-mcp-server
MCP client config
{
"mcpServers": {
"domain-security": {
"command": "npx",
"args": [
"-y",
"domain-security-mcp-server"
]
}
}
}An MCP server that lets an AI agent audit the email and domain security of any domain — SPF, DKIM, DMARC, MTA-STS, TLS-RPT, BIMI, DNSSEC, DNS, TLS/SSL and WHOIS — in plain language. No API keys required.
Built on the v2 MCP SDK: the server speaks the 2026-07-28 protocol revision and keeps accepting 2025-era clients (Claude Desktop, Claude Code, Cursor) from the same factory — the era is negotiated per connection, so there is nothing to configure on either side.
Ask Claude "Is acme.com protected against email spoofing?" and it runs a full authentication audit and hands you a graded report with prioritised fixes — instead of you pasting a domain into five different web tools.
> Is ortamarco.me protected against email spoofing?
email_auth_audit(domain="ortamarco.me")
Grade: A (95/100) · MX: present
✅ SPF ends in '-all' (hard fail). 3/10 DNS lookups.
✅ DMARC policy is enforced ('p=reject').
✅ DKIM key found for selector: google.
Top recommendation: add a TLS-RPT record for delivery-failure reports.
The email-security ecosystem is full of single-purpose web checkers (SPF here, DMARC there, WHOIS somewhere else) and the few MCP equivalents are locked behind paid API tokens. This server brings the whole deliverability & domain-security toolkit to any MCP client, key-free, with one headline workflow tool that does the synthesis for you.
It is the agent-facing companion to the network tools at ortamarco.me and shares the same battle-tested core (public-resolver DNS, host validation, timeouts).
| Tool | What it does |
|---|---|
email_auth_audit ⭐ | One-call SPF + DKIM + DMARC + MX audit → 0–100 score, A–F grade, prioritised fixes |
spf_check | Parse SPF; recursively count DNS lookups vs the RFC 7208 limit of 10; flag +all/?all |
dmarc_check | Parse the DMARC record (every tag is returned) and flag a missing or invalid p, p=none, no rua and pct under 100 |
dkim_check | Probe <selector>._domainkey keys (supply selectors or use common ones) |
mta_sts_check | Validate the _mta-sts TXT and the .well-known/mta-sts.txt policy + mode |
tls_rpt_check | Check the _smtp._tls TLS-RPT record |
bimi_check | Check the default._bimi BIMI record |
dnssec_check | DS/DNSKEY presence + DNSSEC AD validation flag (via DoH) |
dns_lookup | All record types (A/AAAA/CNAME/MX/NS/TXT/SOA) via public resolvers |
ssl_certificate | TLS cert issuer, validity window, days-to-expiry, SANs, fingerprint |
whois_lookup | Registrar, dates, name servers, status (raw port-43 WHOIS, IANA-resolved) |
reverse_dns | PTR records for an IP |
ip_geolocation | Offline IP geolocation (DB-IP Lite) + reverse DNS |
mx_lookup | Mail servers (MX) with priority and resolved IPs |
caa_check | Which CAs may issue TLS certificates (CAA records) |
blacklist_check | IP/domain against open-access email DNSBLs |
dns_propagation | Compare a record across 5 public resolvers worldwide |
http_security_headers | Grade a site's HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy and COOP (an HSTS max-age=0 earns nothing) |
analyze_email_headers | Parse raw headers → SPF/DKIM/DMARC verdicts + Received hop chain with delays |
Every tool is read-only, declares an outputSchema and returns
structuredContent (validated by the SDK) alongside human-readable Markdown
(default) or JSON (response_format="json"), plus actionable error messages.
Requires Node.js 20.18+. Nothing to clone — every MCP client can run it with npx.
claude mcp add domain-security -- npx -y domain-security-mcp-server
Add to claude_desktop_config.json (or ~/.cursor/mcp.json) — see examples/:
{
"mcpServers": {
"domain-security": {
"command": "npx",
"args": ["-y", "domain-security-mcp-server"]
}
}
}
On Windows use "command": "cmd" with "args": ["/c", "npx", "-y", "domain-security-mcp-server"].
Restart the client, then ask: "Audit the email security of stripe.com."
The same server speaks stateless Streamable HTTP for remote or multi-client
use. One endpoint serves both protocol eras and there is no session state, so no
Mcp-Session-Id header is issued or expected.
TRANSPORT=http npx -y domain-security-mcp-server
# POST JSON-RPC to http://127.0.0.1:3000/mcp · health at /healthz
It is safe by default: it binds to 127.0.0.1 and only accepts localhost
Host and Origin headers, which blocks DNS-rebinding attacks from a web page.
To expose it — for example behind Coolify or Traefik — opt in explicitly:
| Variable | Default | Purpose |
|---|---|---|
TRANSPORT | stdio | http to serve Streamable HTTP |
PORT | 3000 | Listening port |
HOST | 127.0.0.1 | Bind address; 0.0.0.0 to accept remote connections |
ALLOWED_HOSTS | — | Comma-separated hostnames the Host header may carry (e.g. mcp.example.com) |
ALLOWED_ORIGINS | — | Comma-separated origins allowed to call from a browser |
MCP_AUTH_TOKEN | — | If set, every request needs Authorization: Bearer <token> |
Binding to a non-loopback address without ALLOWED_HOSTS or MCP_AUTH_TOKEN
works, but the server says so on stderr. With Docker (the image sets HOST=0.0.0.0):
docker build -t domain-security-mcp .
docker run -p 3000:3000 -e ALLOWED_HOSTS=mcp.example.com -e MCP_AUTH_TOKEN=change-me domain-security-mcp
The tools reach out to hosts that the caller names, so every outbound connection is screened against server-side request forgery:
[::ffff:169.254.169.254]).Found a problem? Please open a private security advisory.
npm run dev # tsx watch (stdio)
npm run inspect # open the MCP Inspector against the built server
npm run build # type-check + emit dist/
npm run typecheck # type-check only
npm test # offline unit tests: SSRF guard, SPF/DMARC/DKIM scoring,
# header parsing, HTTP transport defaults
npm run smoke # call all 19 tools on BOTH protocol eras and validate
# structuredContent against each tool's outputSchema
evals/ holds a 10-question LLM evaluation set (stable, verifiable)
and instructions for running it — see evals/README.md.
src/
├── index.ts # transport selection (stdio | http), v2 SDK entry points
├── server.ts # factory: registers every tool on one McpServer
├── core/ # pure logic, no MCP coupling — reusable & testable
│ ├── validate.ts # input validation and the address classifier
│ ├── netguard.ts # connect-time SSRF guard, redirect-safe fetch, capped bodies
│ ├── dns.ts # public-resolver DNS + DoH client
│ ├── net.ts # MX, CAA, DNSBL and propagation checks
│ ├── tls.ts # certificate inspection and trust
│ ├── whois.ts # port-43 WHOIS with IANA/registrar referral
│ ├── http.ts # security-header grading
│ ├── geoip.ts # offline IP geolocation on DB-IP Lite (each file read on first use)
│ ├── email-headers.ts # raw header parsing and hop timing
│ └── email-auth.ts # SPF/DKIM/DMARC/MTA-STS/TLS-RPT/BIMI/DNSSEC + scoring
└── tools/ # thin MCP wrappers (Zod schemas, descriptions, formatting)
The core/ layer is deliberately free of any MCP types, so the exact same logic
powers both this server and the web tools on ortamarco.me.
IP Geolocation by DB-IP. ip_geolocation uses the
free DB-IP "IP to City Lite" database, licensed under
CC BY 4.0 and installed as the
@ip-location-db/dbip-city-mmdb
package; the credit also appears in the tool's description and Markdown output. The
database has no time zone, so time_zone is estimated from the coordinates with
@photostructure/tz-lookup (CC0).
MIT © Marco Orta