<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rosco</title>
    <description>The latest articles on DEV Community by Rosco (@rosconl).</description>
    <link>https://dev.to/rosconl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3954226%2Fb0af5afa-5b2f-461f-be17-c53037348500.jpeg</url>
      <title>DEV Community: Rosco</title>
      <link>https://dev.to/rosconl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rosconl"/>
    <language>en</language>
    <item>
      <title>I built an MCP server for DNS + email security — 37 tools for Claude Code, Cursor, Windsurf</title>
      <dc:creator>Rosco</dc:creator>
      <pubDate>Wed, 27 May 2026 11:36:56 +0000</pubDate>
      <link>https://dev.to/rosconl/i-built-an-mcp-server-for-dns-email-security-37-tools-for-claude-code-cursor-windsurf-13mb</link>
      <guid>https://dev.to/rosconl/i-built-an-mcp-server-for-dns-email-security-37-tools-for-claude-code-cursor-windsurf-13mb</guid>
      <description>&lt;p&gt;The first time &lt;code&gt;intodns-mcp&lt;/code&gt; saved me real time was on day one. Claude scanned a client's domain, listed seven concrete issues with citations to the live records, and proposed exact zone-file edits — in under three seconds. Before MCP, that conversation was three browser tabs, two &lt;code&gt;dig&lt;/code&gt; sessions, and a lot of squinting at numeric DKIM key tags.&lt;/p&gt;

&lt;p&gt;The reason it worked: Claude wasn't guessing.&lt;/p&gt;

&lt;p&gt;Email-auth and DNS are exactly the kind of domain where LLMs hallucinate the worst — small surface area, sharp answers, no room for "approximately correct". Ask any frontier model to check whether &lt;code&gt;example.com&lt;/code&gt; has DNSSEC and a fair share of the time it cheerfully invents a key tag. Ask it whether your SPF blows the 10-lookup limit and it'll quote the rule from memory but skip counting your actual includes.&lt;/p&gt;

&lt;p&gt;There is no fix-by-prompt for this. The model has to &lt;em&gt;look&lt;/em&gt;. So I built &lt;a href="https://github.com/RoscoNL/intodns-mcp-server" rel="noopener noreferrer"&gt;&lt;code&gt;intodns-mcp&lt;/code&gt;&lt;/a&gt; — a Model Context Protocol server that exposes 37 deterministic tools backed by &lt;a href="https://intodns.ai" rel="noopener noreferrer"&gt;IntoDNS.ai&lt;/a&gt;'s free public API. The model doesn't remember. It calls &lt;code&gt;check_dmarc&lt;/code&gt;, gets the live record, gets the policy interpretation, gets the citation URL, and writes an answer grounded in what your DNS actually says today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; intodns-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Claude Code, add to &lt;code&gt;~/.claude.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"intodns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"intodns-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same shape works for Cursor, Windsurf, Zed, Continue, OpenClaw — anything that speaks MCP stdio. No API key. Live in ten seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in the box
&lt;/h2&gt;

&lt;p&gt;37 tools across four buckets:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS layer&lt;/strong&gt; — &lt;code&gt;lookup_dns&lt;/code&gt;, &lt;code&gt;validate_dnssec&lt;/code&gt;, &lt;code&gt;check_dns_propagation&lt;/code&gt;, &lt;code&gt;check_tlsa_dane&lt;/code&gt;, &lt;code&gt;check_http3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email authentication&lt;/strong&gt; — &lt;code&gt;check_spf&lt;/code&gt;, &lt;code&gt;discover_dkim&lt;/code&gt;, &lt;code&gt;check_dmarc&lt;/code&gt;, &lt;code&gt;check_bimi&lt;/code&gt;, &lt;code&gt;check_mta_sts&lt;/code&gt;, &lt;code&gt;check_smtp_tls&lt;/code&gt;, &lt;code&gt;check_fcrdns&lt;/code&gt;, &lt;code&gt;check_blacklist&lt;/code&gt;, &lt;code&gt;check_sender_requirements&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holistic scan + reports&lt;/strong&gt; — &lt;code&gt;scan_domain&lt;/code&gt;, &lt;code&gt;get_everything_report&lt;/code&gt;, &lt;code&gt;create_report_snapshot&lt;/code&gt;, &lt;code&gt;run_public_scan&lt;/code&gt;, &lt;code&gt;start_deep_scan&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance&lt;/strong&gt; — &lt;code&gt;nis2_quickscan&lt;/code&gt;, which is the one I'm most pleased with: it maps every observable DNS/mail-auth/TLS signal onto NIS2 Article 21.2's ten cyber-hygiene measures (a–j) and returns a weighted 0–100 score with per-measure evidence and concrete fix suggestions. For EU teams staring down the NIS2 enforcement deadline, this turns "are we compliant?" into a checkable artifact instead of a panel discussion.&lt;/p&gt;

