Search DevTools

Jump to any tool or page

dns

Unexplored

DNS and email security scanner with 76 MCP tools for SPF, DMARC, DNSSEC, SSL, and brand audits.

MadaBurns8 stars4 forksAI & Agents
View source

Install

mcp_config.json

{
  "mcpServers": {
    "com-blackveilsecurity-dns": {
      "url": "https://dns-mcp.blackveilsecurity.com/mcp",
      "type": "streamable-http"
    }
  }
}

Documentation

BLACKVEIL DNS

Know where you stand.

Source-available DNS & email security scanner for Claude, Cursor, VS Code, and MCP clients across Streamable HTTP, stdio, and legacy HTTP+SSE.


Try it in 30 seconds

Claude Desktop (one-click install):

Download the Blackveil DNS extension and open it — the current 76-tool surface is available instantly. Verify your download.

Claude Code (one command):

claude mcp add --transport http blackveil-dns https://dns-mcp.blackveilsecurity.com/mcp

Then ask: scan anthropic.com

Smithery (one command):

smithery mcp add MadaBurns/bv-mcp

Verify the endpoint is live:

curl https://dns-mcp.blackveilsecurity.com/health

No install. No API key. One URL for hosted HTTP:

Endpoint   https://dns-mcp.blackveilsecurity.com/mcp
Transport  Streamable HTTP · JSON-RPC 2.0
Auth       None required

Transport support:

  • Streamable HTTP: POST /mcp, GET /mcp, DELETE /mcp
  • Native stdio: blackveil-dns-mcp CLI from the blackveil-dns npm package
  • Legacy HTTP+SSE: GET /mcp/sse bootstrap stream plus POST /mcp/messages?sessionId=...

For Streamable HTTP, clients should retain the Mcp-Session-Id returned by initialize and send it on every subsequent request, including notifications. Send the negotiated version in MCP-Protocol-Version; unsupported values are rejected with HTTP 400, while expired or terminated sessions return 404 and require a fresh initialize.


What you get

  • 76 MCP tools with 19 scoring categories — SPF, DMARC, DKIM, DNSSEC, SSL/TLS, MTA-STS, NS, CAA, MX, BIMI, TLS-RPT, subdomain takeover, HTTP security headers, DANE, SVCB/HTTPS, DANE-HTTPS, subdomailing, reverse DNS (PTR/FCrDNS), and DNSKEY strength
  • Maturity staging — Stage 0-4 classification (Unprotected to Hardened) with score-based capping to prevent inflated labels
  • Trust surface analysis — detects shared SaaS senders in SPF, both cataloged platforms (Google, M365, SendGrid) and uncataloged hosts identifiable by their spf delegation label, then cross-references DMARC enforcement to determine real exposure
  • Guided remediationgenerate (artifact=fix_plan) produces provider-aware prioritized actions; its record artifacts (spf_record, dmarc_record, dkim_config, mta_sts_policy, rollout_plan) output ready-to-publish records; validate_fix confirms whether a fix was applied successfully
  • Supply chain mappingmap_supply_chain correlates DNS signals to build a full third-party dependency graph with trust levels and risk signals
  • Attack path simulationsimulate_attack_paths enumerates specific paths (spoofing, takeover, hijack) with severity, steps, and mitigations
  • Compliance mappingmap_compliance maps scan findings to NIST 800-177, PCI DSS 4.0, SOC 2, and CIS Controls
  • Self-tuning scoring — adaptive weights adjust category importance based on patterns seen across scans via Durable Object telemetry
  • Per-tier analytics — usage tracking by auth tier with operator API for tier summaries, key-level usage, and daily digests
  • Passive and read-only — all checks use public Cloudflare DNS-over-HTTPS; no authorization required from the target

