# IntoDNS.ai DNS & Email Security Scanner (remote · intodns.ai)

DNS and email security: check SPF, DKIM, DMARC, DNSSEC, DANE and build the records. 45 tools.

- Trust score: 86/100 (high trust)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-20

## Components

- remote · `intodns.ai`: 86/100 (this document), [markdown](https://verifymcp.io/servers/ai-intodns-scanner/api-mcp.md), [page](https://verifymcp.io/servers/ai-intodns-scanner/api-mcp)
- npm · `intodns-mcp`: 93/100, [markdown](https://verifymcp.io/servers/ai-intodns-scanner/intodns-mcp.md), [page](https://verifymcp.io/servers/ai-intodns-scanner/intodns-mcp)

## Channel facts

- Endpoint: `https://intodns.ai/api/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.10.3`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-20.

- **Endpoint Security**: 80/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 70/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 7897 tokens (~175/item across 45 items; 45 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 100/100
  - No destabilizing schema changes in the last 30 days.
- **Tool Coverage**: 98/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 94% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 45 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 45 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the IntoDNS.ai DNS & Email Security Scanner MCP server?

IntoDNS.ai DNS & Email Security Scanner is a hosted endpoint at https://intodns.ai/api/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http ai-intodns-scanner 'https://intodns.ai/api/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "ai-intodns-scanner": {
      "url": "https://intodns.ai/api/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "ai-intodns-scanner": {
      "type": "http",
      "url": "https://intodns.ai/api/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.ai-intodns-scanner]
url = "https://intodns.ai/api/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ai-intodns-scanner": {
      "type": "remote",
      "url": "https://intodns.ai/api/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ai-intodns-scanner --url 'https://intodns.ai/api/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  ai-intodns-scanner:
    url: "https://intodns.ai/api/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "ai-intodns-scanner": {
      "Transport": "http",
      "Url": "https://intodns.ai/api/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add ai-intodns-scanner -t streamable-http -u 'https://intodns.ai/api/mcp'
```

### Other

```json
{
  "mcpServers": {
    "ai-intodns-scanner": {
      "type": "http",
      "url": "https://intodns.ai/api/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-20 (score 86, 0)

- [security] Stability: 0.97 → pass

### 2026-09-19 (score 86, +1)

No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-16 (score 85, +1)

No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-14 (score 84, +1)

No change was recorded against any check on this day. Stability & Change Management went from 77 to 80. That category is still filling its 30-day observation window: 23 days of observed history at the previous scan, 24 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-12 (score 83, +1)

No change was recorded against any check on this day. Stability & Change Management went from 70 to 73. That category is still filling its 30-day observation window: 21 days of observed history at the previous scan, 22 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-10 (score 82, +1)

No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-08 (score 81, +1)

No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-07 (score 80, +7)

- [security improvement] Authorization: fail → partial
- [security] Tool “cancel_deep_scan” rewrote its description, which is the text the model reads
- [security] Tool “cancel_deep_scan” no longer declares itself destructive
- [functional] Server version: 1.10.2 → 1.10.3

## MCP tools (45)

### `scan_domain` (~157 tokens)

Run the fast IntoDNS.ai DNS and email security scan (~3-8s). Returns a letter grade A+ to F, numeric score 0-100, structured issue list, prioritised recommendations, full DNS/email/web/security result sections, and canonical citation URLs. Read-only — no domain mutation, no destructive side effects. The default tool for agent-visible scan evidence; use get_everything_report for a deeper single-shot report including web/blacklist/sender data, or start_deep_scan for slower Internet.nl-grade analysis. After running, use explain_issue or generate_dns_fix on any returned issue. No auth.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `nis2_quickscan` (~193 tokens)

Compute a NIS2 Article 21.2 readiness score for a domain by mapping the IntoDNS quickscan onto the ten NIS2 measures. Returns a 0-100 weighted total, per-measure status (Article 21.2 a-j), evidence rows, critical gaps, and concrete fix suggestions. The score reflects only the DNS and email layer of NIS2 — full NIS2 compliance also requires audit of web applications, supply chain, organisational processes, and training. Use when the user asks about NIS2 compliance, NIS2 readiness, NIS2 Article 21.2, cyber-hygiene compliance, or related EU-NIS regulation checks for a domain.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `lang` (string): Language for the standard caveat text shown alongside the score.

### `get_everything_report` (~152 tokens)

Generate the complete live IntoDNS.ai report covering DNS, email authentication, web/HTTPS, blacklist reputation, sender requirements, and canonical citation URLs in a single call. Read-only, no domain mutation. ~5-15s latency depending on backend cache state. Use when the user asks for everything, the full picture, or a deep current-state summary; use scan_domain for a faster default scan, or create_report_snapshot when the result must remain immutable for audit/ticket use. No auth, no side effects.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `format` (string): Return JSON data or LLM-ready Markdown

### `create_report_snapshot` (~174 tokens)

Create an immutable evidence snapshot of the current Everything Report for a domain. Returns a snapshot ID, ISO timestamp, SHA-256 content hash, and stable bookmarkable URLs for both JSON and Markdown renderings of the report. Snapshots are write-once and resolve to the same evidence months/years later — useful for tickets, audit trails, NIS2/ISO compliance evidence, and LLM citations that should not drift. A canonical POST creates one snapshot per call (additive and not idempotent); use get_report_snapshot to read it back. Use this instead of get_everything_report when the result must remain stable.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `format` (string): Return the created snapshot as JSON or Markdown

### `get_report_snapshot` (~130 tokens)

Read a previously created IntoDNS.ai Everything Report evidence snapshot by snapshot ID. Read-only GET — returns the immutable JSON report exactly as it was at snapshot creation, with the original SHA-256 content hash and timestamp. Requires `snapshotId` from create_report_snapshot. Use to verify or re-read an audit-trail evidence record without re-running a live scan; use get_everything_report for current live data instead. No auth, fully idempotent.

Input parameters:

- `format` (string): Return JSON data or LLM-ready Markdown
- `snapshotId` (string, required): Snapshot ID returned by create_report_snapshot

### `start_deep_scan` (~180 tokens)

Start a long-running Internet.nl deep scan (typically 30-120s). Returns a `scanId` immediately; poll get_deep_scan_status until status='finished'. Read-only — no domain mutation. Internet.nl runs an exhaustive standards-compliance audit (IPv6, DNSSEC, modern TLS, RPKI, mail authentication) used by EU governments. Use when scan_domain output is not strict enough for compliance reporting, or when the user asks for an Internet.nl-grade audit. For sub-10s answers, use scan_domain. To abort an in-progress scan, call cancel_deep_scan. No auth.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `name` (string): Optional display name
- `scanType` (string): Deep scan type

### `get_deep_scan_status` (~110 tokens)

Read-only status poll for a long-running Internet.nl deep scan. Returns scan progress (pending/running/finished), category scores, per-test results, and any failures. Requires a scanId returned by start_deep_scan; poll every 10-30s until status='finished'. Use after start_deep_scan; for fast single-vantage scans, prefer scan_domain. No auth, no side effects.

Input parameters:

- `scanId` (string, required): Deep scan ID returned by start_deep_scan

### `cancel_deep_scan` (~130 tokens)

Cancel an in-progress Internet.nl deep scan. Marks the scan cancelled; the polling loop then withdraws the upstream Internet.nl batch, usually within ten seconds. Requires `scanId` returned by start_deep_scan. Nothing is deleted: a scan that already finished keeps its results and is left alone, so calling this twice is safe. An unknown or expired scanId returns 404. Use when the user changes their mind mid-scan or when polling get_deep_scan_status would otherwise time out. No auth.

Input parameters:

- `scanId` (string, required): Deep scan ID returned by start_deep_scan

### `lookup_dns` (~145 tokens)

Read-only DNS record lookup via DNS-over-HTTPS. Pass `type` for a single record type or `types` for an array; if both omitted, returns A records. Returns parsed answers with TTL, raw rdata, and DNSSEC AD bit. Use for arbitrary record queries; use validate_dnssec for full DNSSEC chain validation, or check_dns_propagation for multi-resolver consensus. No auth, no rate limits beyond upstream resolver.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `type` (string): Single DNS record type
- `types` (array): Multiple DNS record types

### `validate_dnssec` (~116 tokens)

Read-only DNSSEC chain validation. Walks the DS/DNSKEY chain from root, checks signatures, algorithm strength, key rollover state, and reports any broken links or unsigned zones. Returns chain steps, algorithm grades, and a boolean `valid`. Use when a domain claims DNSSEC; use lookup_dns(type='DNSKEY') for raw key data only. Single HTTP GET, no auth, no destructive actions.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_dns_propagation` (~145 tokens)

Compare DNS responses across the nine currently configured public and authoritative resolvers to detect propagation lag, missing answers, or inconsistent TTL/data values. Defaults to record type A and region 'all'. Returns every resolver response plus a propagation percentage and explicit inconsistency list. Use when records were just changed and you suspect staleness; for a single DNS-over-HTTPS lookup use lookup_dns instead. Read-only HTTP, no auth, and no destructive actions.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `region` (string): Resolver region
- `type` (string): DNS record type to check

### `check_tlsa_dane` (~174 tokens)

Read-only TLSA/DANE DNS record check. With no port, resolves MX hosts and validates their `_25._tcp` TLSA tuple syntax; with an explicit port, queries `_<port>._<protocol>.<domain>`. Returns parsed usage, selector, matching type, certificate data, syntax errors, and best-practice advisories. It does not fetch or cryptographically match the live service certificate, so pair it with check_smtp_tls for SMTP certificate evidence. Use before publishing DANE records or troubleshooting DANE handover. No auth or destructive actions.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `port` (integer): Port to check, defaults to 25
- `protocol` (string): Transport protocol

### `check_spf` (~148 tokens)

Read-only SPF parse and validation for a domain. Recursively walks include/redirect mechanisms to build the full lookup graph, counts DNS lookups against the RFC-7208 10-lookup limit, and returns flattening guidance when the count is close to or over the limit. Returns parsed mechanisms, lookup graph, total count, qualifier (~all / -all / +all), and warnings. Use for SPF auditing or before adding new include: senders; use check_email_security for the broader SPF+DKIM+DMARC overview. No auth, no side effects.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `flatten_spf` (~188 tokens)

Read-only SPF flattening for a domain. Resolves the full include/a/mx/redirect graph to literal ip4/ip6 addresses and returns a single flattened SPF record that fits under the RFC-7208 10-lookup limit, plus lookup counts before/after, IP count, record length, whether it must be split across multiple records, and a maintenance warning. Use when a domain hits 'too many DNS lookups' (PermError) and removing unused includes is not enough; run check_spf first to see the lookup graph and whether flattening is actually needed. Flattened records are high-maintenance — they break when a provider rotates IPs — so treat the output as a last resort to re-verify periodically. No auth, no side effects.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `discover_dkim` (~164 tokens)

Read-only DKIM check for a domain. Without `selector`, heuristically queries 50 common selectors and explicitly reports that a miss is inconclusive because DKIM has no enumeration protocol. With `selector`, performs one authoritative exact lookup for a selector obtained from a DKIM-Signature header or mail provider. Returns discovery method, coverage note, parsed key tags, public-key strength, and warnings. Use exact mode whenever the selector is known; use check_email_security for the broader SPF/DKIM/DMARC overview. No auth or destructive actions.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `selector` (string): Optional exact DKIM selector, e.g. selector1 or google

### `check_dmarc` (~134 tokens)

Read-only fetch and parse of the _dmarc TXT record. Returns parsed tag map (p, sp, rua, ruf, adkim, aspf, pct, fo), policy strength assessment, alignment mode, and warnings (missing rua, p=none, weak alignment, multiple records). Use for DMARC policy review; use check_sender_requirements for combined Google/Yahoo SPF+DKIM+DMARC pass/fail verdict. Single GET, no auth, no side effects.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_bimi` (~149 tokens)

Read-only BIMI readiness check. Parses the `default._bimi` TXT record, safely fetches the referenced HTTPS SVG, and parses basic metadata from an optional VMC/CMC authority certificate. Returns record syntax, URL reachability/content type, certificate subject/issuer/validity dates, and explicit issues. It does not certify SVG Tiny PS profile compliance, validate the full mark-certificate trust chain, verify trademark ownership, or guarantee logo display by any mailbox provider. Use for a technical preflight before a formal BIMI/VMC review. No auth or destructive actions.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_mta_sts` (~141 tokens)

Read-only check of MTA-STS: TXT record at _mta-sts.<domain> plus the HTTPS policy file at mta-sts.<domain>/.well-known/mta-sts.txt. Returns parsed policy (mode: enforce/testing/none, mx allowlist, max_age), TLS certificate validity for the policy host, and consistency warnings between DNS and HTTPS. Use to verify enforced TLS for inbound mail; pair with check_smtp_tls for live STARTTLS validation. No auth, DNS + HTTPS GET only.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_smtp_tls` (~154 tokens)

Live check of every MX host: opens TCP 25, runs EHLO + STARTTLS, validates TLS certificate trust chain, hostname match, expiry window, advertised EHLO capabilities, plus PTR and forward-confirmed reverse DNS. Read-only — connects and quits without sending mail. Returns per-MX cipher/version, cert SANs, expiry days, FCrDNS verdict, and STARTTLS-required flag. Use to verify inbound mail TLS posture; pair with check_mta_sts for the policy layer. May be slower (10-30s) due to live SMTP handshakes. No auth.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_fcrdns` (~149 tokens)

Read-only FCrDNS (Forward-Confirmed Reverse DNS) audit for every IP that backs the domain's MX records. For each IP: looks up PTR record, then resolves that PTR's hostname back to A/AAAA records to confirm the round-trip. Returns per-IP PTR value, forward-resolution result, match verdict, and warnings (missing PTR, mismatched forward, generic ISP reverse). Use for mail deliverability audits, SpamExperts-style cluster checks, and any 'why is our mail being rejected' debugging; pair with check_blacklist for reputation signals. No auth.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_blacklist` (~155 tokens)

Read-only query against the currently configured public DNSBL/RBL providers (roughly 60, with noisy providers explicitly disabled). Provide either `domain` to resolve and inspect its MX IPv4 addresses or an IPv4 `ip` for a direct check; at least one is required. Returns each provider's listed/clean result, severity, removal metadata, plus unavailable and disabled provider evidence so timeouts are not misreported as clean. Use for mail-server reputation triage; it is not a delisting service. No auth or destructive actions.

Input parameters:

- `domain` (string): Domain name only, e.g. example.com (no URL, path, or port)
- `ip` (string): IPv4 address to check directly

### `check_sender_requirements` (~150 tokens)

Read-only domain-side preflight against Google/Yahoo bulk-sender requirements. Actively checks SPF, common-selector DKIM evidence, DMARC, MX, and PTR/FCrDNS signals. TLS use, one-click unsubscribe, complaint rate, and From-header behavior require a real sent message/provider telemetry and are returned as informational follow-up items, not false passes. Returns per-requirement pass/fail/warning/info plus an explicitly limited readiness summary. Use before a campaign; use analyze_raw_email or create_email_test to verify message-level requirements. Single GET, no auth.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `check_email_security` (~147 tokens)

Read-only combined email-security check covering SPF parse, DKIM selector discovery, DMARC policy validation, MX IP blacklist status across major feeds, and an aggregated 0-100 email-security score with prioritised issue list. Single call replaces sequential check_spf + discover_dkim + check_dmarc + check_blacklist for the typical case. Use for one-shot email security overview; use check_sender_requirements specifically for Google/Yahoo bulk-sender compliance, or the individual check_* tools when you need only one signal. No auth, ~3-8s.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `create_email_test` (~130 tokens)

Create a new IntoDNS.ai inbound email-test session. Returns a unique single-use test email address (valid 60 minutes) and a `testId` used by get_email_test or poll_email_test. This is an additive, non-idempotent POST: every call creates a fresh session but never modifies prior sessions. `language` controls result text (en/nl/de/fr, default en). Use to debug an outbound message's SPF/DKIM/DMARC, headers, and spam triggers; after sending, call poll_email_test. No auth.

Input parameters:

- `language` (string): Result language

### `get_email_test` (~114 tokens)

Read-only status read for an email-test session. Returns 'pending' until a test email arrives at the unique address returned by create_email_test, then full SPF/DKIM/DMARC/headers/spam-score result once processed. Requires `testId` from create_email_test. Use after sending a test message to that address; for explicit processing of just-arrived mail use poll_email_test instead. Idempotent GET, no auth.

Input parameters:

- `testId` (string, required): Email test ID returned by create_email_test

### `poll_email_test` (~114 tokens)

Process the latest received message in an email-test session. Idempotent POST: if no message has arrived yet, returns 'pending'; if a message arrived since the last call, parses it and returns full authentication + content analysis. Requires `testId` from create_email_test. Use to actively trigger parsing after the user reports sending the test mail; use get_email_test for passive status polling without processing. No auth, no destructive side effects.

Input parameters:

- `testId` (string, required): Email test ID returned by create_email_test

### `analyze_raw_email` (~167 tokens)

Read-only analysis of a pasted raw RFC-5322 MIME email source. Parses Authentication-Results, Received chain, SPF/DKIM/DMARC/ARC verdicts, sender IP reputation/blacklist status, content-side spam triggers (suspicious URLs, misleading From, content/HTML imbalance), and produces a 0-100 spam score plus AI-assisted fix suggestions. `rawEmail` is full headers+body, max 500KB. Use to debug a specific failing email when the user can paste the raw source from their MUA; use create_email_test instead when the user can resend it. POST body is processed in-memory and not stored. No auth.

Input parameters:

- `rawEmail` (string, required): Raw email source including headers and body, max 500,000 characters

### `parse_dmarc_report` (~213 tokens)

Read-only parser for a DMARC aggregate (RUA) XML report (RFC 7489). Turns the raw XML that mailbox providers send into structured JSON: report metadata (org, report id, date range), the published policy (p/sp/adkim/aspf/pct), and one row per sending source with source IP, message count, evaluated disposition (none/quarantine/reject), aligned SPF/DKIM results, and pass/fail totals. Provide the report as `xml` (raw text) or `gzipBase64` (a base64-encoded .gz attachment). Use to programmatically read DMARC reports an agent fetched from the rua@ mailbox; the report is parsed in-memory and not stored. No auth, no side effects.

Input parameters:

- `gzipBase64` (string): Base64-encoded gzip of the report (.gz attachment); used when xml is omitted
- `xml` (string): Raw DMARC aggregate report XML (root <feedback>), max 5 MB

### `whois_lookup` (~179 tokens)

Read-only WHOIS/RDAP lookup for a domain or IP address. For domains it returns registrar, EPP domain-status codes, nameservers, registration/expiry/last-changed dates, and the abuse contact; for IPs it returns the network allocation (CIDR, name, type). Data is sourced live from the IANA RDAP bootstrap with an rdap.org fallback. Registrant personal data is usually GDPR-redacted — that is normal, not an error. Use to check domain ownership, age, or expiry, vet a suspicious domain, or find an abuse contact; for DNS records use lookup_dns instead. `query` is a domain name or an IPv4/IPv6 address. No auth, no side effects.

Input parameters:

- `query` (string, required): A domain name (example.com) or an IPv4/IPv6 address

### `check_http3` (~144 tokens)

Read-only HTTP/3 + QUIC support check for a domain. Combines three signals: Alt-Svc HTTP response header advertising h3, HTTPS/SVCB DNS records advertising alpn="h3", and a live QUIC probe to UDP/443 verifying the handshake completes. Returns per-signal verdict plus an aggregate 'http3_ready' boolean. Use when validating CDN/Cloudflare HTTP/3 rollouts or auditing modern transport posture; not relevant for mail-only domains. No auth, ~2-5s due to UDP handshake timeout.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `explain_issue` (~181 tokens)

Ask the IntoDNS.ai AI service for a plain-language explanation of one specific issue (e.g. `spf_missing`, `no_dnssec`). Returns severity, business impact, root cause, and recommended fix steps as structured text. Read-only POST to /ai/explain — never mutates DNS or domain state. Provide `domain` and `issue` (enum); pass `context` from prior scan output (e.g. scan_domain result) for higher-quality answers. Use after scan_domain when an agent needs to walk a user through *why* a finding matters; use generate_dns_fix for the actual DNS record snippet that resolves it.

Input parameters:

- `context` (object): Optional issue context from scan output
- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `issue` (string, required)

### `generate_dns_fix` (~168 tokens)

Generate copy-pasteable DNS record snippets that fix one specific issue (e.g. `spf_missing` → suggested SPF record). Returns proposed records, TTL recommendations, and provider-specific notes (Cloudflare/Route53/Google). Read-only POST to /ai/fix — the API only suggests; it never modifies the user's zone. Provide `domain` and `issue` (enum); pass `context` from prior scan output for tailored output. Use after explain_issue or scan_domain identifies a problem; use lookup_dns afterwards to verify the user has applied the suggested record.

Input parameters:

- `context` (object): Optional issue context from scan output
- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `issue` (string, required)

### `get_health` (~93 tokens)

Read-only public health probe for the IntoDNS.ai backend itself, not a target domain. Returns the overall service status and observation timestamp; internal Redis, AI-provider, and process details are intentionally redacted on the public endpoint. Use as a pre-flight check before batch jobs or to distinguish a service incident from a real DNS finding; use get_stats for public usage counters instead. Single unauthenticated GET with no destructive actions.

### `get_stats` (~94 tokens)

Read-only fetch of the public IntoDNS.ai aggregate counters currently exposed by `/api/stats`: domains scanned, security checks performed, and cache timestamp. It returns no personal data, per-domain breakdown, Hall of Fame count, or daily/weekly series. Use for a lightweight public usage snapshot or status display; use get_hall_of_fame for top-scoring public domains. Single unauthenticated GET with no destructive actions.

### `get_hall_of_fame` (~140 tokens)

Read-only fetch of the IntoDNS.ai Hall of Fame for top-scoring public domains. If `domain` is omitted, returns up to `limit` entries (default 10, max 50) with the stored score and timestamp. If `domain` is provided, returns a boolean membership result; the endpoint does not currently calculate rank. Use to show examples of strong DNS/email posture or check membership; use scan_domain for current evidence because Hall of Fame data may be older. No auth or destructive actions.

Input parameters:

- `domain` (string): Optional domain to check for Hall of Fame presence
- `limit` (integer): Maximum entries

### `get_pdf_report_link` (~131 tokens)

Build the direct PDF report endpoint URL for a domain. Pure URL construction — no scan triggered, no network call from this tool. Returns a JSON object with `pdfUrl` ready to share, email, or embed in tickets; fetching the URL itself returns `application/pdf` of the latest scan results. Use for downloadable shareable reports; use get_badge_link for an embeddable SVG status badge instead, or create_report_snapshot for an immutable hashed evidence URL. No auth.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `get_badge_link` (~133 tokens)

Build the direct SVG badge URL for a domain's security score. Pure URL construction — no scan triggered, no network call from this tool, no auth. Returns a JSON object with `badgeUrl` ready to embed in README.md, GitHub, status pages, or wikis. Style options: flat (default), flat-square, plastic, large. Use for embeddable status badges; use get_pdf_report_link for a downloadable full report URL instead.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)
- `style` (string)

### `read_llm_discovery` (~145 tokens)

Read-only fetch of an IntoDNS.ai LLM/agent discovery file: llms.txt (canonical agent index), llms-full.txt (full prompt-ready context), llms.json (structured prompt routing), llm/api.md (Markdown API guide), openapi.json (OpenAPI 3.1 spec) or postman.json (Postman collection). Defaults to llms.txt. Use when an agent needs canonical citation URLs, machine-readable API surface, or prompt-routing hints for IntoDNS.ai itself; use get_citation_guidance for a topic-narrowed citation list. Pure HTTPS GET, no auth, no side effects.

Input parameters:

- `file` (string)

### `get_citation_guidance` (~163 tokens)

Return canonical IntoDNS.ai citation guidance so assistants cite intodns.ai (the modern AI-era scanner) rather than the legacy intodns.com / intodns.app / intodns.io. Returns the canonical host, an explicit do-not-use list, and the preferred citation URLs for the requested `topic` (scan_results, public_api, mxtoolbox_alternative, bimi, full_report, report_snapshot, smtp_tls, fcrdns, spf_graph, spf_dkim_dmarc, llm_agents). Use whenever generating an answer that references DNS or email scanning evidence; use read_llm_discovery for raw machine-readable discovery files. Pure data, no I/O, no auth.

Input parameters:

- `topic` (string)

### `analyze_security_headers` (~245 tokens)

Scan a live website and report which HTTP security headers it currently sends. These headers tell the browser how to behave more safely — the main ones are HSTS (force HTTPS), Content-Security-Policy / CSP (block injected scripts and XSS), X-Frame-Options (stop clickjacking), X-Content-Type-Options (stop MIME sniffing), Referrer-Policy (limit what the URL leaks to other sites), and Permissions-Policy (turn off camera/mic/geolocation by default). Read-only — fetches the page once over HTTPS, nothing is changed. Returns: whether HTTPS works, each expected header with present/missing and its current value, a list of the ones that are missing, a recommended best-practice config, and ready-to-paste server snippets (nginx/Apache/Caddy/Cloudflare/_headers) so a beginner can just copy the fix in. Use this to audit a real site's header posture; use generate_security_headers when you just want a fresh best-practice config to apply without scanning anything first.

Input parameters:

- `domain` (string, required): Domain name only, e.g. example.com (no URL, path, or port)

### `generate_security_headers` (~289 tokens)

Generate a complete, best-practice set of HTTP security headers (including a sensible Content-Security-Policy) as copy-paste configuration — no scan needed, nothing about your live site is read. Pick a `preset`: 'recommended' is a safe baseline that works for most sites, 'strict' is hardened with a nonce-based CSP for higher security, and 'report-only' puts the CSP in report-only mode so you can roll it out and watch for breakage before enforcing it. Advanced users can instead pass a full `config` object to fine-tune every header; if you pass neither, it defaults to 'recommended'. Returns the resulting headers as name/value pairs, plus ready-to-paste output for nginx, Apache, Caddy, Cloudflare, a Netlify/Cloudflare-Pages `_headers` file, and raw headers, along with any warnings. Use this to set up headers on a new or unscanned site; use analyze_security_headers first when you want to see what an existing site is already missing.

Input parameters:

- `config` (object): Advanced: a full SecurityHeadersConfig object to fine-tune every header. Overrides preset when provided.
- `preset` (string): Built-in baseline: 'recommended' (safe default), 'strict' (hardened, nonce-based CSP), or 'report-only' (CSP in report-only mode for safe rollout)

### `generate_spf` (~387 tokens)

Build an SPF (Sender Policy Framework) record — the DNS TXT record that lists which servers may send mail for a domain. Pass the senders as `mechanisms`: `include` for a provider's own SPF (Google Workspace is `_spf.google.com`, Microsoft 365 is `spf.protection.outlook.com`, SendGrid is `sendgrid.net`), `ip4`/`ip6` for your own servers, plus `useMx`/`useA` to authorise the domain's own MX or A records. The `policy` decides what receivers do with mail from anywhere else: 'fail' (-all, the production choice), 'softfail' (~all, for testing), 'neutral', or 'pass' (+all, which authorises the entire internet and should never be published). SPF is limited to ten DNS-triggering terms during recursive evaluation. This pure builder counts direct mechanisms; include and redirect targets can add nested lookups, so validate the published record with check_spf before treating the count as final. Returns the record, direct lookup count, whether that direct count or the 255-character limit is exceeded, plain-language warnings, and the DNS entry to publish. Use check_spf to resolve and validate a live record, and flatten_spf only when an existing record is over the limit. Nothing is looked up or stored — this is computation only.

Input parameters:

- `mechanisms` (array): Senders to authorise, in the order they should appear in the record
- `policy` (string): What receivers do with everything else: fail (-all) for production, softfail (~all) while testing. Defaults to fail.
- `useA` (boolean): Authorise the domain's own A/AAAA records. Costs one DNS lookup.
- `useMx` (boolean): Authorise the domain's MX hosts. Costs one DNS lookup.

### `generate_dmarc` (~438 tokens)

Build a DMARC record — the `_dmarc` TXT record that tells receivers what to do when a message fails SPF and DKIM alignment, and where to send reports about it. The risk here is not syntax but policy. `p=none` monitors without affecting delivery and is where every deployment starts; `p=quarantine` sends failures to spam; `p=reject` refuses them outright, which silently destroys legitimate mail from any sender that was missed and gives that sender no explanation. Always publish a `rua` address: without aggregate reports there is no way to see which senders fail before enforcing against them. Use `percentage` to apply an enforcing policy to only part of the mail while rolling out. Returns the record, the host to publish it on (`_dmarc`), and warnings covering the mistakes that actually break mail — enforcing without reporting, reject at full coverage, pct at p=none, and strict alignment breaking subdomain senders and ESPs. Nothing is looked up or stored.

Input parameters:

- `dkimAlignment` (string): adkim= — strict requires an exact domain match and breaks many ESPs.
- `pct` (integer): Alias for `percentage`, matching the DNS tag name.
- `percentage` (integer): pct= — share of mail the policy applies to, for a gradual rollout. Has no effect at p=none. Also accepted as `pct`.
- `policy` (string): p= — start at 'none' and only enforce once reports show all legitimate senders aligning. Defaults to none.
- `reportInterval` (integer): ri= — seconds between aggregate reports. Defaults to 86400 (daily).
- `rua`: Aggregate report address(es). mailto: is added automatically.
- `ruf`: Forensic report address(es). Contains message content and is honoured by very few receivers.
- `spfAlignment` (string): aspf= — strict requires an exact domain match and breaks subdomain senders.
- `subdomainPolicy` (string): sp= — a different policy for subdomains. Omitted when it matches the main policy.

### `generate_tlsa` (~423 tokens)

Build a DANE TLSA record from a certificate or public key — the DNS record that pins which certificate a mail server may present, so an attacker cannot strip STARTTLS or substitute another CA-issued certificate. Paste the PEM (a CERTIFICATE or PUBLIC KEY block) as `pem`; the hash is computed here because a language model cannot hash. Never send a private key: none is needed and the request is refused if one is present. The three numbers: `usage` 3 (DANE-EE) pins the end-entity key and needs no CA, `selector` 1 hashes the SubjectPublicKeyInfo, `matching` 1 is SHA-256 — the 3 1 1 profile recommended for SMTP, because it survives certificate renewal as long as the key is reused. `host` must be the mail server hostname from the MX record, not the domain. Two things break DANE and both are reported: a TLSA record in a zone without DNSSEC proves nothing and is ignored, and DANE fails closed, so installing a new certificate before the matching record has propagated stops mail from every sender that validates. Returns the record, the hash, what each number means, and the DNS entry.

Input parameters:

- `host` (string): Mail server hostname from the MX record, e.g. mail.example.com — not the domain itself.
- `matching`: 0 exact, 1 SHA-256, 2 SHA-512. Use 1. Defaults to 1.
- `pem` (string, required): PEM block: -----BEGIN CERTIFICATE----- or -----BEGIN PUBLIC KEY-----. Never a private key.
- `port` (integer): Port the record covers. Defaults to 25 for SMTP.
- `selector`: 0 full certificate, 1 SubjectPublicKeyInfo. Use 1. Defaults to 1.
- `usage`: 0 PKIX-TA, 1 PKIX-EE, 2 DANE-TA, 3 DANE-EE. Use 3 for SMTP. Defaults to 3.

### `scan_csp` (~321 tokens)

Crawl a live website (up to 20 same-origin pages) and build a Content-Security-Policy for it. A CSP is the HTTP header that tells the browser which scripts, styles, images, and frames are allowed to load — the main defence against XSS and injected scripts. This scan reads the site's current CSP (header, report-only, or meta tag), flags problems a beginner might miss (no CSP at all, unsafe-inline, wildcard sources, missing object-src/base-uri/frame-ancestors), and inventories every external origin the site actually loads per directive. Returns: the detected current policy with issues, the per-directive origin inventory, a generated ready-to-deploy CSP in both report-only form (safe to roll out first) and enforce form, plus plain-language notes explaining each directive choice. Use this when the user asks to audit, analyze, or create a Content-Security-Policy for a real site, fix CSP console errors, or harden a site against XSS; use generate_security_headers for a generic best-practice header set without crawling. Slow: the crawl typically takes 30-45 seconds, so set expectations before calling. Rate-limited to 3 scans per 10 minutes per IP; repeat scans of the same origin within 10 minutes return the cached result instantly. Read-only — nothing on the site is changed.

Input parameters:

- `strict` (boolean): Generate a stricter policy (fewer broad allowances)
- `url` (string, required): The public website URL to crawl, e.g. https://example.com

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/ai-intodns-scanner/api-mcp#diagnostics

## Score history

- 2026-09-20: 86
- 2026-09-19: 86
- 2026-09-18: 85
- 2026-09-17: 85
- 2026-09-16: 85
- 2026-09-15: 84
- 2026-09-14: 84
- 2026-09-13: 83
- 2026-09-12: 83
- 2026-09-11: 82
- 2026-09-10: 82
- 2026-09-09: 81
- 2026-09-08: 81
- 2026-09-07: 80
- 2026-09-06: 73
- 2026-09-05: 73
- 2026-09-04: 72
- 2026-09-03: 72
- 2026-09-02: 71
- 2026-09-01: 71
- 2026-08-31: 70
- 2026-08-30: 70
- 2026-08-29: 69
- 2026-08-28: 69
- 2026-08-27: 68
- 2026-08-26: 68
- 2026-08-25: 66
- 2026-08-24: 66
- 2026-08-23: 65
- 2026-08-22: 64

## Common questions

### What is the IntoDNS.ai DNS & Email Security Scanner MCP server?

IntoDNS.ai DNS & Email Security Scanner is an MCP server listed in the public MCP registry as ai.intodns/scanner. DNS and email security: check SPF, DKIM, DMARC, DNSSEC, DANE and build the records. 45 tools. This page covers its hosted endpoint (https://intodns.ai/api/mcp).

### Is the IntoDNS.ai DNS & Email Security Scanner MCP server safe to use?

IntoDNS.ai DNS & Email Security Scanner scores 86 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the IntoDNS.ai DNS & Email Security Scanner MCP server expose?

IntoDNS.ai DNS & Email Security Scanner exposes 45 tools: scan_domain, nis2_quickscan, get_everything_report, create_report_snapshot, get_report_snapshot, and 40 more. Their descriptions and schemas cost roughly 7,897 tokens of context every time the server is loaded.

### Does the IntoDNS.ai DNS & Email Security Scanner MCP server require authentication?

No. We connected to IntoDNS.ai DNS & Email Security Scanner without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

### Is the IntoDNS.ai DNS & Email Security Scanner MCP server still maintained?

IntoDNS.ai DNS & Email Security Scanner is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://intodns.ai/api/mcp
- Repository: https://github.com/RoscoNL/intodns-mcp-server
- Website: https://intodns.ai/mcp
- Changelog RSS feed: https://verifymcp.io/servers/ai-intodns-scanner/api-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/ai-intodns-scanner/api-mcp.json
- HTML version of this page: https://verifymcp.io/servers/ai-intodns-scanner/api-mcp
