MCP Hub
Back to servers

DNS MCP Server

Real-time DNS security analysis — DNSSEC, email auth, and RDAP. Built for SOC investigations.

Registry
Stars
1
Updated
Mar 4, 2026
Validated
Apr 22, 2026

DNS MCP Server

Real-time DNS security analysis for AI assistants via MCP. Gives your assistant the ability to investigate domains the way a practitioner would — DNSSEC chain validation, email authentication posture, and registration intelligence — without leaving your chat session.

Built by a cybersecurity professional for SOC investigation workflows. Not a toy — the same queries you'd run at the command line, accessible through any MCP-compatible assistant in real time.

Tools

DNS Tools

ToolDescription
dns_queryStandard DNS lookups (A, AAAA, MX, TXT, NS, SOA, CNAME, PTR, SRV)
dns_dig_styleDetailed dig-style output with DNSSEC flags (DO flag set)
dns_dnssec_validateChain-of-trust validation like delv +vtrace
nsec_infoNSEC/NSEC3 denial-of-existence analysis and zone walkability assessment
reverse_dnsPTR record lookups for IP addresses
timestamp_converterConvert between ISO, epoch, and human-readable timestamps
detect_hijackingTest a resolver for DNS hijacking/tampering (NXDOMAIN probe, known record, DNSSEC, identity)

Email Security Tools

ToolDescription
check_spfSPF record parsing with recursive include resolution (RFC 7208 10-lookup limit)
check_dmarcDMARC policy retrieval with organizational domain fallback
check_dkim_selectorDKIM public key record verification for a selector+domain pair
check_bimiBIMI record and VMC (Verified Mark Certificate) check
check_mta_stsMTA-STS DNS record + HTTPS policy file fetch (mode, MX patterns, max_age)
check_smtp_tlsrptSMTP TLS Reporting record check
check_daneDANE TLSA record check with DNSSEC validation for a domain's MX hosts
check_tlsaStandalone TLSA record lookup for any hostname, port, and protocol
rdap_lookupDomain registration data via RDAP (modern WHOIS replacement)

Utility

ToolDescription
pingHealth check — returns pong with timestamp
server_infoShow resolver config: dnspython version, nameservers, EDNS settings
quineReturns the source code of this server

Analyst Prompts

The server ships with three analyst prompt templates. Any MCP-compatible client can list and invoke them — no Claude-specific configuration required.

PromptWhat it does
email_security_auditDomain email security audit: SPF, DKIM, DMARC, MTA-STS, BIMI — graded A through F with prioritized recommendations
dnssec_chain_auditFull DNSSEC chain-of-trust audit from the IANA root trust anchor down to the target domain
soc_email_forensicsForensic phishing analysis of a raw email (.eml or pasted headers) — returns TRUSTABLE / SUSPICIOUS / PHISHING / FURTHER ANALYSIS REQUIRED

Prompts set the analyst context and tool-use strategy for the session. The LLM runs the appropriate tools in sequence and synthesizes a structured report.

Client support note: MCP prompt invocation requires client-side UI support. Claude Code CLI supports prompts via slash commands (see Quick Start §4). Claude Desktop currently exposes MCP tools only — prompts are registered but not reachable from the UI. Use tools ad-hoc in Desktop, or describe the analysis you want and the model will apply the same workflow.

Example

Ask your assistant: "Check the email security posture of deflationhollow.net"

The assistant calls check_spf, check_dmarc, check_dane, check_mta_sts, and check_bimi in sequence and returns a complete analysis:

✅ SPF: Hard fail (-all), delegated to ForwardEmail, 5 lookups (under RFC limit)
✅ DMARC: p=reject, pct=100 — full enforcement, aggregate reporting configured
⚠️  DANE: TLSA records present but unverifiable — DNSSEC not enabled on zone
⚠️  MTA-STS: Not configured — no TLS enforcement policy published  
⚠️  BIMI: Not configured

Overall: B+ — Strong fundamentals, three actionable gaps identified.

No copy-pasting dig commands. No tab-switching. One question.

Quick Start

Prerequisites

  • Docker

1. Build

git clone https://github.com/mclose/dns-mcp.git
cd dns-mcp
make build

2. Connect

Any MCP client that supports stdio transport works. The server config block is the same across all clients — see Client Support for client-specific setup instructions and config file locations.

The --dns 9.9.9.9 flag ensures DNSSEC-correct resolution regardless of the host's DNS configuration.

3. Verify

make test                  # unit tests inside container
./test-mcp-stdio.sh        # end-to-end stdio test

4. Start an analysis

Once connected, just ask:

