@cyanheads/whois-mcp-server 0.1.5 → 0.2.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.
Files changed (52) hide show
  1. package/AGENTS.md +27 -14
  2. package/CLAUDE.md +27 -14
  3. package/Dockerfile +48 -34
  4. package/README.md +30 -35
  5. package/changelog/0.1.x/0.1.6.md +41 -0
  6. package/changelog/0.2.x/0.2.0.md +40 -0
  7. package/dist/app.d.ts +67 -26
  8. package/dist/app.d.ts.map +1 -1
  9. package/dist/app.js +7 -5
  10. package/dist/app.js.map +1 -1
  11. package/dist/mcp-server/tools/definitions/_fqdn.d.ts +9 -3
  12. package/dist/mcp-server/tools/definitions/_fqdn.d.ts.map +1 -1
  13. package/dist/mcp-server/tools/definitions/_fqdn.js +10 -14
  14. package/dist/mcp-server/tools/definitions/_fqdn.js.map +1 -1
  15. package/dist/mcp-server/tools/definitions/whois-check-availability.tool.d.ts +11 -5
  16. package/dist/mcp-server/tools/definitions/whois-check-availability.tool.d.ts.map +1 -1
  17. package/dist/mcp-server/tools/definitions/whois-check-availability.tool.js +25 -40
  18. package/dist/mcp-server/tools/definitions/whois-check-availability.tool.js.map +1 -1
  19. package/dist/mcp-server/tools/definitions/whois-get-dns.tool.d.ts +23 -4
  20. package/dist/mcp-server/tools/definitions/whois-get-dns.tool.d.ts.map +1 -1
  21. package/dist/mcp-server/tools/definitions/whois-get-dns.tool.js +44 -28
  22. package/dist/mcp-server/tools/definitions/whois-get-dns.tool.js.map +1 -1
  23. package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.d.ts +0 -5
  24. package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.d.ts.map +1 -1
  25. package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.js +58 -53
  26. package/dist/mcp-server/tools/definitions/whois-get-dossier.tool.js.map +1 -1
  27. package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.d.ts +2 -2
  28. package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.d.ts.map +1 -1
  29. package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.js +9 -5
  30. package/dist/mcp-server/tools/definitions/whois-lookup-asn.tool.js.map +1 -1
  31. package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.d.ts +16 -9
  32. package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.d.ts.map +1 -1
  33. package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.js +60 -24
  34. package/dist/mcp-server/tools/definitions/whois-lookup-domain.tool.js.map +1 -1
  35. package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.d.ts +16 -2
  36. package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.d.ts.map +1 -1
  37. package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.js +44 -17
  38. package/dist/mcp-server/tools/definitions/whois-lookup-ip.tool.js.map +1 -1
  39. package/dist/services/doh/doh-service.d.ts +3 -3
  40. package/dist/services/doh/doh-service.d.ts.map +1 -1
  41. package/dist/services/doh/doh-service.js +71 -24
  42. package/dist/services/doh/doh-service.js.map +1 -1
  43. package/dist/services/doh/types.d.ts +16 -0
  44. package/dist/services/doh/types.d.ts.map +1 -1
  45. package/dist/services/rdap/rdap-service.d.ts +20 -8
  46. package/dist/services/rdap/rdap-service.d.ts.map +1 -1
  47. package/dist/services/rdap/rdap-service.js +200 -145
  48. package/dist/services/rdap/rdap-service.js.map +1 -1
  49. package/dist/services/rdap/types.d.ts +32 -2
  50. package/dist/services/rdap/types.d.ts.map +1 -1
  51. package/package.json +14 -12
  52. package/server.json +11 -25
@@ -5,22 +5,54 @@
5
5
  import { tool, z } from '@cyanheads/mcp-ts-core';
6
6
  import { JsonRpcErrorCode, McpError } from '@cyanheads/mcp-ts-core/errors';
7
7
  import { getRdapService } from '../../../services/rdap/rdap-service.js';
