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 +76 -0
- package/README.md +517 -0
- package/dist/index.d.ts +506 -0
- package/dist/index.js +5546 -0
- package/dist/index.js.map +1 -0
- package/dist/stdio.d.ts +12 -0
- package/dist/stdio.js +9854 -0
- package/dist/stdio.js.map +1 -0
- package/package.json +87 -0
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
|
+
[](https://github.com/MadaBurns/bv-mcp/stargazers)
|
|
10
|
+
[](https://www.npmjs.com/package/blackveil-dns)
|
|
11
|
+
[](https://www.npmjs.com/package/blackveil-dns)
|
|
12
|
+
[](https://github.com/MadaBurns/bv-mcp/actions)
|
|
13
|
+
[](https://github.com/MadaBurns/bv-mcp/actions)
|
|
14
|
+
[](LICENSE)
|
|
15
|
+
[](https://modelcontextprotocol.io/)
|
|
16
|
+
[](https://workers.cloudflare.com/)
|
|
17
|
+
[](https://www.typescriptlang.org/)
|
|
18
|
+
|
|
19
|
+

|
|
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 → 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>
|