"Check the email security posture of deflationhollow.net" "Audit the DNSSEC chain for dnssec.works" "Is this email headers trustworthy?" (paste raw headers)

Clients that support MCP prompts can also invoke the structured analyst workflows directly — see Client Support for details.

Client Support

All clients use the same server block. The command and args are identical everywhere — only the config file location and prompt invocation differ.

{
  "mcpServers": {
    "dns-mcp": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "--dns", "9.9.9.9", "dns-mcp", "python", "server.py"]
    }
  }
}

Claude Desktop

Prompts: Not supported — Desktop exposes MCP tools only. Use ad-hoc questions.

Config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Claude Code CLI

Prompts: Full support via / slash commands.

Add the server with one command (adds to local project config):

claude mcp add dns-mcp -- docker run --rm -i --dns 9.9.9.9 dns-mcp python server.py

Or add --scope user to make it available across all projects. Invoke prompts by typing / in the chat — the three analyst prompts appear as:

/mcp__dns-mcp__email_security_audit
/mcp__dns-mcp__dnssec_chain_audit
/mcp__dns-mcp__soc_email_forensics

Type /mcp__dns-mcp__ and tab-complete to see all three.

Gemini CLI

Prompts: Supported (Gemini CLI implements the full MCP spec).

Add the server with one command:

gemini mcp add dns-mcp -- docker run --rm -i --dns 9.9.9.9 dns-mcp python server.py

Or add manually to ~/.gemini/settings.json (user scope) or .gemini/settings.json (project scope) using the same JSON block above.

Cursor

Prompts: Verify with your installed version — Cursor MCP support is active and evolving. Config location: consult Cursor MCP docs.

Add the JSON block above to your Cursor MCP config file.

VS Code (GitHub Copilot / Continue / Cline)

Prompts: Depends on the extension — check extension documentation.

Config location varies by extension. The JSON block above is the standard stdio format; consult your extension's MCP setup guide for the exact file path.

Zed

Prompts: Check current Zed release notes — MCP support is active. Config location: consult Zed MCP docs.

Windsurf

Prompts: Check current Windsurf release notes. Config location: consult Windsurf MCP documentation.


Note on prompt support: MCP prompts require explicit client-side UI (a slash command picker or equivalent). Not all clients have implemented this yet. When prompts aren't available, ask ad-hoc — the tools work the same way and the model applies the same workflow.

Architecture

MCP Client (e.g. Claude Desktop)
  |
  | (spawns per-session)
  v
docker run --rm -i dns-mcp python server.py
  |
  | stdin/stdout (MCP stdio transport)
  v
FastMCP server (server.py)
  |  - All 19 tools
  |  - dnspython for DNS queries
  |  - requests for RDAP only

No network ports. No auth tokens. No proxy. The MCP client manages the container lifecycle — one container per session, cleaned up on exit.

Day-to-Day

CommandWhat it does
make buildBuild the Docker image (uses layer cache)
make rebuildFull clean build, no cache — use when something feels off
make testRun unit tests inside the container
make shellInteractive shell inside the container
./test-mcp-stdio.shEnd-to-end stdio protocol test

Testing

Unit tests — tool logic, input validation, error handling:

make test    # runs pytest inside container

End-to-end stdio — full MCP protocol over stdin/stdout:

./test-mcp-stdio.sh

Security

  • No shell execution — all DNS via dnspython, RDAP via requests
  • Strict domain validation (regex allowlist)
  • IP address validation (ipaddress module)
  • Query type allowlist
  • Non-root container user (claude, uid 1000)
  • SPF recursion limit enforced (RFC 7208)
  • RDAP: input validated before HTTP request, 10s timeout, max 3 redirects

File Structure

dns-mcp/
├── server.py              # FastMCP server (19 tools, stdio transport)
├── Dockerfile             # Single-stage Alpine image
├── docker-compose.yml     # Build target
├── Makefile               # build/test/shell
├── requirements.txt       # Python dependencies
├── test-mcp-stdio.sh      # End-to-end stdio test
└── tests/
    └── test_tools.py      # pytest unit tests

Contributing

pip install pre-commit
pre-commit install

That's it. On every commit, ruff will lint and auto-fix staged Python files. The full test suite (pytest + stdio e2e) runs in CI on every push and pull request.

Remote / HTTP Transport

The remote branch contains the HTTP Streamable transport version of this server, including a Flask auth proxy sidecar, bearer token authentication, fail2ban integration, and instructions for exposing the server via an HTTPS reverse proxy. See that branch if you need network-accessible deployment.

License

MIT

Reviews

No reviews yet

Sign in to write a review