@cyanheads/whois-mcp-server 0.1.1
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/AGENTS.md +349 -0
- package/CLAUDE.md +349 -0
- package/Dockerfile +99 -0
- package/LICENSE +201 -0
- package/README.md +316 -0
- package/changelog/0.1.x/0.1.1.md +32 -0
- package/changelog/template.md +127 -0
- package/dist/config/server-config.d.ts +16 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +30 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/_fqdn.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/_fqdn.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/_fqdn.js +18 -0
- package/dist/mcp-server/tools/definitions/_fqdn.js.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-check-availability.tool.d.ts +26 -0
- package/dist/mcp-server/tools/definitions/whois-check-availability.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-check-availability.tool.js +102 -0
- package/dist/mcp-server/tools/definitions/whois-check-availability.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-get-dns.tool.d.ts +49 -0
- package/dist/mcp-server/tools/definitions/whois-get-dns.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-get-dns.tool.js +97 -0
- package/dist/mcp-server/tools/definitions/whois-get-dns.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.d.ts +41 -0
- package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.js +332 -0
- package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.d.ts +30 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.js +83 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.d.ts +40 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.js +124 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.d.ts +39 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.js +111 -0
- package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.js.map +1 -0
- package/dist/services/doh/doh-service.d.ts +30 -0
- package/dist/services/doh/doh-service.d.ts.map +1 -0
- package/dist/services/doh/doh-service.js +114 -0
- package/dist/services/doh/doh-service.js.map +1 -0
- package/dist/services/doh/types.d.ts +45 -0
- package/dist/services/doh/types.d.ts.map +1 -0
- package/dist/services/doh/types.js +17 -0
- package/dist/services/doh/types.js.map +1 -0
- package/dist/services/rdap/rdap-service.d.ts +54 -0
- package/dist/services/rdap/rdap-service.d.ts.map +1 -0
- package/dist/services/rdap/rdap-service.js +609 -0
- package/dist/services/rdap/rdap-service.js.map +1 -0
- package/dist/services/rdap/types.d.ts +140 -0
- package/dist/services/rdap/types.d.ts.map +1 -0
- package/dist/services/rdap/types.js +6 -0
- package/dist/services/rdap/types.js.map +1 -0
- package/package.json +103 -0
- package/server.json +161 -0
package/README.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>@cyanheads/whois-mcp-server</h1>
|
|
3
|
+
<p><b>Look up domain registration, check availability, fetch DNS records, and resolve IPs and ASNs via RDAP and DNS-over-HTTPS via MCP. STDIO or Streamable HTTP.</b>
|
|
4
|
+
<div>6 Tools</div>
|
|
5
|
+
</p>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<div align="center">
|
|
9
|
+
|
|
10
|
+
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/whois-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/whois-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div align="center">
|
|
15
|
+
|
|
16
|
+
[](https://github.com/cyanheads/whois-mcp-server/releases/latest/download/whois-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=whois-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvd2hvaXMtbWNwLXNlcnZlciJdfQ==) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22whois-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Fwhois-mcp-server%22%5D%7D)
|
|
17
|
+
|
|
18
|
+
[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Tools
|
|
25
|
+
|
|
26
|
+
Six tools covering domain intelligence, DNS, and IP/ASN resolution:
|
|
27
|
+
|
|
28
|
+
| Tool | Description |
|
|
29
|
+
|:-----|:------------|
|
|
30
|
+
| `whois_lookup_domain` | Full domain registration record — registrar, created/expiry dates, nameservers, EPP status, DNSSEC, registrant org |
|
|
31
|
+
| `whois_check_availability` | Check whether a domain is registered or available for registration |
|
|
32
|
+
| `whois_get_dns` | DNS records for any hostname via DNS-over-HTTPS (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA, PTR) |
|
|
33
|
+
| `whois_lookup_ip` | IP or CIDR netblock, org, country, abuse contact, and reverse DNS via RIR RDAP |
|
|
34
|
+
| `whois_lookup_asn` | Resolve an ASN to its org name, country, and RIR source |
|
|
35
|
+
| `whois_get_dossier` | One-call domain triage — registration + DNS in parallel, normalized into a single record with factual signals |
|
|
36
|
+
|
|
37
|
+
### `whois_lookup_domain`
|
|
38
|
+
|
|
39
|
+
Look up a domain's full RDAP registration record.
|
|
40
|
+
|
|
41
|
+
- RDAP-first via IANA auto-bootstrap — automatically selects the correct registry RDAP server per TLD
|
|
42
|
+
- Returns registrar, creation/expiry dates, nameservers, EPP status codes, DNSSEC delegation flag
|
|
43
|
+
- Surfaces `registrant_redacted: true` explicitly when privacy redaction is in effect (standard post-GDPR for gTLDs)
|
|
44
|
+
- Returns `rdap_coverage: false` for TLDs without RDAP coverage rather than silently failing
|
|
45
|
+
- Includes `last_update_of_rdap_db` event timestamp for data freshness transparency
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### `whois_check_availability`
|
|
50
|
+
|
|
51
|
+
Check whether a domain name is registered or available to register.
|
|
52
|
+
|
|
53
|
+
- RDAP 404 = available (`available: true`) — exploits the RDAP spec's intended behavior
|
|
54
|
+
- Returns `available: false` with `registrar` and `expiry_date` when registered
|
|
55
|
+
- Returns `available: null` with `rdap_coverage: false` for TLDs without RDAP — cannot determine availability
|
|
56
|
+
- Optimized for bulk name sweeps — thin response, no unnecessary fields
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### `whois_get_dns`
|
|
61
|
+
|
|
62
|
+
Fetch DNS records via DNS-over-HTTPS.
|
|
63
|
+
|
|
64
|
+
- Cloudflare `1.1.1.1` primary, Google `8.8.8.8` fallback (used for CAA records where Cloudflare returns raw hex)
|
|
65
|
+
- Supports A, AAAA, MX, TXT, NS, CNAME, SOA, CAA, PTR — multiple types in one call
|
|
66
|
+
- Returns records with TTLs and the resolving source (`cloudflare` or `google`)
|
|
67
|
+
- `nxdomain: true` in result (not an error) when the domain doesn't exist in DNS
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### `whois_lookup_ip`
|
|
72
|
+
|
|
73
|
+
Look up an IP address or CIDR block via RIR RDAP.
|
|
74
|
+
|
|
75
|
+
- Auto-routes to the correct RIR (ARIN, RIPE, APNIC, LACNIC, AFRINIC) via IANA IP bootstrap
|
|
76
|
+
- Returns netblock CIDR, org name, country, abuse contact email
|
|
77
|
+
- Fetches PTR (reverse DNS) via DoH as a best-effort step — `ptr: null` on failure, not an error
|
|
78
|
+
- Validates and rejects private/reserved ranges (RFC 1918, loopback, link-local) with a clear error
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### `whois_lookup_asn`
|
|
83
|
+
|
|
84
|
+
Resolve an ASN to its org name, country, and RIR.
|
|
85
|
+
|
|
86
|
+
- Accepts `AS15169` or bare integer `15169` format
|
|
87
|
+
- Routes to the correct RIR RDAP endpoint via IANA ASN bootstrap
|
|
88
|
+
- Returns `name`, `org`, `country`, `rir`, `start_autnum`, `end_autnum`
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `whois_get_dossier`
|
|
93
|
+
|
|
94
|
+
One-call domain triage aggregating registration and DNS data in parallel.
|
|
95
|
+
|
|
96
|
+
- Runs RDAP domain lookup and DoH (A, MX, NS, TXT) in parallel via `Promise.allSettled`
|
|
97
|
+
- Inferred signals: `age_days`, `privacy_redacted`, `registrar`, `ns_provider` (from NS records), `mx_provider` (from MX records)
|
|
98
|
+
- No synthesized risk scores — factual signals only; the agent decides the verdict
|
|
99
|
+
- Partial results surfaced when one leg fails (`source_error` on the failed leg)
|
|
100
|
+
- Both-legs-fail throws `ServiceUnavailable`; individual leg failures are data, not errors
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Features
|
|
105
|
+
|
|
106
|
+
Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
|
|
107
|
+
|
|
108
|
+
- Declarative tool definitions — single file per tool, framework handles registration and validation
|
|
109
|
+
- Unified error handling — handlers throw, framework catches, classifies, and formats
|
|
110
|
+
- Pluggable auth: `none`, `jwt`, `oauth`
|
|
111
|
+
- Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
|
|
112
|
+
- Structured logging with optional OpenTelemetry tracing
|
|
113
|
+
- STDIO and Streamable HTTP transports
|
|
114
|
+
|
|
115
|
+
Domain and network intelligence:
|
|
116
|
+
|
|
117
|
+
- RDAP over HTTPS — no port-43 TCP dependency, runs on Node, Bun, and Cloudflare Workers
|
|
118
|
+
- IANA bootstrap auto-selection — correct registry RDAP server picked per TLD, RIR, or ASN range; bootstrap JSON cached (TTL 24h) in tenant state
|
|
119
|
+
- DNS-over-HTTPS via Cloudflare and Google — resilient dual-provider with per-type routing (Google for CAA; Cloudflare for all others)
|
|
120
|
+
- No API keys required — all sources (IANA, registry RDAP endpoints, RIR RDAP, Cloudflare DoH, Google DoH) are public and keyless
|
|
121
|
+
|
|
122
|
+
Agent-friendly output:
|
|
123
|
+
|
|
124
|
+
- Explicit coverage signals — `rdap_coverage: false` tells the agent the TLD lacks RDAP rather than returning a confusing error
|
|
125
|
+
- Privacy redaction surfaced as a field — `registrant_redacted: true` rather than silently absent contact data
|
|
126
|
+
- Partial failure model — `whois_get_dossier` marks individual legs with `source_error` and continues; only both-legs-fail escalates to an error
|
|
127
|
+
- Factual signals, not scores — `age_days`, `privacy_redacted`, `ns_provider`, `mx_provider` are real data; agents chain into threat-intel or risk servers for enrichment
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Getting started
|
|
132
|
+
|
|
133
|
+
No API keys or accounts required. Add the following to your MCP client configuration file.
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"mcpServers": {
|
|
138
|
+
"whois-mcp-server": {
|
|
139
|
+
"type": "stdio",
|
|
140
|
+
"command": "bunx",
|
|
141
|
+
"args": ["@cyanheads/whois-mcp-server@latest"],
|
|
142
|
+
"env": {
|
|
143
|
+
"MCP_TRANSPORT_TYPE": "stdio",
|
|
144
|
+
"MCP_LOG_LEVEL": "info"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Or with npx (no Bun required):
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"mcpServers": {
|
|
156
|
+
"whois-mcp-server": {
|
|
157
|
+
"type": "stdio",
|
|
158
|
+
"command": "npx",
|
|
159
|
+
"args": ["-y", "@cyanheads/whois-mcp-server@latest"],
|
|
160
|
+
"env": {
|
|
161
|
+
"MCP_TRANSPORT_TYPE": "stdio",
|
|
162
|
+
"MCP_LOG_LEVEL": "info"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Or with Docker:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"mcpServers": {
|
|
174
|
+
"whois-mcp-server": {
|
|
175
|
+
"type": "stdio",
|
|
176
|
+
"command": "docker",
|
|
177
|
+
"args": [
|
|
178
|
+
"run", "-i", "--rm",
|
|
179
|
+
"-e", "MCP_TRANSPORT_TYPE=stdio",
|
|
180
|
+
"ghcr.io/cyanheads/whois-mcp-server:latest"
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
For Streamable HTTP, set the transport and start the server:
|
|
188
|
+
|
|
189
|
+
```sh
|
|
190
|
+
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
|
|
191
|
+
# Server listens at http://localhost:3010/mcp
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Prerequisites
|
|
195
|
+
|
|
196
|
+
- [Bun v1.3.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
197
|
+
- No API keys required — all data sources are public.
|
|
198
|
+
|
|
199
|
+
### Installation
|
|
200
|
+
|
|
201
|
+
1. **Clone the repository:**
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
git clone https://github.com/cyanheads/whois-mcp-server.git
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
2. **Navigate into the directory:**
|
|
208
|
+
|
|
209
|
+
```sh
|
|
210
|
+
cd whois-mcp-server
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
3. **Install dependencies:**
|
|
214
|
+
|
|
215
|
+
```sh
|
|
216
|
+
bun install
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
4. **Configure environment:**
|
|
220
|
+
|
|
221
|
+
```sh
|
|
222
|
+
cp .env.example .env
|
|
223
|
+
# All vars are optional — defaults work for most use cases
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Configuration
|
|
229
|
+
|
|
230
|
+
| Variable | Description | Default |
|
|
231
|
+
|:---------|:------------|:--------|
|
|
232
|
+
| `RDAP_TIMEOUT_MS` | HTTP timeout for RDAP requests in milliseconds. | `5000` |
|
|
233
|
+
| `DOH_TIMEOUT_MS` | HTTP timeout for DNS-over-HTTPS requests in milliseconds. | `3000` |
|
|
234
|
+
| `RDAP_MAX_RETRIES` | Max retry attempts on transient RDAP failures. | `2` |
|
|
235
|
+
| `DOH_MAX_RETRIES` | Max retry attempts on transient DoH failures. | `2` |
|
|
236
|
+
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
|
|
237
|
+
| `MCP_HTTP_PORT` | Port for HTTP server. | `3010` |
|
|
238
|
+
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
239
|
+
| `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
|
|
240
|
+
| `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
|
|
241
|
+
|
|
242
|
+
See [`.env.example`](./.env.example) for the full list of optional overrides.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Running the server
|
|
247
|
+
|
|
248
|
+
### Local development
|
|
249
|
+
|
|
250
|
+
- **Build and run:**
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
bun run rebuild
|
|
254
|
+
bun run start:stdio
|
|
255
|
+
# or
|
|
256
|
+
bun run start:http
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- **Run checks and tests:**
|
|
260
|
+
|
|
261
|
+
```sh
|
|
262
|
+
bun run devcheck # Lint, format, typecheck, security
|
|
263
|
+
bun run test # Vitest test suite
|
|
264
|
+
bun run lint:mcp # Validate MCP definitions against spec
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Docker
|
|
268
|
+
|
|
269
|
+
```sh
|
|
270
|
+
docker build -t whois-mcp-server .
|
|
271
|
+
docker run --rm -p 3010:3010 whois-mcp-server
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `/var/log/whois-mcp-server`. OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Project structure
|
|
279
|
+
|
|
280
|
+
| Path | Purpose |
|
|
281
|
+
|:-----|:--------|
|
|
282
|
+
| `src/index.ts` | `createApp()` entry point — registers tools and inits services. |
|
|
283
|
+
| `src/config/` | Server-specific environment variable parsing and validation (Zod). |
|
|
284
|
+
| `src/services/rdap/` | RDAP client — IANA bootstrap cache, domain/IP/ASN lookup, retry. |
|
|
285
|
+
| `src/services/doh/` | DNS-over-HTTPS client — Cloudflare primary, Google fallback. |
|
|
286
|
+
| `src/mcp-server/tools/` | Tool definitions (`*.tool.ts`). |
|
|
287
|
+
| `tests/` | Vitest tests mirroring `src/`. |
|
|
288
|
+
| `docs/` | Design and API reference documents. |
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Development guide
|
|
293
|
+
|
|
294
|
+
See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
|
|
295
|
+
|
|
296
|
+
- Handlers throw, framework catches — no `try/catch` in tool logic
|
|
297
|
+
- Use `ctx.log` for request-scoped logging, `ctx.state` for tenant-scoped storage (IANA bootstrap cache)
|
|
298
|
+
- Register new tools via `src/index.ts` tools array
|
|
299
|
+
- Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Contributing
|
|
304
|
+
|
|
305
|
+
Issues and pull requests are welcome. Run checks and tests before submitting:
|
|
306
|
+
|
|
307
|
+
```sh
|
|
308
|
+
bun run devcheck
|
|
309
|
+
bun run test
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## License
|
|
315
|
+
|
|
316
|
+
Apache-2.0 — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Initial public release — 6 RDAP + DoH tools for domain registration, availability, DNS records, IP netblock, ASN, and domain dossier; TXT record prompt-injection hardening"
|
|
3
|
+
breaking: false
|
|
4
|
+
security: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.1.1 — 2026-06-05
|
|
8
|
+
|
|
9
|
+
Initial public release of `@cyanheads/whois-mcp-server`. Provides 6 MCP tools over [RDAP](https://www.iana.org/rdap) (via IANA bootstrap) and [DNS-over-HTTPS](https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-https/) (Cloudflare primary, Google fallback):
|
|
10
|
+
|
|
11
|
+
- **`whois_lookup_domain`** — domain registration record: registrar, created/expiry dates, nameservers, EPP status codes, DNSSEC flag, registrant org
|
|
12
|
+
- **`whois_check_availability`** — domain availability check via RDAP 404 signal
|
|
13
|
+
- **`whois_get_dns`** — DNS records via DoH (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA, PTR)
|
|
14
|
+
- **`whois_lookup_ip`** — IP/CIDR netblock, org, abuse contact via RIR RDAP
|
|
15
|
+
- **`whois_lookup_asn`** — ASN to org/RIR resolution via RIR RDAP
|
|
16
|
+
- **`whois_get_dossier`** — one-call domain triage: registration + DNS records fetched in parallel
|
|
17
|
+
|
|
18
|
+
## Added
|
|
19
|
+
|
|
20
|
+
- **`whois_lookup_domain`** — RDAP domain lookup with IANA auto-bootstrap; returns registrar, dates, nameservers, EPP status, DNSSEC, and registrant org (where not privacy-redacted)
|
|
21
|
+
- **`whois_check_availability`** — checks domain availability by interpreting RDAP 404 as unregistered; falls back to a registration hint when RDAP coverage is absent for the TLD
|
|
22
|
+
- **`whois_get_dns`** — DNS record fetch via Cloudflare DoH (primary) / Google DoH (fallback); supports A, AAAA, MX, TXT, NS, CNAME, SOA, CAA, PTR record types
|
|
23
|
+
- **`whois_lookup_ip`** — resolves any IPv4/IPv6 address or CIDR prefix to its RIR netblock record (org, country, abuse contact) via the appropriate RIR's RDAP endpoint
|
|
24
|
+
- **`whois_lookup_asn`** — resolves an AS number to org name, country, and RIR via RIR RDAP
|
|
25
|
+
- **`whois_get_dossier`** — parallel domain triage tool combining `whois_lookup_domain` + `whois_get_dns` in a single call; includes derived signals (hosting provider guess, SPF/DMARC/DKIM presence, registrar-lock status)
|
|
26
|
+
- **RDAP service** (`src/services/rdap/`) — IANA bootstrap cache (TTL via `ctx.state`), domain/IP/ASN lookup, RIR routing, normalized types
|
|
27
|
+
- **DoH service** (`src/services/doh/`) — Cloudflare-primary / Google-fallback DNS-over-HTTPS client, all record types, normalized types
|
|
28
|
+
- **Server config** (`src/config/server-config.ts`) — `RDAP_TIMEOUT_MS`, `DOH_TIMEOUT_MS`, `RDAP_MAX_RETRIES`, `DOH_MAX_RETRIES` env vars
|
|
29
|
+
|
|
30
|
+
## Security
|
|
31
|
+
|
|
32
|
+
- **TXT record prompt-injection hardening** — DNS TXT record values are attacker-controlled free-text; `whois_get_dns` and `whois_get_dossier` now backtick-fence every TXT value in `format()` output before it reaches the LLM context, preventing embedded instructions from executing as prompt content
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
# FORMAT REFERENCE — do not edit. Copy this file to
|
|
3
|
+
# `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.8.x/0.8.6.md`)
|
|
4
|
+
# to author a new release. Set that file's H1 to `# <version> — YYYY-MM-DD`
|
|
5
|
+
# with a concrete date.
|
|
6
|
+
|
|
7
|
+
# Required. One-line GitHub Release-style headline. 350 character cap.
|
|
8
|
+
# Default short and scannable. Don't pad, don't stitch unrelated changes with
|
|
9
|
+
# semicolons — pick the headline. Quotes required: unquoted YAML treats `: `
|
|
10
|
+
# inside the value as a key separator and fails GitHub's strict parser.
|
|
11
|
+
summary: ""
|
|
12
|
+
|
|
13
|
+
# Set `true` when consumers must change code to upgrade: API removals,
|
|
14
|
+
# signature changes, config renames, behavior changes that break existing
|
|
15
|
+
# usage. Flagged as `Breaking` in the rollup.
|
|
16
|
+
breaking: false
|
|
17
|
+
|
|
18
|
+
# Set `true` if this release contains any security fix. Pairs with the
|
|
19
|
+
# `## Security` section below. Flagged as `Security` in the rollup so
|
|
20
|
+
# users can triage upgrade urgency at a glance.
|
|
21
|
+
security: false
|
|
22
|
+
|
|
23
|
+
# Optional free-form notes for maintenance agents processing this release.
|
|
24
|
+
# Not rendered in CHANGELOG — consumed by agents running `maintenance` on
|
|
25
|
+
# downstream servers. Use for adoption instructions that don't fit the
|
|
26
|
+
# human-facing sections: new files to create, fields to populate, one-time
|
|
27
|
+
# migration steps. Omit the field entirely when there's nothing to say.
|
|
28
|
+
# agent-notes: |
|
|
29
|
+
# <instructions for downstream maintenance agents>
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# <version> — YYYY-MM-DD
|
|
33
|
+
|
|
34
|
+
<!--
|
|
35
|
+
AUTHORING GUIDE — applies to the new per-version file you create from this
|
|
36
|
+
template.
|
|
37
|
+
|
|
38
|
+
Audience: someone scanning release notes to decide what affects them. Lead
|
|
39
|
+
each bullet with the symbol or concept name in **bold** so they can skip
|
|
40
|
+
what's irrelevant and zoom in on what's not.
|
|
41
|
+
|
|
42
|
+
Tone: terse, fact-dense, not verbose. Default to one sentence per bullet —
|
|
43
|
+
name the symbol, state what changed, stop. Use a second sentence only when
|
|
44
|
+
it carries weight. If a bullet feels long, it is.
|
|
45
|
+
|
|
46
|
+
Cut: mechanism walkthroughs (those belong in JSDoc, CLAUDE.md/AGENTS.md, or the
|
|
47
|
+
relevant skill), ceremonial framings ("This release introduces…",
|
|
48
|
+
backwards-compat paragraphs), file-by-file test enumerations, internal
|
|
49
|
+
implementation notes. Prefer code/symbol names over English re-explanations.
|
|
50
|
+
|
|
51
|
+
Narrative intro: skip by default. Add one short sentence only when the
|
|
52
|
+
release theme genuinely needs framing the bullets can't carry.
|
|
53
|
+
|
|
54
|
+
Sections: Keep a Changelog order — Added, Changed, Deprecated, Removed,
|
|
55
|
+
Fixed, Security. Include only sections with entries; delete the rest
|
|
56
|
+
(including the commented-out scaffolding below). Don't ship empty headers.
|
|
57
|
+
|
|
58
|
+
Include: every distinct fact a reader needs to adopt or audit the release —
|
|
59
|
+
new exports, signatures, lint rule IDs, env vars, breaking changes, version
|
|
60
|
+
bumps on shipped skills. Nothing more.
|
|
61
|
+
|
|
62
|
+
Links: link issues, PRs, docs, or skills where they help a reader jump to
|
|
63
|
+
context. Once per item per entry — don't re-link the same issue in summary,
|
|
64
|
+
narrative, and bullet. Skip links for inline symbol names; code spans speak
|
|
65
|
+
for themselves.
|
|
66
|
+
|
|
67
|
+
Issue/PR URLs: use full URLs. GitHub's bare `#NN` auto-link only resolves
|
|
68
|
+
inside its own UI, not in npm reads or local editors.
|
|
69
|
+
|
|
70
|
+
[#38](https://github.com/cyanheads/mcp-ts-core/issues/38) ← issue
|
|
71
|
+
[#42](https://github.com/cyanheads/mcp-ts-core/pull/42) ← PR
|
|
72
|
+
|
|
73
|
+
Verify numbers exist before linking (`gh issue view NN`, `gh pr view NN`).
|
|
74
|
+
Never speculate on a future number — `#42` for an upcoming PR silently
|
|
75
|
+
resolves to whatever real item already owns 42, and timeline previews pull
|
|
76
|
+
in that unrelated item's metadata.
|
|
77
|
+
|
|
78
|
+
TAG ANNOTATIONS — the annotated tag body renders as the GitHub Release body
|
|
79
|
+
via `gh release create --notes-from-tag`. The tag is a derivative of this
|
|
80
|
+
changelog entry — a condensed, scannable version, not a copy. Format:
|
|
81
|
+
|
|
82
|
+
<theme — omit version number, GitHub prepends it>
|
|
83
|
+
← blank line
|
|
84
|
+
<1-2 sentence context: what this release does>
|
|
85
|
+
← blank line
|
|
86
|
+
Dependency bumps: ← section header
|
|
87
|
+
← blank line
|
|
88
|
+
- `@cyanheads/mcp-ts-core` ^0.9.1 → ^0.9.6 ← bullet
|
|
89
|
+
← blank line
|
|
90
|
+
Changed: ← only sections with entries
|
|
91
|
+
← blank line
|
|
92
|
+
- `format()` output includes `query` in text mode
|
|
93
|
+
← blank line
|
|
94
|
+
Added:
|
|
95
|
+
← blank line
|
|
96
|
+
- `manifest.json` scaffolded for MCPB bundle support
|
|
97
|
+
- Install badges (Claude Desktop, Cursor, VS Code)
|
|
98
|
+
← blank line
|
|
99
|
+
<N> tests pass; `bun run devcheck` clean. ← footer
|
|
100
|
+
|
|
101
|
+
Never a flat comma-separated string. Always structured markdown with
|
|
102
|
+
sections. The tag must scan well as a rendered GitHub Release page.
|
|
103
|
+
-->
|
|
104
|
+
|
|
105
|
+
## Added
|
|
106
|
+
|
|
107
|
+
-
|
|
108
|
+
|
|
109
|
+
## Changed
|
|
110
|
+
|
|
111
|
+
-
|
|
112
|
+
|
|
113
|
+
<!-- ## Deprecated
|
|
114
|
+
|
|
115
|
+
- -->
|
|
116
|
+
|
|
117
|
+
<!-- ## Removed
|
|
118
|
+
|
|
119
|
+
- -->
|
|
120
|
+
|
|
121
|
+
## Fixed
|
|
122
|
+
|
|
123
|
+
-
|
|
124
|
+
|
|
125
|
+
<!-- ## Security
|
|
126
|
+
|
|
127
|
+
- -->
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-specific environment configuration for whois-mcp-server.
|
|
3
|
+
* @module config/server-config
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
declare const ServerConfigSchema: z.ZodObject<{
|
|
7
|
+
rdapTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
8
|
+
dohTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
9
|
+
rdapMaxRetries: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
10
|
+
dohMaxRetries: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
13
|
+
/** Returns the parsed server config, lazy-initialized on first call. */
|
|
14
|
+
export declare function getServerConfig(): ServerConfig;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=server-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,QAAA,MAAM,kBAAkB;;;;;iBAWtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,wEAAwE;AACxE,wBAAgB,eAAe,IAAI,YAAY,CAQ9C"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-specific environment configuration for whois-mcp-server.
|
|
3
|
+
* @module config/server-config
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
7
|
+
const ServerConfigSchema = z.object({
|
|
8
|
+
rdapTimeoutMs: z.coerce.number().default(5000).describe('HTTP timeout for RDAP requests in ms.'),
|
|
9
|
+
dohTimeoutMs: z.coerce.number().default(3000).describe('HTTP timeout for DoH requests in ms.'),
|
|
10
|
+
rdapMaxRetries: z.coerce
|
|
11
|
+
.number()
|
|
12
|
+
.default(2)
|
|
13
|
+
.describe('Max retry attempts on transient RDAP failures.'),
|
|
14
|
+
dohMaxRetries: z.coerce
|
|
15
|
+
.number()
|
|
16
|
+
.default(2)
|
|
17
|
+
.describe('Max retry attempts on transient DoH failures.'),
|
|
18
|
+
});
|
|
19
|
+
let _config;
|
|
20
|
+
/** Returns the parsed server config, lazy-initialized on first call. */
|
|
21
|
+
export function getServerConfig() {
|
|
22
|
+
_config ??= parseEnvConfig(ServerConfigSchema, {
|
|
23
|
+
rdapTimeoutMs: 'RDAP_TIMEOUT_MS',
|
|
24
|
+
dohTimeoutMs: 'DOH_TIMEOUT_MS',
|
|
25
|
+
rdapMaxRetries: 'RDAP_MAX_RETRIES',
|
|
26
|
+
dohMaxRetries: 'DOH_MAX_RETRIES',
|
|
27
|
+
});
|
|
28
|
+
return _config;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=server-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC;IAChG,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC9F,cAAc,EAAE,CAAC,CAAC,MAAM;SACrB,MAAM,EAAE;SACR,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,gDAAgD,CAAC;IAC7D,aAAa,EAAE,CAAC,CAAC,MAAM;SACpB,MAAM,EAAE;SACR,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,+CAA+C,CAAC;CAC7D,CAAC,CAAC;AAIH,IAAI,OAAiC,CAAC;AAEtC,wEAAwE;AACxE,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,cAAc,CAAC,kBAAkB,EAAE;QAC7C,aAAa,EAAE,iBAAiB;QAChC,YAAY,EAAE,gBAAgB;QAC9B,cAAc,EAAE,kBAAkB;QAClC,aAAa,EAAE,iBAAiB;KACjC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview whois-mcp-server MCP server entry point.
|
|
4
|
+
* @module index
|
|
5
|
+
*/
|
|
6
|
+
import { createApp } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { whoisCheckAvailability } from './mcp-server/tools/definitions/whois-check-availability.tool.js';
|
|
8
|
+
import { whoisGetDns } from './mcp-server/tools/definitions/whois-get-dns.tool.js';
|
|
9
|
+
import { whoisGetDossier } from './mcp-server/tools/definitions/whois-get-dossier.tool.js';
|
|
10
|
+
import { whoisLookupAsn } from './mcp-server/tools/definitions/whois-lookup-asn.tool.js';
|
|
11
|
+
import { whoisLookupDomain } from './mcp-server/tools/definitions/whois-lookup-domain.tool.js';
|
|
12
|
+
import { whoisLookupIp } from './mcp-server/tools/definitions/whois-lookup-ip.tool.js';
|
|
13
|
+
import { initDohService } from './services/doh/doh-service.js';
|
|
14
|
+
import { initRdapService } from './services/rdap/rdap-service.js';
|
|
15
|
+
await createApp({
|
|
16
|
+
tools: [
|
|
17
|
+
whoisLookupDomain,
|
|
18
|
+
whoisCheckAvailability,
|
|
19
|
+
whoisGetDns,
|
|
20
|
+
whoisLookupIp,
|
|
21
|
+
whoisLookupAsn,
|
|
22
|
+
whoisGetDossier,
|
|
23
|
+
],
|
|
24
|
+
resources: [],
|
|
25
|
+
prompts: [],
|
|
26
|
+
instructions: 'whois-mcp-server: domain and IP intelligence via RDAP and DNS-over-HTTPS. No API keys required.\n' +
|
|
27
|
+
'- whois_lookup_domain: full registration record (registrar, dates, status, nameservers)\n' +
|
|
28
|
+
'- whois_check_availability: is a domain available to register? (RDAP 404 = available)\n' +
|
|
29
|
+
'- whois_get_dns: DNS records for any hostname (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA, PTR)\n' +
|
|
30
|
+
'- whois_lookup_ip: IP/CIDR netblock, org, abuse contact, and PTR via RIR RDAP\n' +
|
|
31
|
+
'- whois_lookup_asn: ASN to org/RIR resolution\n' +
|
|
32
|
+
'- whois_get_dossier: one-call domain triage — registration + DNS in parallel with inferred signals',
|
|
33
|
+
setup(core) {
|
|
34
|
+
initRdapService(core.config, core.storage);
|
|
35
|
+
initDohService(core.config, core.storage);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iEAAiE,CAAC;AACzG,OAAO,EAAE,WAAW,EAAE,MAAM,sDAAsD,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4DAA4D,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,wDAAwD,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,SAAS,CAAC;IACd,KAAK,EAAE;QACL,iBAAiB;QACjB,sBAAsB;QACtB,WAAW;QACX,aAAa;QACb,cAAc;QACd,eAAe;KAChB;IACD,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,mGAAmG;QACnG,2FAA2F;QAC3F,yFAAyF;QACzF,8FAA8F;QAC9F,iFAAiF;QACjF,iDAAiD;QACjD,oGAAoG;IACtG,KAAK,CAAC,IAAI;QACR,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared FQDN validation used across tool handlers.
|
|
3
|
+
* @module mcp-server/tools/definitions/_fqdn
|
|
4
|
+
*/
|
|
5
|
+
/** Simple FQDN validation: labels separated by dots, no consecutive dots, length limits */
|
|
6
|
+
export declare function isValidFqdn(domain: string): boolean;
|
|
7
|
+
//# sourceMappingURL=_fqdn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_fqdn.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_fqdn.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2FAA2F;AAC3F,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQnD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared FQDN validation used across tool handlers.
|
|
3
|
+
* @module mcp-server/tools/definitions/_fqdn
|
|
4
|
+
*/
|
|
5
|
+
/** Simple FQDN validation: labels separated by dots, no consecutive dots, length limits */
|
|
6
|
+
export function isValidFqdn(domain) {
|
|
7
|
+
if (!domain || domain.length > 253)
|
|
8
|
+
return false;
|
|
9
|
+
const labels = domain.split('.');
|
|
10
|
+
if (labels.length < 2)
|
|
11
|
+
return false;
|
|
12
|
+
return labels.every((label) => {
|
|
13
|
+
if (!label || label.length > 63)
|
|
14
|
+
return false;
|
|
15
|
+
return /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$|^[a-zA-Z0-9]$/.test(label);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=_fqdn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_fqdn.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/_fqdn.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2FAA2F;AAC3F,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;QAC9C,OAAO,wDAAwD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview whois_check_availability tool — domain availability check via RDAP 404 semantics.
|
|
3
|
+
* @module mcp-server/tools/definitions/whois-check-availability.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const whoisCheckAvailability: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
domain: z.ZodString;
|
|
9
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
10
|
+
domain: z.ZodString;
|
|
11
|
+
available: z.ZodNullable<z.ZodBoolean>;
|
|
12
|
+
rdap_coverage: z.ZodBoolean;
|
|
13
|
+
registrar: z.ZodOptional<z.ZodString>;
|
|
14
|
+
expiry_date: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>, readonly [{
|
|
16
|
+
readonly reason: "invalid_domain";
|
|
17
|
+
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
18
|
+
readonly when: "Input is not a valid FQDN.";
|
|
19
|
+
readonly recovery: "Provide a valid fully-qualified domain name like \"example.com\" or \"sub.example.org\".";
|
|
20
|
+
}, {
|
|
21
|
+
readonly reason: "rdap_no_coverage";
|
|
22
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
23
|
+
readonly when: "TLD has no RDAP server — available is null, cannot determine registration status.";
|
|
24
|
+
readonly recovery: "This TLD has no RDAP coverage; availability cannot be determined programmatically.";
|
|
25
|
+
}], undefined>;
|
|
26
|
+
//# sourceMappingURL=whois-check-availability.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whois-check-availability.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-check-availability.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;cA4GjC,CAAC"}
|