Tools

  76 MCP tools · 7 prompts · 6 resources

  Email Auth             Infrastructure          Brand & Threats       Meta
 ─────────────          ──────────────          ───────────────       ───────────────
  check_mx              check_dnssec            check_bimi            scan_domain
  check_spf             check_ssl               check_tlsrpt          batch_scan
  check_dmarc           check_ns                check_lookalikes      compare_domains
  check_dkim            check_caa               check_shadow_domains  compare_baseline
  check_mta_sts         check_http_security                           explain_finding
  check_subdomailing    check_dane
  check_mx_reputation   check_dane_https        DNS Hygiene           Remediation
                        check_svcb_https       ─────────────         ───────────────
                        check_ptr               check_txt_hygiene     generate (one tool;
  Intelligence          check_srv                                       artifact=fix_plan,
 ─────────────          check_zone_hygiene                              spf_record,
  get_benchmark         check_resolver_         Discovery               dmarc_record,
  get_domain_rank         consistency          ─────────────           dkim_config,
  get_provider_                                 discover_brand_         mta_sts_policy,
    insights            check_dbl                domains                rollout_plan)
  assess_spoofability   check_rbl               brand_audit_single    validate_fix
  map_supply_chain      cymru_asn               brand_audit_batch_
  analyze_drift         rdap_lookup               start
  resolve_spf_chain     check_nsec_             brand_audit_status
  discover_subdomains     walkability           brand_audit_get_
  map_compliance        check_dnssec_chain        report
  prioritize_csc_leads
  simulate_attack_paths check_fast_flux         list_brand_audit_watches
  check_agent_discovery check_dnskey_strength
                        check_authoritative_dns_infra
                        check_root_server_set   register_brand_audit_watch
                                                delete_brand_audit_watch

  + check_subdomain_takeover (standalone tool + internal — runs inside scan_domain)
  + check_authoritative_dns_infra and check_root_server_set (authoritative DNS infrastructure profile)
  + discover_brand_domains_start / discover_brand_domains_status / discover_brand_domains_findings
    (async start → poll → fetch sibling of discover_brand_domains, for clients that time out on the ~24s sync call)

  Operator-deploy only (BV_RECON binding; degrade to unprovisioned on self-hosted BUSL deployments):
  + check_realtime_threat_feed   — curated intel-gateway threat feed lookup
  + scan_buckets_start           — async cloud-bucket discovery scan (start → poll → findings)
  + scan_buckets_status          — poll status of a running bucket scan
  + scan_buckets_findings        — retrieve findings for a completed bucket scan
  + osint_investigate_domain_start          — async domain OSINT investigation (start → poll → report)
  + osint_investigate_infrastructure_start  — async deep-infrastructure OSINT (domain, IP, or org)
  + osint_investigate_supply_chain_start    — async supply-chain OSINT investigation
  + osint_investigate_username_start        — async username OSINT (owner/enterprise tier only)
  + osint_investigate_email_start           — async email OSINT (owner/enterprise tier only)
  + osint_investigation_status   — poll status of any running OSINT investigation
  + osint_investigation_report   — retrieve report for a completed OSINT investigation

  Operator-deploy only (proxied via the `BV_WEB` service binding, wired as the `m365Proxy` runtime option; Microsoft 365 / Entra identity security ops — degrade to unprovisioned without it):
  + query_signins                — query Microsoft Entra sign-in logs for a tenant
  + query_ual                    — query the Microsoft 365 Unified Audit Log for a tenant
  + get_ca_policies              — retrieve Conditional Access policies for an Entra tenant
  + assess_coverage              — assess Conditional Access coverage gaps for an Entra tenant

Tool discovery metadata (_meta)

tools/list returns every tool with server-specific discovery metadata under each tool's _meta (the MCP-sanctioned extension point), so a client can group or filter the surface without hard-coding tool names:

  • group — functional group (email_auth, infrastructure, brand_threats, dns_hygiene, intelligence, remediation, discovery, identity_secops, meta).
  • tier — scoring tier (core / protective / hardening); absent for non-scoring tools.
  • scanIncludedtrue when the tool runs inside scan_domain's parallel audit.
  • recommended — present (true) only on the curated starter set (scan_domain, explain_finding, compare_baseline); omitted otherwise. A client facing the full surface can lead with tools.filter(t => t._meta.recommended) to avoid overwhelming an LLM with all tools flat. Every tool is still listed — this is an additive signal, not a filter.

Authoritative DNS infrastructure

check_authoritative_dns_infra scores authoritative DNS hosting behavior for a hostname. It is designed to consume raw UDP/TCP DNS, authoritative AA/RA behavior, zone-transfer refusal, DNSSEC, abuse-resistance, BGP/RPKI, and multi-vantage evidence from the BV_INFRA_PROBE service binding when that worker is provisioned.

check_root_server_set validates the DNS root-server set against the embedded official root hints. With BV_INFRA_PROBE, it also checks live root priming, glue, parent/child delegation, DNSKEY, and SOA serial evidence across roots.

