blackveil-dns 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,76 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: BLACKVEIL Security
6
+ Licensed Work: Blackveil DNS v1.3.0
7
+ The Licensed Work is (c) 2026 BLACKVEIL Security
8
+ Additional Use Grant: You may make non-commercial use of the Licensed Work.
9
+ "Non-commercial use" means use that is not intended for
10
+ or directed toward commercial advantage or monetary
11
+ compensation. For the avoidance of doubt, providing the
12
+ Licensed Work as a hosted service to third parties for a
13
+ fee, or embedding the Licensed Work in a commercial
14
+ product, constitutes commercial use.
15
+
16
+ Change Date: 2030-03-17
17
+
18
+ Change License: MIT License
19
+
20
+ For information about alternative licensing arrangements for the Software,
21
+ please visit: https://blackveilsecurity.com
22
+
23
+ Notice
24
+
25
+ The Business Source License (this document, or the "License") is not an Open
26
+ Source license. However, the Licensed Work will eventually be made available
27
+ under an Open Source License, as stated in this License.
28
+
29
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
30
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
31
+
32
+ -----------------------------------------------------------------------------
33
+
34
+ Business Source License 1.1
35
+
36
+ Terms
37
+
38
+ The Licensor hereby grants you the right to copy, modify, create derivative
39
+ works, redistribute, and make non-production use of the Licensed Work. The
40
+ Licensor may make an Additional Use Grant, above, permitting limited
41
+ production use.
42
+
43
+ Effective on the Change Date, or the fourth anniversary of the first publicly
44
+ available distribution of a specific version of the Licensed Work under this
45
+ License, whichever comes first, the Licensor hereby grants you rights under
46
+ the terms of the Change License, and the rights granted in the paragraph
47
+ above terminate.
48
+
49
+ If your use of the Licensed Work does not comply with the requirements
50
+ currently in effect as described in this License, you must purchase a
51
+ commercial license from the Licensor, its affiliated entities, or authorized
52
+ resellers, or you must refrain from using the Licensed Work.
53
+
54
+ All copies of the original and modified Licensed Work, and derivative works
55
+ of the Licensed Work, are subject to this License. This License applies
56
+ separately for each version of the Licensed Work and the Change Date may vary
57
+ for each version of the Licensed Work released by Licensor.
58
+
59
+ You must conspicuously display this License on each original or modified copy
60
+ of the Licensed Work. If you receive the Licensed Work in original or
61
+ modified form from a third party, the terms and conditions set forth in this
62
+ License apply to your use of that work.
63
+
64
+ Any use of the Licensed Work in violation of this License will automatically
65
+ terminate your rights under this License for the current and all other
66
+ versions of the Licensed Work.
67
+
68
+ This License does not grant you any right in any trademark or logo of
69
+ Licensor or its affiliates (provided that you may use a trademark or logo of
70
+ Licensor as expressly required by this License).
71
+
72
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
73
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
74
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
75
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
76
+ TITLE.
package/README.md ADDED
@@ -0,0 +1,517 @@
1
+ <div align="center">
2
+
3
+ # BLACK**V**EIL DNS
4
+
5
+ **Know where you stand.**
6
+
7
+ Open-source DNS & email security scanner for Claude, Cursor, VS Code, and MCP clients across Streamable HTTP, stdio, and legacy HTTP+SSE.
8
+
9
+ [![GitHub stars](https://img.shields.io/github/stars/MadaBurns/bv-mcp?style=flat&logo=github)](https://github.com/MadaBurns/bv-mcp/stargazers)
10
+ [![npm version](https://img.shields.io/npm/v/blackveil-dns)](https://www.npmjs.com/package/blackveil-dns)
11
+ [![npm downloads](https://img.shields.io/npm/dm/blackveil-dns)](https://www.npmjs.com/package/blackveil-dns)
12
+ [![Tests](https://img.shields.io/badge/Tests-1097-brightgreen)](https://github.com/MadaBurns/bv-mcp/actions)
13
+ [![Coverage](https://img.shields.io/badge/Coverage-~90%25-brightgreen)](https://github.com/MadaBurns/bv-mcp/actions)
14
+ [![BUSL-1.1 License](https://img.shields.io/badge/License-BUSL--1.1-blue.svg)](LICENSE)
15
+ [![MCP](https://img.shields.io/badge/MCP-2025--03--26-blue)](https://modelcontextprotocol.io/)
16
+ [![Cloudflare Workers](https://img.shields.io/badge/Cloudflare%20Workers-F38020?logo=cloudflare&logoColor=white)](https://workers.cloudflare.com/)
17
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.5-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
18
+
19
+ ![DNS Security](https://dns-mcp.blackveilsecurity.com/badge/blackveilsecurity.com)
20
+
21
+ </div>
22
+
23
+ ---
24
+
25
+ ## Try it in 30 seconds
26
+
27
+ **Claude Code** (one command):
28
+
29
+ ```bash
30
+ claude mcp add --transport http blackveil-dns https://dns-mcp.blackveilsecurity.com/mcp
31
+ ```
32
+
33
+ Then ask: `scan anthropic.com`
34
+
35
+ **Verify the endpoint is live:**
36
+
37
+ ```bash
38
+ curl https://dns-mcp.blackveilsecurity.com/health
39
+ ```
40
+
41
+ No install. No API key. One URL for hosted HTTP:
42
+
43
+ ```
44
+ Endpoint https://dns-mcp.blackveilsecurity.com/mcp
45
+ Transport Streamable HTTP · JSON-RPC 2.0
46
+ Auth None required
47
+ ```
48
+
49
+ Transport support:
50
+
51
+ - `Streamable HTTP`: `POST /mcp`, `GET /mcp`, `DELETE /mcp`
52
+ - `Native stdio`: `blackveil-dns-mcp` CLI from the `blackveil-dns` npm package
53
+ - `Legacy HTTP+SSE`: `GET /mcp/sse` bootstrap stream plus `POST /mcp/messages?sessionId=...`
54
+
55
+ <!-- TODO: Add terminal demo GIF here -->
56
+
57
+ ---
58
+
59
+ ## What you get
60
+
61
+ - **57+ checks across 20 categories** — SPF, DMARC, DKIM, DNSSEC, SSL/TLS, MTA-STS, NS, CAA, MX, BIMI, TLS-RPT, subdomain takeover, lookalike domains, HTTP security headers, DANE, shadow domains, TXT hygiene, MX reputation, SRV, zone hygiene
62
+ - **Maturity staging** — Stage 0-4 classification (Unprotected to Hardened) with next steps
63
+ - **Trust surface analysis** — detects shared SaaS platforms (Google, M365, SendGrid) and cross-references DMARC enforcement to determine real exposure
64
+ - **Plain-English remediation** — `explain_finding` turns findings into guidance anyone can understand
65
+ - **Self-tuning scoring** — adaptive weights adjust category importance based on patterns seen across scans, so scores reflect real-world failure distributions rather than static assumptions
66
+ - **Provider intelligence** — inbound/outbound email provider inference from MX, SPF, DKIM
67
+ - **Passive and read-only** — all checks use public Cloudflare DNS-over-HTTPS; no authorization required from the target
68
+
69
+ Full scope and limitations in the coverage table below.
70
+
71
+ ```
72
+ scan_domain("anthropic.com")
73
+
74
+ ████████████████████████████████████████░░░░░ 85 / 100
75
+ Grade: A · Maturity: Intermediate
76
+
77
+ SPF ·········· 80 MTA-STS ····· 85
78
+ DMARC ········ 90 NS ·········· 95
79
+ DKIM ········· 85 CAA ········· 85
80
+ DNSSEC ······· 35 BIMI ········ 95
81
+ SSL ········· 100 TLS-RPT ····· 95
82
+ MX ·········· 100
83
+
84
+ 2 high · 4 medium · 5 low · 5 info
85
+ ```
86
+
87
+ <div align="center">
88
+
89
+ **[Scan your domain now &rarr; blackveilsecurity.com](https://blackveilsecurity.com)**
90
+
91
+ </div>
92
+
93
+ ---
94
+
95
+ ## Tools
96
+
97
+ ```
98
+ 22 MCP tools
99
+
100
+ Email Auth Infrastructure Brand & Threats Meta
101
+ ──────────── ──────────────── ───────────────── ──────────────
102
+ check_spf check_dnssec check_bimi scan_domain
103
+ check_dmarc check_ns check_tlsrpt explain_finding
104
+ check_dkim check_caa check_lookalikes compare_baseline
105
+ check_mta_sts check_ssl check_shadow_domains
106
+ check_mx check_http_security
107
+ check_mx_reputation check_dane
108
+ check_srv
109
+ DNS Hygiene check_zone_hygiene
110
+ ────────────
111
+ check_txt_hygiene
112
+
113
+ + check_subdomain_takeover (internal — runs inside scan_domain)
114
+ ```
115
+
116
+ `explain_finding` takes any finding and returns: what it means, potential impact, adverse consequences, specific steps to fix, and relevant RFCs.
117
+
118
+ **Confidence labels:**
119
+ `deterministic` — direct protocol/record validation | `heuristic` — signal-based inference, may need manual validation | `verified` — high-confidence validation signal
120
+
121
+ **Subdomain takeover verification:**
122
+ `potential` — DNS signal, requires proof-of-control | `verified` — deprovisioning fingerprint detected | `not_exploitable` — no takeover signal
123
+
124
+ ---
125
+
126
+ ## Client setup
127
+
128
+ <details>
129
+ <summary><b>VS Code / Copilot</b></summary>
130
+
131
+ `.vscode/mcp.json`
132
+
133
+ ```json
134
+ {
135
+ "servers": {
136
+ "blackveil-dns": {
137
+ "type": "http",
138
+ "url": "https://dns-mcp.blackveilsecurity.com/mcp"
139
+ }
140
+ }
141
+ }
142
+ ```
143
+ </details>
144
+
145
+ <details>
146
+ <summary><b>Claude Code</b></summary>
147
+
148
+ `.mcp.json`
149
+
150
+ ```json
151
+ {
152
+ "mcpServers": {
153
+ "blackveil-dns": {
154
+ "type": "http",
155
+ "url": "https://dns-mcp.blackveilsecurity.com/mcp"
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ Or via CLI:
162
+
163
+ ```bash
164
+ claude mcp add --transport http blackveil-dns https://dns-mcp.blackveilsecurity.com/mcp
165
+ ```
166
+ </details>
167
+
168
+ <details>
169
+ <summary><b>Claude Desktop</b></summary>
170
+
171
+ **Recommended:** Open [claude.ai](https://claude.ai) → **Settings → Connectors → Add custom connector** → paste `https://dns-mcp.blackveilsecurity.com/mcp`.
172
+
173
+ **Advanced fallback:** If you want first-party local stdio instead of the hosted HTTP connector, open **Settings → Developer → Edit Config** (`claude_desktop_config.json`) and add:
174
+
175
+ ```json
176
+ {
177
+ "mcpServers": {
178
+ "blackveil-dns": {
179
+ "type": "stdio",
180
+ "command": "/opt/homebrew/bin/npx",
181
+ "args": ["-y", "--package", "blackveil-dns", "blackveil-dns-mcp"]
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ > Prefer the direct custom connector above when possible. The stdio route runs the server locally and depends on Node.js being available to Claude Desktop.
188
+ >
189
+ > On macOS GUI apps, `npx` may not resolve from `PATH`; if Homebrew is installed elsewhere, replace `/opt/homebrew/bin/npx` with your actual `npx` path. After editing the config, fully restart Claude Desktop. If you already have other servers, merge `"blackveil-dns"` into your existing `"mcpServers"` object — don't paste a second `{ }` wrapper.
190
+
191
+ </details>
192
+
193
+ <details>
194
+ <summary><b>Cursor</b></summary>
195
+
196
+ `.cursor/mcp.json`
197
+
198
+ ```json
199
+ {
200
+ "mcpServers": {
201
+ "blackveil-dns": {
202
+ "url": "https://dns-mcp.blackveilsecurity.com/mcp"
203
+ }
204
+ }
205
+ }
206
+ ```
207
+ </details>
208
+
209
+ For hosted MCP setup, stdio usage, and legacy fallback endpoints, see `docs/client-setup.md`.
210
+
211
+ ---
212
+
213
+ ## CI/CD
214
+
215
+ Enforce DNS security grades in your pipeline with the [Blackveil DNS GitHub Action](https://github.com/MadaBurns/blackveil-dns-action):
216
+
217
+ ```yaml
218
+ - uses: MadaBurns/blackveil-dns-action@v1
219
+ with:
220
+ domain: example.com
221
+ minimum-grade: B
222
+ profile: auto # or: mail_enabled, enterprise_mail, non_mail, web_only, minimal
223
+ api-key: ${{ secrets.BV_API_KEY }} # optional — bypasses rate limits
224
+ ```
225
+
226
+ The action outputs `score`, `grade`, `maturity`, `scoring-profile`, and `passed` for downstream steps.
227
+
228
+ ## Monitoring
229
+
230
+ Get weekly DNS security reports in Slack or Discord. See [`examples/slack-discord-webhook/`](examples/slack-discord-webhook/) for a ready-to-deploy Cloudflare Cron Trigger recipe.
231
+
232
+ ---
233
+
234
+ ## npm package
235
+
236
+ Install from npm when you want to call the scanner from your own Node.js app, script, or service. If you are connecting from VS Code, Claude, Cursor, or another MCP client, use the MCP endpoint configuration above instead.
237
+
238
+ ```bash
239
+ npm install blackveil-dns
240
+ ```
241
+
242
+ Requirements: Node 18+ or another runtime with global `fetch`, `URL`, `AbortController`, and Web Platform APIs.
243
+
244
+ <details>
245
+ <summary><b>Usage example</b></summary>
246
+
247
+ ```ts
248
+ import { scanDomain, explainFinding, formatScanReport, validateDomain } from 'blackveil-dns';
249
+
250
+ const candidate = 'example.com';
251
+ const validation = validateDomain(candidate);
252
+
253
+ if (!validation.valid) {
254
+ throw new Error(validation.error);
255
+ }
256
+
257
+ const result = await scanDomain(candidate);
258
+ console.log(formatScanReport(result));
259
+
260
+ const guidance = explainFinding('SPF', 'fail', 'No SPF record found');
261
+ console.log(guidance.recommendation);
262
+ ```
263
+
264
+ The npm package exports the reusable scanner API only. It does not start the MCP server or Cloudflare Worker entrypoint.
265
+ </details>
266
+
267
+ ---
268
+
269
+ <details>
270
+ <summary><b>Coverage — 57+ checks across 20 categories</b></summary>
271
+
272
+ The full [BLACKVEIL](https://blackveilsecurity.com) platform extends each with deeper analytics.
273
+
274
+ | Category | Checks | MCP (Free) | Platform |
275
+ |---|---:|---|---|
276
+ | SPF | 8 | Policy and syntax validation | Include-chain and sender-path analytics |
277
+ | DMARC | 10 | Policy, pct, reporting, alignment | Subdomain inheritance, reporting quality |
278
+ | DKIM | 9 | Selector discovery, RSA key strength | Rotation heuristics, key-age drift |
279
+ | DNSSEC | 6 | AD validation, signed-zone baseline | Chain-of-trust, rollover posture |
280
+ | SSL/TLS | 8 | Certificate availability, validity | Protocol/cipher depth, renewal risk |
281
+ | MTA-STS | 5 | TXT policy, policy retrieval | Policy hardening, reporting depth |
282
+ | NS | 4 | Delegation, diversity, resiliency | Infrastructure concentration |
283
+ | CAA | 4 | Presence, issuer allowlist | Issuance surface modeling |
284
+ | MX | 4 | Presence, routing, provider inference | Mail routing posture |
285
+ | Subdomain Takeover | 2 | Dangling CNAME detection | Expanded asset discovery |
286
+ | BIMI | 1 | Record presence, logo URL, VMC | Brand indicator compliance |
287
+ | TLS-RPT | 1 | Record presence, reporting URI | Reporting depth |
288
+ | Lookalikes | 1 | Typosquat detection, DNS + MX probing | Expanded permutation strategies |
289
+ | HTTP Security | 7 | CSP, X-Frame-Options, COOP, CORP, Permissions-Policy | Header depth analytics |
290
+ | DANE | 3 | TLSA record validation for MX and HTTPS | Certificate pinning posture |
291
+ | Shadow Domains | 1 | Alternate-TLD email spoofing risk | Extended TLD coverage |
292
+ | TXT Hygiene | 1 | Stale verifications, SaaS exposure | Shadow IT discovery |
293
+ | MX Reputation | 1 | DNSBL + PTR/FCrDNS validation | Deliverability analytics |
294
+ | SRV | 1 | Service footprint discovery | Protocol exposure analytics |
295
+ | Zone Hygiene | 1 | SOA consistency, sensitive subdomains | Infrastructure exposure |
296
+
297
+ </details>
298
+
299
+ <details>
300
+ <summary><b>Scan output — anthropic.com (real, unedited)</b></summary>
301
+
302
+ ```
303
+ BLACKVEIL DNS anthropic.com
304
+ ─────────────────────────────────────────────────────────────────────
305
+
306
+ CATEGORY SCORE STATUS KEY FINDINGS
307
+ ─────────────────────────────────────────────────────────────────────
308
+ SPF 80/100 PASS Soft fail (~all), Google shared
309
+ DMARC 90/100 PASS p=reject, relaxed alignment
310
+ DKIM 85/100 PASS google selector, 2048-bit RSA
311
+ DNSSEC 35/100 FAIL Not enabled — no DNSKEY/DS
312
+ SSL/TLS 100/100 PASS HTTPS + HSTS configured
313
+ MTA-STS 85/100 PASS No MTA-STS/TLS-RPT records
314
+ NS 95/100 PASS Cloudflare anycast
315
+ CAA 85/100 PASS No CAA records published
316
+ MX 100/100 PASS 5 MX records, Google Workspace
317
+ BIMI 95/100 PASS Eligible but not published
318
+ TLS-RPT 95/100 PASS No TLS-RPT record
319
+ ─────────────────────────────────────────────────────────────────────
320
+
321
+ ████████████████████████████████████████░░░░░ 85 / 100 Grade: A
322
+ ```
323
+
324
+ ### Findings
325
+
326
+ ```
327
+ SEVERITY FINDING CATEGORY
328
+ ─────────────────────────────────────────────────────────────────────────────
329
+ HIGH DNSSEC not validated — AD flag not set DNSSEC
330
+ HIGH No DNSKEY records found DNSSEC
331
+ MEDIUM No DS records — chain of trust broken DNSSEC
332
+ MEDIUM No MTA-STS or TLS-RPT records MTA-STS
333
+ MEDIUM No CAA records — any CA can issue certs CAA
334
+ MEDIUM DKIM RSA key below recommended (2048 < 4096) DKIM
335
+ LOW SPF soft fail (~all) — consider -all SPF
336
+ LOW Relaxed DKIM alignment (adkim=r) DMARC
337
+ LOW Relaxed SPF alignment (aspf=r) DMARC
338
+ LOW Low nameserver diversity (all Cloudflare) NS
339
+ LOW No BIMI record — eligible with p=reject BIMI
340
+ LOW No TLS-RPT record TLSRPT
341
+ INFO SPF delegates to shared platform: Google Workspace SPF
342
+ INFO DMARC properly configured (p=reject, sp=reject) DMARC
343
+ INFO MX records found (5 records) MX
344
+ INFO Inbound provider: Google Workspace MX
345
+ INFO HTTPS + HSTS properly configured SSL
346
+ ```
347
+
348
+ **What this means.** Anthropic has strong email authentication — DMARC is set to `reject`, SPF and DKIM are present, Google Workspace handles mail. Because DMARC enforcement is strong, the shared-platform SPF delegation to Google stays informational rather than being flagged as a risk. The main gap is DNSSEC (DNS responses aren't cryptographically signed) and hardening opportunities around CAA, MTA-STS, and BIMI.
349
+
350
+ Run `explain_finding` on any result for plain-English remediation.
351
+
352
+ </details>
353
+
354
+ <details>
355
+ <summary><b>Protocol</b></summary>
356
+
357
+ | Method | Path | Purpose |
358
+ |---|---|---|
359
+ | `POST` | `/mcp` | JSON-RPC 2.0 tool/protocol requests (single or batch) |
360
+ | `GET` | `/mcp` | SSE stream for server notifications (requires session) |
361
+ | `DELETE` | `/mcp` | Session termination |
362
+ | `GET` | `/mcp/sse` | Legacy SSE bootstrap stream |
363
+ | `POST` | `/mcp/messages` | Legacy message delivery (requires `?sessionId=`) |
364
+ | `GET` | `/health` | Health probe |
365
+ | `POST` | `/internal/tools/call` | Service binding: single tool call (no auth/rate limits) |
366
+ | `POST` | `/internal/tools/batch` | Service binding: bulk scan up to 500 domains |
367
+
368
+ Supported methods: `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list`, `resources/read`.
369
+
370
+ Prompt methods (`prompts/list`, `prompts/get`) return `-32601 Method not found`.
371
+
372
+ </details>
373
+
374
+ <details>
375
+ <summary><b>Architecture</b></summary>
376
+
377
+ ```
378
+ MCP Client
379
+
380
+ │ POST /mcp (JSON-RPC 2.0)
381
+
382
+ ┌───▼──────────────────────┐
383
+ │ Cloudflare Worker │
384
+ │ │
385
+ │ Hono ─► Origin check │
386
+ │ ─► Auth │
387
+ │ ─► Rate limiting │
388
+ │ ─► Session mgmt │
389
+ └───┬──────────────────────┘
390
+
391
+ ┌───▼──────────────────────┐
392
+ │ Tool Handlers │
393
+ │ 14 checks in parallel │
394
+ └───┬──────────────────────┘
395
+
396
+ ┌───▼──────────────────────┐
397
+ │ Cloudflare DoH │
398
+ │ DNS-over-HTTPS │
399
+ └──────────────────────────┘
400
+ ```
401
+
402
+ - Input sanitation and domain validation
403
+ - Optional bearer-token authentication
404
+ - Per-IP rate limiting (KV + in-memory fallback)
405
+ - `check_lookalikes` capped at 20/day per IP with 60-min caching
406
+ - `scan_domain` capped at 75/day per IP (results cached 5 min)
407
+ - Scan result caching (KV + in-memory fallback)
408
+ - Adaptive scoring via Durable Object telemetry (graceful fallback to static weights)
409
+ - Structured JSON logging
410
+
411
+ Implementation details in `CLAUDE.md`.
412
+
413
+ </details>
414
+
415
+ <details>
416
+ <summary><b>Security</b></summary>
417
+
418
+ Full details in `CLAUDE.md` (security and observability sections).
419
+
420
+ - Domain inputs validated and sanitized before execution
421
+ - IP literals rejected (standard and alternate numeric forms)
422
+ - SSRF protections block unsafe/private targets
423
+ - Error responses sanitized — only known validation errors surface
424
+ - DNS via Cloudflare DoH with optional secondary confirmation
425
+ - Rate limits: `50/min` and `300/hr` per IP for `tools/call`
426
+ - Control-plane traffic: `60/min` and `600/hr` per IP
427
+ - Global daily cap: `500,000` unauthenticated tool calls/day (cost ceiling)
428
+ - Session creation: `60/min` per IP
429
+
430
+ **Natural-language convenience:**
431
+ `tools/call` supports `scan` as an alias for `scan_domain`. In chat clients, say `scan example.com`. Raw JSON-RPC expects `params.name` to be `scan` or `scan_domain`.
432
+
433
+ </details>
434
+
435
+ <details>
436
+ <summary><b>Provider detection</b></summary>
437
+
438
+ `check_mx` and `scan_domain` infer managed email providers.
439
+
440
+ - **Inbound** — MX host matching
441
+ - **Outbound** — SPF include/redirect signals + DKIM selector hints
442
+ - Metadata: `detectionType`, `providers`, `providerConfidence` (0.0-1.0), `signatureSource`, `signatureVersion`
443
+ - Fallback order: runtime source -> stale cache -> built-in signatures
444
+
445
+ Optional configuration:
446
+
447
+ | Variable | Purpose |
448
+ |---|---|
449
+ | `PROVIDER_SIGNATURES_URL` | Runtime provider-signature JSON source |
450
+ | `PROVIDER_SIGNATURES_SHA256` | Required pinned digest |
451
+ | `PROVIDER_SIGNATURES_ALLOWED_HOSTS` | Hostname allowlist |
452
+
453
+ </details>
454
+
455
+ ---
456
+
457
+ ## Development
458
+
459
+ ```bash
460
+ git clone https://github.com/MadaBurns/bv-mcp.git
461
+ cd bv-mcp
462
+ npm install
463
+ npm run dev # localhost:8787/mcp
464
+ ```
465
+
466
+ ```bash
467
+ npm test # 1090+ tests, ~90% coverage
468
+ npm run typecheck
469
+ ```
470
+
471
+ <details>
472
+ <summary><b>Private deployment</b></summary>
473
+
474
+ ```bash
475
+ cp wrangler.private.example.jsonc .dev/wrangler.deploy.jsonc
476
+ # replace KV namespace IDs and analytics dataset in .dev/wrangler.deploy.jsonc
477
+ npm run deploy:private
478
+ ```
479
+
480
+ The checked-in [wrangler.jsonc](wrangler.jsonc) stays generic for open source use. Real KV IDs, session storage, and Analytics Engine dataset names should live only in the ignored `.dev/wrangler.deploy.jsonc` file.
481
+
482
+ </details>
483
+
484
+ Manual request examples and failure modes in `docs/troubleshooting.md`.
485
+
486
+ ---
487
+
488
+ ## Docs
489
+
490
+ | Document | Path |
491
+ |---|---|
492
+ | Client setup | `docs/client-setup.md` |
493
+ | Scoring | `docs/scoring.md` |
494
+ | Troubleshooting | `docs/troubleshooting.md` |
495
+ | Style guide | `docs/style-guide.md` |
496
+
497
+ ---
498
+
499
+ ## Why
500
+
501
+ Most DNS and email security tools are paywalled dashboards or CLI scripts that need local setup. Neither works inside an AI assistant where you want to check a domain mid-conversation.
502
+
503
+ One endpoint URL. No install. No API key. Point any MCP client at `https://dns-mcp.blackveilsecurity.com/mcp` and know where you stand.
504
+
505
+ ---
506
+
507
+ <div align="center">
508
+
509
+ Built and maintained by [**BLACKVEIL**](https://blackveilsecurity.com) — NZ-owned cybersecurity consultancy.
510
+
511
+ Featured in [SecurityBrief](https://securitybrief.co.nz/story/exclusive-how-cybersecurity-startup-blackveil-is-targetting-ai-driven-threats) · [NZ Herald](https://www.nzherald.co.nz/video/herald-now/ryan-bridge-today/cybersecurity-medimap-hack/OMLGW3OMXOVSSJ3RLFXPMAVGKE/) · [Modern Cyber](https://www.youtube.com/watch?v=W4aJHpfB5rY)
512
+
513
+ Want continuous monitoring? [BLACKVEIL](https://blackveilsecurity.com) provides real-time alerting and Buck AI to help you fix what this scanner finds.
514
+
515
+ MIT License
516
+
517
+ </div>