8
- import { isValidFqdn } from './_fqdn.js';
8
+ import { REGISTRATION_NAME_PATTERN } from './_fqdn.js';
9
9
  export const whoisLookupDomain = tool('whois_lookup_domain', {
10
10
  title: 'Domain Registration Lookup',
11
11
  description: "Look up a domain's registration record — registrar, created/expiry dates, nameservers, EPP status codes, " +
12
- 'DNSSEC flag, and registrant org (where not privacy-redacted). Uses RDAP via IANA bootstrap to auto-select ' +
12
+ 'provider DNSSEC evidence, and public registrant organization independently of contact redaction. Uses IANA bootstrap to select ' +
13
13
  'the correct per-TLD RDAP server, returning one normalized shape regardless of TLD. When the TLD has no RDAP ' +
14
- 'coverage, returns rdap_coverage: false. If the domain is not registered, throws domain_not_found — use ' +
15
- 'whois_check_availability to test availability without triggering an error.',
14
+ 'coverage, throws rdap_no_coverage. A missing registry object throws domain_not_found; ' +
15
+ 'whois_check_availability returns record status without an eligibility guarantee. include_registrar opts into one ' +
16
+ 'bounded registrar referral with separate contact detail; registry fields remain authoritative.',
16
17
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
17
18
  input: z.object({
19
+ include_registrar: z
20
+ .boolean()
21
+ .default(false)
22
+ .describe('Follow one guarded registrar RDAP referral for optional contact detail. Registry fields remain authoritative; failed detail is disclosed without discarding the registry record.'),
18
23
  domain: z
19
24
  .string()
25
+ .max(253)
26
+ .regex(REGISTRATION_NAME_PATTERN, 'Provide a dot-separated ASCII hostname such as example.com; labels are 1–63 characters, without underscores, whitespace or a root dot.')
20
27
  .describe('Fully qualified domain name to look up (e.g., "example.com", "github.com"). ' +
21
28
  'Must be a valid FQDN — labels separated by dots, each label up to 63 chars.'),
22
29
  }),
23
30
  output: z.object({
31
+ registrar_detail: z
32
+ .object({
33
+ status: z
34
+ .enum(['found', 'no_referral', 'failed'])
35
+ .describe('Optional registrar lookup outcome.'),
36
+ source: z
37
+ .string()
38
+ .optional()
39
+ .describe('Registrar RDAP source URL, or attempted referral on failure.'),
40
+ registrant_org: z
41
+ .string()
42
+ .optional()
43
+ .describe('Public registrar-reported organization, independent of contact redaction.'),
44
+ registrant_redacted: z
45
+ .boolean()
46
+ .nullable()
47
+ .optional()
48
+ .describe('Explicit registrar privacy evidence; null when absent.'),
49
+ source_error: z
50
+ .string()
51
+ .optional()
52
+ .describe('Optional detail failure; registry fields remain usable.'),
53
+ })
54
+ .optional()
55
+ .describe('Registrar contact detail only when include_registrar is true.'),
24
56
  domain: z.string().describe('Normalized domain name (lowercased).'),
25
57
  rdap_coverage: z
26
58
  .boolean()
@@ -45,22 +77,20 @@ export const whoisLookupDomain = tool('whois_lookup_domain', {
45
77
  .array(z.string())
46
78
  .describe('EPP status codes (e.g., clientTransferProhibited, serverDeleteProhibited).'),
47
79
  nameservers: z.array(z.string()).describe('Authoritative nameservers for this domain.'),
48
- dnssec_signed: z.boolean().describe('True when the domain has DNSSEC delegation signed.'),
80
+ dnssec_signed: z
81
+ .boolean()
82
+ .nullable()
83
+ .describe('Provider delegationSigned value; null when absent.'),
49
84
  registrant_org: z
50
85
  .string()
51
86
  .optional()
52
- .describe('Registrant organization name. Omitted when privacy-redacted.'),
87
+ .describe('Public registrant organization from jCard org. Omitted when absent or a placeholder; contact redaction is independent.'),
53
88
  registrant_redacted: z
54
89
  .boolean()
55
- .describe('True when registrant contact data is privacy-redacted (common post-GDPR).'),
90
+ .nullable()
91
+ .describe('True for explicit registrant redaction evidence; null when privacy evidence is absent.'),
56
92
  }),
57
93
  errors: [
58
- {
59
- reason: 'invalid_domain',
60
- code: JsonRpcErrorCode.ValidationError,
61
- when: 'Input is not a valid FQDN.',
62
- recovery: 'Provide a valid fully-qualified domain name like "example.com" or "sub.example.org".',
63
- },
64
94
  {
65
95
  reason: 'rdap_no_coverage',
66
96
  code: JsonRpcErrorCode.NotFound,
@@ -70,20 +100,15 @@ export const whoisLookupDomain = tool('whois_lookup_domain', {
70
100
  {
71
101
  reason: 'domain_not_found',
72
102
  code: JsonRpcErrorCode.NotFound,
73
- when: 'RDAP server returned 404 — domain is not registered.',
74
- recovery: 'The domain is not registered. Use whois_check_availability to confirm availability for registration.',
103
+ when: 'RDAP server returned 404 — no domain record found.',
104
+ recovery: 'Use whois_check_availability for record status; a missing record does not establish registration eligibility.',
75
105
  },
76
106
  ],
77
107
  async handler(input, ctx) {
78
- if (!isValidFqdn(input.domain)) {
79
- throw ctx.fail('invalid_domain', `"${input.domain}" is not a valid FQDN.`, {
80
- ...ctx.recoveryFor('invalid_domain'),
81
- });
82
- }
83
108
  ctx.log.info('RDAP domain lookup', { domain: input.domain });
84
109
  let record;
85
110
  try {
86
- record = await getRdapService().lookupDomain(input.domain, ctx);
111
+ record = await getRdapService().lookupDomain(input.domain, ctx, input.include_registrar);
87
112
  }
88
113
  catch (err) {
89
114
  // Re-throw domain_not_found with recovery hint from the typed contract
@@ -99,7 +124,6 @@ export const whoisLookupDomain = tool('whois_lookup_domain', {
99
124
  if (!record.rdap_coverage) {
100
125
  throw ctx.fail('rdap_no_coverage', `No RDAP server found for the TLD of "${input.domain}".`, {
101
126
  domain: input.domain,
102
- ...ctx.recoveryFor('rdap_no_coverage'),
103
127
  });
104
128
  }
105
129
  return record;
@@ -124,14 +148,26 @@ export const whoisLookupDomain = tool('whois_lookup_domain', {
124
148
  lines.push(`**RDAP DB Updated:** ${result.rdap_last_updated}`);
125
149
  if (result.handle)
126
150
  lines.push(`**Handle:** ${result.handle}`);
127
- lines.push(`**DNSSEC:** ${result.dnssec_signed ? 'Signed' : 'Not signed'}`);
128
- lines.push(`**Registrant Redacted:** ${result.registrant_redacted ? 'Yes (GDPR/privacy)' : 'No'}`);
151
+ lines.push(`**DNSSEC:** ${result.dnssec_signed === null ? 'Unknown' : result.dnssec_signed ? 'Signed' : 'Not signed'}`);
152
+ lines.push(`**Registrant Redacted:** ${result.registrant_redacted === null ? 'Unknown' : result.registrant_redacted ? 'Yes (GDPR/privacy)' : 'No'}`);
129
153
  if (result.registrant_org)
130
154
  lines.push(`**Registrant Org:** ${result.registrant_org}`);
131
155
  if (result.status.length > 0)
132
156
  lines.push(`**Status:** ${result.status.join(', ')}`);
133
157
  if (result.nameservers.length > 0)
134
158
  lines.push(`**Nameservers:** ${result.nameservers.join(', ')}`);
159
+ if (result.registrar_detail) {
160
+ const detail = result.registrar_detail;
161
+ lines.push(`**Registrar Detail:** ${detail.status}`);
162
+ if (detail.source)
163
+ lines.push(`**Registrar Source:** ${detail.source}`);
164
+ if (detail.registrant_org)
165
+ lines.push(`**Registrar Registrant Org:** ${detail.registrant_org}`);
166
+ if (detail.status === 'found')
167
+ lines.push(`**Registrar Registrant Redacted:** ${detail.registrant_redacted === null ? 'Unknown' : detail.registrant_redacted ? 'Yes' : 'No'}`);
168
+ if (detail.source_error)
169
+ lines.push(`**Registrar Detail Error:** ${detail.source_error}`);
170
+ }
135
171
  return [{ type: 'text', text: lines.join('\n') }];
136
172
  },
137
173
  });
@@ -1 +1 @@
1
- {"version":3,"file":"whois-lookup-domain.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-lookup-domain.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"whois-lookup-domain.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-lookup-domain.tool.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ export declare const whoisLookupIp: import("@cyanheads/mcp-ts-core").ToolDefinit
12
12
  start_address: z.ZodOptional<z.ZodString>;
13
13
  end_address: z.ZodOptional<z.ZodString>;
14
14
  cidr: z.ZodOptional<z.ZodString>;
15
+ cidrs: z.ZodArray<z.ZodString>;
15
16
  ip_version: z.ZodOptional<z.ZodString>;
16
17
  name: z.ZodOptional<z.ZodString>;
17
18
  type: z.ZodOptional<z.ZodString>;
@@ -19,8 +20,21 @@ export declare const whoisLookupIp: import("@cyanheads/mcp-ts-core").ToolDefinit
19
20
  org_name: z.ZodOptional<z.ZodString>;
20
21
  abuse_email: z.ZodOptional<z.ZodString>;
21
22
  ptr: z.ZodNullable<z.ZodString>;
23
+ ptr_status: z.ZodEnum<{
24
+ failed: "failed";
25
+ found: "found";
26
+ not_found: "not_found";
27
+ }>;
28
+ ptr_source_error: z.ZodOptional<z.ZodString>;
22
29
  rdap_source: z.ZodOptional<z.ZodString>;
23
30
  }, z.core.$strip>, readonly [{
31
+ readonly reason: "ip_no_rdap_route";
32
+ readonly code: JsonRpcErrorCode.NotFound;
33
+ readonly when: "A successfully loaded IANA bootstrap has no covering RIR route.";
34
+ readonly recovery: "Try another address; this range has no RDAP route in the IANA bootstrap.";
35
+ readonly retryable: false;
36
+ readonly thrownBy: "service";
37
+ }, {
24
38
  readonly reason: "invalid_ip";
25
39
  readonly code: JsonRpcErrorCode.ValidationError;
26
40
  readonly when: "Input is not a valid IPv4, IPv6, or CIDR address.";
@@ -28,8 +42,8 @@ export declare const whoisLookupIp: import("@cyanheads/mcp-ts-core").ToolDefinit
28
42
  }, {
29
43
  readonly reason: "private_range";
30
44
  readonly code: JsonRpcErrorCode.ValidationError;
31
- readonly when: "Input is a private or reserved range — no RIR RDAP record exists for it.";
32
- readonly recovery: "Use a public, globally-routable IP address. RFC 1918, loopback, and link-local addresses have no RIR records.";
45
+ readonly when: "The numeric address falls within the server’s explicit excluded ranges.";
46
+ readonly recovery: "Choose an address outside the excluded ranges listed in this tool’s description.";
33
47
  readonly thrownBy: "service";
34
48
  }, {
35
49
  readonly reason: "ip_not_found";
@@ -1 +1 @@
1
- {"version":3,"file":"whois-lookup-ip.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-lookup-ip.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,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgHxB,CAAC"}
1
+ {"version":3,"file":"whois-lookup-ip.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-lookup-ip.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA6IxB,CAAC"}
@@ -6,25 +6,37 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
6
6
  import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
7
7
  import { getDohService } from '../../../services/doh/doh-service.js';
8
8
  import { getRdapService, ipv4ToPtr, ipv6ToPtr, validateIp } from '../../../services/rdap/rdap-service.js';
9
+ import { IP_PATTERN } from './_fqdn.js';
9
10
  export const whoisLookupIp = tool('whois_lookup_ip', {
10
11
  title: 'IP Address / Network Lookup',
11
12
  description: 'Look up an IP address or CIDR block via RIR RDAP (ARIN, RIPE, APNIC, LACNIC, AFRINIC — auto-routed ' +
12
- 'via IANA bootstrap). Returns netblock, org, country, CIDR, abuse contact email, and reverse DNS (PTR) ' +
13
- 'via DoH. PTR is best-effort — failure returns ptr: null. Private/reserved ranges (RFC 1918, loopback, ' +
14
- 'link-local) return a validation error — no RIR RDAP record exists for them.',
13
+ 'via IANA bootstrap). Returns netblock, org, country, all provider CIDRs, abuse contact email, and reverse DNS (PTR) ' +
14
+ 'via DoH. PTR status distinguishes found, not_found, and failed with ptr_source_error. Alias traversal is limited ' +
15
+ 'to five transitions under one DNS deadline. The base address is queried for CIDR input. ' +
16
+ 'The server excludes IPv4 0/8, 10/8, 100.64/10, 127/8, 169.254/16, 172.16/12, 192.168/16, 255/8 ' +
17
+ 'and IPv6 ::1/128, fc00::/7, fe80::/10. Other special-use addresses remain eligible for lookup.',
15
18
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
16
19
  input: z.object({
17
20
  ip: z
18
21
  .string()
22
+ .min(1)
23
+ .regex(IP_PATTERN, 'Provide an IPv4/IPv6 address with at most one decimal CIDR prefix; no spaces, brackets or zone IDs.')
19
24
  .describe('IPv4 address (e.g., "8.8.8.8"), IPv6 address (e.g., "2001:4860:4860::8888"), or CIDR notation ' +
20
- '(e.g., "192.0.2.0/24"). Private/reserved ranges will return a validation error.'),
25
+ '(e.g., "192.0.2.0/24"). One decimal prefix in 0–32 (IPv4) or 0–128 (IPv6); no whitespace, ' +
26
+ 'zone IDs, or brackets. IPv4-mapped IPv6 uses its embedded IPv4 for lookup and PTR.'),
21
27
  }),
22
28
  output: z.object({
23
29
  ip: z.string().describe('The IP or CIDR queried.'),
24
30
  handle: z.string().optional().describe('RIR handle / object identifier.'),
25
31
  start_address: z.string().optional().describe('Start address of the IP netblock.'),
26
32
  end_address: z.string().optional().describe('End address of the IP netblock.'),
27
- cidr: z.string().optional().describe('CIDR notation of the netblock (e.g., "8.8.8.0/24").'),
33
+ cidr: z
34
+ .string()
35
+ .optional()
36
+ .describe('Provider CIDR only when the allocation has exactly one component.'),
37
+ cidrs: z
38
+ .array(z.string())
39
+ .describe('All provider CIDR components in upstream order; empty when absent.'),
28
40
  ip_version: z.string().optional().describe('IP version: "v4" or "v6".'),
29
41
  name: z.string().optional().describe('Network name assigned by the RIR.'),
30
42
  type: z.string().optional().describe('Network type (e.g., "DIRECT ALLOCATION").'),
@@ -38,12 +50,27 @@ export const whoisLookupIp = tool('whois_lookup_ip', {
38
50
  .string()
39
51
  .nullable()
40
52
  .describe('Reverse DNS hostname (PTR record). Null when PTR lookup fails, returns no answer, or domain is NXDOMAIN.'),
53
+ ptr_status: z
54
+ .enum(['found', 'not_found', 'failed'])
55
+ .describe('PTR outcome: matching hostname, successful absence, or failed resolver/alias traversal.'),
56
+ ptr_source_error: z
57
+ .string()
58
+ .optional()
59
+ .describe('PTR failure explanation; RDAP data remains usable.'),
41
60
  rdap_source: z
42
61
  .string()
43
62
  .optional()
44
63
  .describe('RIR that provided the RDAP data (ARIN, RIPE, APNIC, LACNIC, AFRINIC).'),
45
64
  }),
46
65
  errors: [
66
+ {
67
+ reason: 'ip_no_rdap_route',
68
+ code: JsonRpcErrorCode.NotFound,
69
+ when: 'A successfully loaded IANA bootstrap has no covering RIR route.',
70
+ recovery: 'Try another address; this range has no RDAP route in the IANA bootstrap.',
71
+ retryable: false,
72
+ thrownBy: 'service',
73
+ },
47
74
  {
48
75
  reason: 'invalid_ip',
49
76
  code: JsonRpcErrorCode.ValidationError,
@@ -53,8 +80,8 @@ export const whoisLookupIp = tool('whois_lookup_ip', {
53
80
  {
54
81
  reason: 'private_range',
55
82
  code: JsonRpcErrorCode.ValidationError,
56
- when: 'Input is a private or reserved range — no RIR RDAP record exists for it.',
57
- recovery: 'Use a public, globally-routable IP address. RFC 1918, loopback, and link-local addresses have no RIR records.',
83
+ when: 'The numeric address falls within the server’s explicit excluded ranges.',
84
+ recovery: 'Choose an address outside the excluded ranges listed in this tool’s description.',
58
85
  thrownBy: 'service',
59
86
  },
60
87
  {
@@ -66,21 +93,18 @@ export const whoisLookupIp = tool('whois_lookup_ip', {
66
93
  },
67
94
  ],
68
95
  async handler(input, ctx) {
69
- const { valid } = validateIp(input.ip);
70
- if (!valid) {
71
- throw ctx.fail('invalid_ip', `"${input.ip}" is not a valid IPv4, IPv6, or CIDR address.`, {
72
- ...ctx.recoveryFor('invalid_ip'),
73
- });
96
+ const parsed = validateIp(input.ip);
97
+ if (!parsed.valid) {
98
+ throw ctx.fail('invalid_ip', `"${input.ip}" is not a valid IPv4, IPv6, or CIDR address.`);
74
99
  }
75
100
  ctx.log.info('RDAP IP lookup', { ip: input.ip });
76
101
  // getRdapService().lookupIp already throws invalid_ip / private_range via factories with data.reason
77
102
  const network = await getRdapService().lookupIp(input.ip, ctx);
78
103
  // PTR lookup — best-effort, failure = null
79
- const base = input.ip.split('/')[0] ?? '';
80
- const isIpv6 = base.includes(':');
104
+ const { base, isIpv6 } = parsed;
81
105
  const ptrName = isIpv6 ? ipv6ToPtr(base) : ipv4ToPtr(base);
82
106
  const ptr = await getDohService().ptrLookup(ptrName, ctx);
83
- return { ...network, ptr };
107
+ return { ...network, ...ptr };
84
108
  },
85
109
  format: (result) => {
86
110
  const lines = [];
@@ -89,8 +113,8 @@ export const whoisLookupIp = tool('whois_lookup_ip', {
89
113
  lines.push(`**RIR Source:** ${result.rdap_source}`);
90
114
  if (result.org_name)
91
115
  lines.push(`**Organization:** ${result.org_name}`);
92
- if (result.cidr)
93
- lines.push(`**CIDR:** ${result.cidr}`);
116
+ if (result.cidrs.length)
117
+ lines.push(`**CIDRs:** ${result.cidrs.join(', ')}`);
94
118
  if (result.start_address && result.end_address) {
95
119
  lines.push(`**Range:** ${result.start_address} — ${result.end_address}`);
96
120
  }
@@ -107,6 +131,9 @@ export const whoisLookupIp = tool('whois_lookup_ip', {
107
131
  if (result.abuse_email)
108
132
  lines.push(`**Abuse Email:** ${result.abuse_email}`);
109
133
  lines.push(`**Reverse DNS (PTR):** ${result.ptr ?? 'Not available'}`);
134
+ lines.push(`**PTR Status:** ${result.ptr_status}`);
135
+ if (result.ptr_source_error)
136
+ lines.push(`**PTR Error:** ${result.ptr_source_error}`);
110
137
  return [{ type: 'text', text: lines.join('\n') }];
111
138
  },
112
139
  });
@@ -1 +1 @@
1
- {"version":3,"file":"whois-lookup-ip.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-lookup-ip.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEnG,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,EAAE;IACnD,KAAK,EAAE,6BAA6B;IACpC,WAAW,EACT,qGAAqG;QACrG,wGAAwG;QACxG,wGAAwG;QACxG,6EAA6E;IAC/E,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IAE9E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,EAAE,EAAE,CAAC;aACF,MAAM,EAAE;aACR,QAAQ,CACP,gGAAgG;YAC9F,iFAAiF,CACpF;KACJ,CAAC;IAEF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAClD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACzE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QAClF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QAC9E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;QAC3F,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACvE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACzE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QACjF,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,mEAAmE,CAAC;QAChF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACnF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC3E,GAAG,EAAE,CAAC;aACH,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,0GAA0G,CAC3G;QACH,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,uEAAuE,CAAC;KACrF,CAAC;IAEF,MAAM,EAAE;QACN;YACE,MAAM,EAAE,YAAY;YACpB,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,mDAAmD;YACzD,QAAQ,EACN,qGAAqG;SACxG;QACD;YACE,MAAM,EAAE,eAAe;YACvB,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,0EAA0E;YAChF,QAAQ,EACN,+GAA+G;YACjH,QAAQ,EAAE,SAAS;SACpB;QACD;YACE,MAAM,EAAE,cAAc;YACtB,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,8DAA8D;YACpE,QAAQ,EACN,6GAA6G;YAC/G,QAAQ,EAAE,SAAS;SACpB;KACF;IAED,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,KAAK,CAAC,EAAE,+CAA+C,EAAE;gBACxF,GAAG,GAAG,CAAC,WAAW,CAAC,YAAY,CAAC;aACjC,CAAC,CAAC;QACL,CAAC;QAED,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAEjD,qGAAqG;QACrG,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAE/D,2CAA2C;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE1D,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5E,IAAI,MAAM,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxE,IAAI,MAAM,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,aAAa,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,MAAM,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1E,IAAI,MAAM,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,IAAI,MAAM,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC7E,KAAK,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC,CAAC;QAEtE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"whois-lookup-ip.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/whois-lookup-ip.tool.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@
6
6
  import type { Context } from '@cyanheads/mcp-ts-core';
7
7
  import type { AppConfig } from '@cyanheads/mcp-ts-core/config';
8
8
  import type { StorageService } from '@cyanheads/mcp-ts-core/storage';
9
- import type { DnsLookupResult, DnsRecordType } from './types.js';
9
+ import type { DnsLookupResult, DnsRecordType, PtrLookupResult } from './types.js';
10
10
  export declare class DohService {
11
11
  /** Fetch DNS records for one type from a single DoH endpoint */
12
12
  private fetchSingleType;
@@ -21,9 +21,9 @@ export declare class DohService {
21
21
  * Perform a reverse DNS (PTR) lookup for an IP address.
22
22
  * IPv4: reverses octets + .in-addr.arpa
23
23
  * IPv6: reverses nibbles + .ip6.arpa
24
- * Returns null if the PTR lookup fails or returns no answer.
24
+ * Follows reachable aliases under one deadline; distinguishes absence from failure.
25
25
  */
26
- ptrLookup(ptrName: string, ctx: Context): Promise<string | null>;
26
+ ptrLookup(ptrName: string, ctx: Context): Promise<PtrLookupResult>;
27
27
  }
28
28
  export declare function initDohService(_config: AppConfig, _storage: StorageService): void;
29
29
  export declare function getDohService(): DohService;
@@ -1 +1 @@
1
- {"version":3,"file":"doh-service.d.ts","sourceRoot":"","sources":["../../../src/services/doh/doh-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAoC,MAAM,YAAY,CAAC;AAWnG,qBAAa,UAAU;IACrB,gEAAgE;IAChE,OAAO,CAAC,eAAe;IA8BvB;;;;;OAKG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CA2D3F;IAED;;;;;OAKG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUrE;CACF;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAEjF;AAED,wBAAgB,aAAa,IAAI,UAAU,CAK1C"}
1
+ {"version":3,"file":"doh-service.d.ts","sourceRoot":"","sources":["../../../src/services/doh/doh-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EAGb,eAAe,EAChB,MAAM,YAAY,CAAC;AAWpB,qBAAa,UAAU;IACrB,gEAAgE;IAChE,OAAO,CAAC,eAAe;IA8CvB;;;;;OAKG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CA4D3F;IAED;;;;;OAKG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CA2CvE;CACF;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAEjF;AAED,wBAAgB,aAAa,IAAI,UAAU,CAK1C"}
@@ -3,6 +3,7 @@
3
3
  * CAA records always use NextDNS because Cloudflare returns raw hex wire format for them.
4
4
  * @module services/doh/doh-service
5
5
  */
6
+ import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
6
7
  import { fetchWithTimeout, withRetry } from '@cyanheads/mcp-ts-core/utils';
7
8
  import { getServerConfig } from '../../config/server-config.js';
8
9
  import { DNS_TYPE_NUMBERS } from './types.js';
@@ -15,13 +16,26 @@ export class DohService {
15
16
  fetchSingleType(domain, type, baseUrl, timeoutMs, ctx, source) {
16
17
  const url = `${baseUrl}?name=${encodeURIComponent(domain)}&type=${encodeURIComponent(type)}`;
17
18
  return withRetry(async () => {
19
+ ctx.signal.throwIfAborted();
18
20
  const response = await fetchWithTimeout(url, timeoutMs, ctx, {
19
21
  headers: {
20
22
  Accept: 'application/dns-json',
21
23
  },
22
24
  signal: ctx.signal,
23
25
  });
24
- return response.json();
26
+ const data = (await response.json());
27
+ ctx.signal.throwIfAborted();
28
+ if (data.TC === true || (data.Status !== 0 && data.Status !== 3)) {
29
+ throw serviceUnavailable(`DNS ${type} query via ${source} failed: ${data.TC ? 'truncated response' : `RCODE ${data.Status}`}.`, {
30
+ reason: 'dns_response_failed',
31
+ type,
32
+ resolver: source,
33
+ status: data.Status,
34
+ truncated: data.TC === true,
35
+ recovery: { hint: 'Retry the DNS query later or choose another record type.' },
36
+ });
37
+ }
38
+ return data;
25
39
  }, {
26
40
  operation: `doh.fetchSingleType.${source}`,
27
41
  context: ctx,
@@ -37,31 +51,30 @@ export class DohService {
37
51
  * Returns `nxdomain: true` when NXDOMAIN (Status 3) is returned.
38
52
  */
39
53
  async lookup(domain, types, ctx) {
54
+ ctx.signal.throwIfAborted();
40
55
  const config = getServerConfig();
41
56
  const records = [];
42
57
  let nxdomain = false;
43
- // Track actual resolvers used: cloudflare = at least one non-CAA type used Cloudflare primary;
44
- // nextdns = all types used NextDNS (either CAA-primary or Cloudflare-fallback)
45
- let usedCloudflare = false;
46
- await Promise.all(types.map(async (type) => {
58
+ const querySources = await Promise.all([...new Set(types)].map(async (type) => {
47
59
  // CAA always via NextDNS; everything else Cloudflare first
48
60
  const primaryUrl = type === 'CAA' ? NEXTDNS_DOH : CLOUDFLARE_DOH;
49
- const primarySource = type === 'CAA' ? 'nextdns' : 'cloudflare';
61
+ let source = type === 'CAA' ? 'nextdns' : 'cloudflare';
50
62
  let resp;
51
63
  try {
52
- resp = await this.fetchSingleType(domain, type, primaryUrl, config.dohTimeoutMs, ctx, primarySource);
53
- // Only count as cloudflare when we successfully used Cloudflare (not CAA)
54
- if (type !== 'CAA')
55
- usedCloudflare = true;
64
+ resp = await this.fetchSingleType(domain, type, primaryUrl, config.dohTimeoutMs, ctx, source);
56
65
  }
57
- catch {
66
+ catch (error) {
67
+ ctx.signal.throwIfAborted();
68
+ if (type === 'CAA')
69
+ throw error;
58
70
  // Fallback to NextDNS for non-CAA types
59
71
  resp = await this.fetchSingleType(domain, type, NEXTDNS_DOH, config.dohTimeoutMs, ctx, 'nextdns');
72
+ source = 'nextdns';
60
73
  }
61
74
  if (resp.Status === 3) {
62
75
  // NXDOMAIN — domain does not exist in DNS
63
76
  nxdomain = true;
64
- return;
77
+ return { type, source };
65
78
  }
66
79
  for (const answer of resp.Answer ?? []) {
67
80
  const typeName = TYPE_NUM_TO_NAME[answer.type];
@@ -74,28 +87,62 @@ export class DohService {
74
87
  data: answer.data,
75
88
  });
76
89
  }
90
+ return { type, source };
77
91
  }));
78
- const source = usedCloudflare ? 'cloudflare' : 'nextdns';
79
- return { domain, nxdomain, records, source };
92
+ const source = querySources.some((query) => query.source === 'cloudflare')
93
+ ? 'cloudflare'
94
+ : 'nextdns';
95
+ return { domain, nxdomain, records, source, query_sources: querySources };
80
96
  }
81
97
  /**
82
98
  * Perform a reverse DNS (PTR) lookup for an IP address.
83
99
  * IPv4: reverses octets + .in-addr.arpa
84
100
  * IPv6: reverses nibbles + .ip6.arpa
85
- * Returns null if the PTR lookup fails or returns no answer.
101
+ * Follows reachable aliases under one deadline; distinguishes absence from failure.
86
102
  */
87
103
  async ptrLookup(ptrName, ctx) {
104
+ const signal = AbortSignal.any([
105
+ ctx.signal,
106
+ AbortSignal.timeout(getServerConfig().dohTimeoutMs),
107
+ ]);
108
+ const ptrCtx = { ...ctx, signal };
109
+ const normalize = (name) => name.toLowerCase().replace(/\.$/, '');
110
+ let owner = normalize(ptrName);
111
+ let hops = 0;
112
+ const visited = new Set([owner]);
88
113
  try {
89
- const result = await this.lookup(ptrName, ['PTR'], ctx);
90
- if (result.nxdomain || result.records.length === 0)
91
- return null;
92
- const first = result.records[0];
93
- if (!first)
94
- return null;
95
- return first.data.replace(/\.$/, '') || null;
114
+ while (true) {
115
+ signal.throwIfAborted();
116
+ const result = await this.lookup(owner, ['PTR'], ptrCtx);
117
+ if (result.nxdomain)
118
+ return { ptr: null, ptr_status: 'not_found' };
119
+ let followed = false;
120
+ while (true) {
121
+ const ptr = result.records.find((record) => record.type === 'PTR' && normalize(record.name) === owner);
122
+ if (ptr)
123
+ return { ptr: normalize(ptr.data), ptr_status: 'found' };
124
+ const alias = result.records.find((record) => record.type === 'CNAME' && normalize(record.name) === owner);
125
+ if (!alias)
126
+ break;
127
+ const target = normalize(alias.data);
128
+ if (visited.has(target) || hops === 5)
129
+ throw serviceUnavailable('Reverse DNS alias loop or five-transition limit reached.');
130
+ visited.add(target);
131
+ owner = target;
132
+ hops++;
133
+ followed = true;
134
+ }
135
+ if (!followed)
136
+ return { ptr: null, ptr_status: 'not_found' };
137
+ }
96
138
  }
97
- catch {
98
- return null;
139
+ catch (error) {
140
+ ctx.signal.throwIfAborted();
141
+ return {
142
+ ptr: null,
143
+ ptr_status: 'failed',
144
+ ptr_source_error: error instanceof Error ? error.message : String(error),
145
+ };
99
146
  }
100
147
  }
101
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"doh-service.js","sourceRoot":"","sources":["../../../src/services/doh/doh-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doh-service.js","sourceRoot":"","sources":["../../../src/services/doh/doh-service.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,23 @@ export interface NormalizedDnsRecord {
39
39
  export interface DnsLookupResult {
40
40
  domain: string;
41
41
  nxdomain: boolean;
42
+ query_sources: Array<{
43
+ type: DnsRecordType;
44
+ source: 'cloudflare' | 'nextdns';
45
+ }>;
42
46
  records: NormalizedDnsRecord[];
43
47
  source: 'cloudflare' | 'nextdns';
44
48
  }
49
+ /** Best-effort reverse lookup distinguishes a hostname, successful absence and failure. */
50
+ export type PtrLookupResult = {
51
+ ptr: string;
52
+ ptr_status: 'found';
53
+ } | {
54
+ ptr: null;
55
+ ptr_status: 'not_found';
56
+ } | {
57
+ ptr: null;
58
+ ptr_status: 'failed';
59
+ ptr_source_error: string;
60
+ };
45
61
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/doh/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEjG,6BAA6B;AAC7B,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAU1D,CAAC;AAEF,uCAAuC;AACvC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4BAA4B;AAC5B,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;CAClC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/doh/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEjG,6BAA6B;AAC7B,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAU1D,CAAC;AAEF,uCAAuC;AACvC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4BAA4B;AAC5B,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAChF,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;CAClC;AAED,2FAA2F;AAC3F,MAAM,MAAM,eAAe,GACvB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,QAAQ,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC"}