Self-hosted or local deployments without BV_INFRA_PROBE still return structured partial results. The worker-only mode records the embedded root hints and marks live raw-DNS, routing, RPKI, and vantage capabilities as inconclusive rather than pretending they ran.


Quality & Reliability

The server classifies detected MCP clients by their default response format:

  • Interactive clients: claude_mobile, claude_code, cursor, vscode, claude_desktop, claude_connector, windsurf (auto-format: compact)
  • Non-interactive clients: mcp_remote, blackveil_dns_action, bv_claude_dns_proxy, unknown (auto-format: full)

The bv_load_test class identifies internal load/chaos/tranco-scan traffic so it stays out of real-client analytics segments.

The comprehensive chaos suite validates session stability, authentication precedence, format negotiation, and transport-specific edge cases across Streamable HTTP and Legacy SSE for its supported client fixtures. Without an API key it exercises the public/free-tier path; with a valid key exported as BV_API_KEY, it covers Bearer authentication, legacy self-host ?api_key= compatibility, authenticated SSE bootstrap, and authenticated batch behavior.

Run the client/session chaos suite locally: python3 scripts/chaos/chaos-test-clients.py.

Run repeat force-refresh scans to detect production scoring drift:

BV_API_KEY=... python3 scripts/chaos/score-stability-test.py --count 20 --rounds 3 --concurrency 5

The stability harness negotiates MCP protocol 2025-06-18, accepts JSON and Streamable HTTP SSE responses, and exits non-zero on any transport/tool error or score/category drift. Use --from <json-file> with a JSON array of domains for a targeted provider-diversity sweep.

SSOT guardrails are enforced by focused audit tests:

  • Tool counts and public resource copy are generated from the TOOLS registry, not hand-written — npm run generate:tool-surface rewrites every advertised count, and npm run check:tool-surface fails CI if any drifts. Counts advertised to clients use the public surface (TOOLS minus internal-only tools), so the number in the docs, the badge, the VS Code listing and the resources/read copy is the number tools/list actually returns.
  • Domain-required validation is derived from each tool input schema.
  • Scan timeout budgets are resolved from shared runtime config.
  • WASM tool permissions are generated from MCP tool annotations.
  • Public quota copy is checked against runtime quota config.

Version stamps in scan output

Every scan_domain / batch_scan result carries three reproducibility stamps. They are three different namespaces — do not compare them to each other, and do not read any of them as the npm package version unless it says so:

FieldWhat it tracksHow often it moves
scoringModelVersionThe scoring policy: category weights, profile weights, grade thresholds, severity penalties, the passed/missing-control rule, profile detection.Only when a change alters scores or grades. Slowly — most releases do not touch it.
dnsChecksPackageVersionThe @blackveil/dns-checks engine package version bundled by the running build.Every package release — code, new detections, bug fixes.
scoringConfigHashFingerprint of the effective scoring configuration that produced this result, including any SCORING_CONFIG override.Whenever the effective config differs.

scoringModelVersion is independent of dnsChecksPackageVersion and is normally lower — for example model 1.10.0 alongside package 1.18.0. That is not a version gap, and it does not mean a consumer's vendored copy scores differently from the hosted service: the package advanced eight minors without changing scoring policy. Reading the model version as the package version has twice triggered a false "engine version gap" investigation, which is why both are now emitted side by side.

When you publish or cite a score, record scoringConfigHash — not either version number. It is the value that identifies the exact scoring configuration behind a result, so two scans carrying the same hash were graded under the same rules.

Status badge

GET /badge/<domain> returns an embeddable SVG — the badge at the top of this README is a live scan of our own domain. It needs no authentication and is subject to the same anonymous rate limits and daily caps as a public scan.

The badge shows the same customer-facing letter scan_domain reports — the NIST-aligned 6-band grade (A+ ≥95, A ≥90, B ≥80, C ≥70, D ≥60, F <60) — so a domain cannot show one grade on its badge and a different one in its report. Two further states are stated rather than papered over:

  • <grade> partial — the scan was graded, but did not complete every check (a WAF challenge, a timeout, an unreachable host). The hover/aria title gives the exact coverage, e.g. 17 of 19 checks measured. The grade and its colour are unchanged: coverage and posture are different axes.
  • unknown — the domain could not be measured at all. The badge says so instead of substituting a letter, which would publish a failing grade nobody measured.

See docs/scoring.md for the grade scales and the evidence rules behind them.