&lt;p&gt;The full tool list is in the README.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real session
&lt;/h2&gt;

&lt;p&gt;Asking Claude to audit &lt;code&gt;example.com&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; /mcp__intodns__scan_domain example.com

Grade: D
Score: 42/100

Issues:
- spf_missing
- dmarc_missing
- no_dnssec
- no_caa

Recommendations:
- Publish SPF record (start with: v=spf1 -all)
- Add DMARC policy (start at p=none, sp=none, ruf=…)
- Enable DNSSEC at registrar
- Publish CAA records to restrict CA issuance

Citations:
- https://intodns.ai/scan/example.com
- https://intodns.ai/learn/spf
- …
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model now reasons over a real result instead of fictional RFCs. Combine &lt;code&gt;scan_domain&lt;/code&gt; with &lt;code&gt;generate_dns_fix&lt;/code&gt; and you can ask "what's broken and how do I fix it?" and get an answer that references actual records, not the kind of confident-sounding plausible advice that makes incident reviews miserable.&lt;/p&gt;

&lt;h2&gt;
  
  
  NIS2 quickscan, briefly
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;nis2_quickscan&lt;/code&gt; is the differentiator. Article 21.2 lists ten technical and organisational measures every essential and important entity has to implement. DNS/email is only one layer, but it's the layer that's &lt;em&gt;observable from outside&lt;/em&gt; — any auditor with a resolver can grade it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; /mcp__intodns__nis2_quickscan example.eu

NIS2 21.2 Readiness: 64/100

Per-measure status:
  a (risk policy)         — n/a (organisational)
  b (incident handling)   — n/a (organisational)
  c (business continuity) — n/a (organisational)
  d (supply chain)        — partial: 3rd-party mail provider observed
  e (acquisition/dev)     — n/a (process)
  f (effectiveness assess)— evidence: weak (no DMARC reports collected)
  g (basic cyber hygiene) — strong: SPF + DMARC enforced
  h (cryptography)        — strong: TLS 1.3, MTA-STS enforce
  i (HR security)         — n/a
  j (auth, MFA, …)        — partial: DNSSEC missing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real compliance still needs the full audit (organisational measures, supply chain, training, incident response). But for the DNS/email layer, the model now has a concrete, citable answer — which is the part that previously took a security consultant two hours of dig commands to produce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP, not "just call the API"
&lt;/h2&gt;

&lt;p&gt;You could absolutely just &lt;code&gt;curl&lt;/code&gt; the IntoDNS API. But once the model has the tools wired through MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent picks the &lt;em&gt;right&lt;/em&gt; tool for the question without you scripting it&lt;/li&gt;
&lt;li&gt;Tool descriptions feed into the model's reasoning — it learns when &lt;code&gt;check_mta_sts&lt;/code&gt; is the right call vs &lt;code&gt;check_smtp_tls&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Citation URLs come back with the data, so the model writes answers with links instead of vibes&lt;/li&gt;
&lt;li&gt;Same server works in your editor, your terminal, your remote agent — install once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the bet of MCP in general, and DNS/email security turns out to be a near-perfect fit: deterministic backend, structured answers, well-bounded tool surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the catch
&lt;/h2&gt;

&lt;p&gt;Honestly, the catch is the same as every backend-tools-over-MCP design: your agent only knows what your backend knows. IntoDNS.ai scans from one vantage point, so propagation tests are best-effort, not authoritative across every recursive resolver on Earth. For deep-scan cases (CDN edge issues, GeoDNS) you'll still want to combine with something like RIPE Atlas.&lt;/p&gt;

&lt;p&gt;Everything else — SPF/DKIM/DMARC parsing, DNSSEC validation, MTA-STS, NIS2 mapping — is deterministic and reproducible. Citation-grade report snapshots are content-hashed so the same scan referenced in a ticket six months from now still resolves to the same evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Server: &lt;a href="https://github.com/RoscoNL/intodns-mcp-server" rel="noopener noreferrer"&gt;github.com/RoscoNL/intodns-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/intodns-mcp" rel="noopener noreferrer"&gt;intodns-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live install snippets for every MCP client: &lt;a href="https://intodns.ai/mcp" rel="noopener noreferrer"&gt;intodns.ai/mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Free public API (same backend): &lt;a href="https://intodns.ai/api" rel="noopener noreferrer"&gt;intodns.ai/api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NIS2 quickscan in browser: &lt;a href="https://intodns.ai/nis2" rel="noopener noreferrer"&gt;intodns.ai/nis2&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built by &lt;a href="https://intodns.ai" rel="noopener noreferrer"&gt;Cobytes&lt;/a&gt; — a Dutch webhosting anf security focussed company. MIT-licensed. PRs welcome.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>claude</category>
      <category>dns</category>
    </item>
  </channel>
</rss>