Architecture

  MCP Client
      │
      │  POST /mcp (JSON-RPC 2.0)
      │
  ┌───▼──────────────────────┐
  │  Cloudflare Worker       │
  │                          │
  │  Hono ─► Origin check    │
  │       ─► Auth            │
  │       ─► Rate limiting   │
  │       ─► Session mgmt    │
  └───┬──────────────────────┘
      │
  ┌───▼──────────────────────┐
  │  Tool Handlers           │
  │  19 scoring categories   │
  └───┬──────────────────────┘
      │
  ┌───▼──────────────────────┐
  │  Generic Scoring Engine  │
  │  Three-tier model        │
  └───┬──────────────────────┘
      │
  ┌───▼──────────────────────┐
  │  Cloudflare DoH          │
  │  DNS-over-HTTPS          │
  └──────────────────────────┘
  • Generic Scoring Engine: Runtime-agnostic, string-keyed three-tier scoring with configurable weights
  • Infra Probe Binding: Optional BV_INFRA_PROBE service binding supplies raw authoritative DNS, root-server, BGP/RPKI, and vantage evidence for the authoritative DNS infrastructure profile
  • WASM Policy Engine: High-performance permission and token checks via bv-wasm-core
  • Reliable Sessions: Hardened tombstone logic prevents race-condition revival of terminated sessions
  • Protocol Enforcement: Unsupported MCP versions fail closed; notifications and SSE connections use the same session-validity rules as other post-initialize requests
  • Bounded Egress: Public CT and target-HTML responses are streamed under byte ceilings before parsing or fingerprinting
  • Cryptographic Identifiers: Session and CSC report identifiers use Web Crypto randomness
  • Adaptive Scoring: Durable Object telemetry adjusts weights based on real-world distributions
  • Client Awareness: Automatic response formatting (compact vs full) based on client User-Agent

Brand-discovery modes (discover_brand_domains / brand_audit_*)

The discovery_mode argument accepts two values:

  • classic (the default everywhere this repo runs out-of-the-box) — the public, BUSL-licensed signal-sweep pipeline. Uses only public-internet data sources (DNS, RDAP, CT logs, MX/TXT inspection). This is the only mode supported for self-hosted deployments and the only mode the open test suite covers end-to-end.
  • tiered — layers a portfolio-aware Tier 0 / infrastructure-graph Tier 1 / declared-evidence Tier 2 pipeline in front of the classic sweep. Tiered mode requires private BlackVeil-internal cross-Worker bindings (BV_INFRA_GRAPH, BV_INTEL_GATEWAY, BV_ENTERPRISE) that are not packaged with the open distribution — they live in BlackVeil's production deploy overlay (.dev/wrangler.deploy.jsonc) and call into proprietary Workers. Self-hosters cannot enable tiered mode without those bindings.

BlackVeil's hosted production at dns-mcp.blackveilsecurity.com flips its runtime default to tiered via the env var BRAND_AUDIT_DISCOVERY_MODE_DEFAULT="tiered" in the private overlay; the public schema default in src/schemas/tool-args.ts stays 'classic' permanently so anyone building from main gets the BUSL-licensed behaviour unchanged. An explicit caller-supplied discovery_mode always wins over the env default.


Client setup

The free tier requires no authentication. Authenticated requests bypass per-IP rate limits and follow your tier's daily quota. Hosted production supports:

  • Header: Authorization: Bearer <KEY>
  • Header (alternative): X-API-Key: <KEY> — for clients that cannot set Authorization. If both are sent, Authorization: Bearer wins.
  • OAuth 2.1: optional authorization-code flow with PKCE, enabled only when operators set ENABLE_OAUTH=true; owner-key consent is separately gated by ENABLE_OWNER_OAUTH=true.

The ?api_key=<KEY> fallback is legacy/self-host compatibility only. BlackVeil hosted production sets REJECT_QUERY_API_KEY=true; clients that cannot send headers should use OAuth or an mcp-remote header bridge.

For full hosted setup examples, stdio usage, OAuth setup, and legacy fallback endpoints, see docs/client-setup.md.


Operator configuration

These settings apply to operators running their own deployment. They are optional — self-hosted (BUSL) deployments fall back to privacy-preserving defaults when they are unset.

Detailed analytics capture

The public /mcp path writes a per-event access log enriched with geolocation and network identity. The write path, PII depth, and retention are operator-controlled:

| Binding / var | Type | Purpose

Sourced from the repository README.

More in AI & Agents