Find domain names that are actually registrable. Calls Domain Search King's remote MCP (live RDAP). Never guess availability. No API key.
Coding
domain-recon
Try itPassive domain/infra OSINT over five keyless public APIs — subdomains, RDAP/WHOIS, DNS-over-HTTPS, IP geo/ISP, and ASN/prefix ownership.
What it does
Passive domain/infra OSINT over five keyless public APIs — subdomains, RDAP/WHOIS, DNS-over-HTTPS, IP geo/ISP, and ASN/prefix ownership.
The skill document
domain-recon
Passive reconnaissance for a domain, IP, or ASN using five keyless public APIs — no API keys, no accounts, no secrets. Everything is passive: the skill only queries public third-party databases; it never connects to or probes the target host directly.
Use this when the user wants to investigate a domain or IP's public footprint: enumerate subdomains, look up WHOIS/RDAP registration, resolve DNS records, geo- locate an IP, or identify which network/ASN owns an address.
All work runs through one Python helper (standard library only — no pip install):
python3 {baseDir}/scripts/recon.py [options]
Output is JSON by default (easy to parse and chain); add --human for a compact
readable summary.
Subcommands
| Subcommand | Source | What it does |
|---|---|---|
certs | crt.sh + certSpotter (Certificate Transparency) | Enumerate subdomains + certificate history; falls back to certSpotter when crt.sh is down |
rdap | IANA bootstrap + supplement → authoritative server (rdap.org fallback) | Modern WHOIS for a domain, IP, or ASN (auto-detected); resolves ccTLDs like .ai (bootstrap) and .io/.sh/.ac/.us (supplement) that rdap.org 404s |
dns | Google / Cloudflare DoH | Resolve DNS records (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA) |
ip | ip-api.com | IP → geo, ISP, ASN, and proxy/hosting flags |
asn | RIPEstat Data API | ASN → holder + announced prefixes; IP → owning ASN + prefix |
wayback | archive.org | Wayback snapshot availability + CDX capture history |
profile | all of the above | One-shot orchestration: certs → dns → ip → asn → wayback into a single report |
Common options
--human— readable text instead of JSON.--timeout— per-request timeout (default 20).--retries— retry attempts on 429/5xx/network errors (default 3).certs --no-wildcards— drop*.wildcard subdomains.dns --type A,MX,TXT— comma-separated record types in one call.dns --provider cloudflare— use Cloudflare DoH instead of Google (default).rdap --kind domain|ip|asn— force the resource kind instead of auto-detecting.asn --no-prefixes— skip the announced-prefixes list for a faster ASN lookup.certs --limit/certs --max-certs— cap the returned subdomains / cert-history rows (full counts still reported).certs --all-ct— query both CT sources (crt.sh + certSpotter) and merge, instead of stopping at the first that answers (wider coverage).rdap --no-bootstrap— skip the IANA bootstrap and query rdap.org directly (domains only).wayback --no-cdx— availability only;wayback --cdx-limit— number of recent captures to list.profile --cert-limit/--resolve-limit/--ip-limit— bound how much of each stage the orchestrator pulls;--no-waybackto skip the archive step.
Example invocations
# Subdomains + cert history for a domain
python3 {baseDir}/scripts/recon.py certs example.com --human
# WHOIS/RDAP (auto-detects domain vs IP vs ASN)
python3 {baseDir}/scripts/recon.py rdap example.com
python3 {baseDir}/scripts/recon.py rdap 8.8.8.8
python3 {baseDir}/scripts/recon.py rdap AS15169
# DNS records — several types at once, via Cloudflare
python3 {baseDir}/scripts/recon.py dns example.com --type A,AAAA,MX,TXT --provider cloudflare
# IP geolocation / ISP / hosting flags
python3 {baseDir}/scripts/recon.py ip 8.8.8.8 --human
# Who owns this network? (ASN or IP)
python3 {baseDir}/scripts/recon.py asn AS15169
python3 {baseDir}/scripts/recon.py asn 8.8.8.8
# Is it archived? (availability + recent capture history)
python3 {baseDir}/scripts/recon.py wayback example.com
# One-shot: profile a domain across every source in a single report
python3 {baseDir}/scripts/recon.py profile example.com --human
A typical "profile this domain" flow: run certs for subdomains, rdap for
registration, dns for the live records, then ip + asn on the resolved
address to see who hosts it. The profile subcommand chains exactly this
sequence for you (respecting ip-api's rate limit between enrichment calls) and
returns one merged JSON/--human report.
Behavior & safety notes
- Passive only. No port scans, no direct connections to the target — just public database lookups.
- Keyless. No credentials are ever required, read, or transmitted.
- No shell injection surface. Inputs are validated (domains IDNA/punycode- encoded, IPs and ASNs parsed) and passed only as URL-encoded query parameters; the helper never invokes a shell.
- Courteous. Sends a descriptive User-Agent, uses per-request timeouts, and
backs off with retries on
429/5xx(honoringRetry-After). ip-api.com is rate-limited to 45 requests/minute — batch and space out calls. - Resilient to source outages.
certsfalls back from crt.sh (which frequently hard-502s under load) to certSpotter so subdomain enumeration survives, recording which source answered insources_used.rdapresolves the authoritative RDAP server via the IANA bootstrap, plus a small curated supplement for TLDs IANA omits but that still run RDAP (e.g..io, which the rdap.org redirector404s), then falls back to rdap.org for anything else. The winning source is recorded inrdap_source. - Graceful degradation —
rdaptells you when a TLD isn't supported.rdapis the only TLD-variable query (dns/certs/ip/asn/wayback are TLD-agnostic). When a domain's TLD has no public RDAP server anywhere (absent from both the IANA bootstrap and the supplement — many ccTLDs are WHOIS-only),rdapreturns a first-class{"supported": false, "rdap_source": "none", "reason": ...}result at exit0, not a 404 or an exception. A calling agent should checksupportedand skip RDAP for that domain while still using the other sources; insideprofilethis appears as a clean signal underapex.rdap, never inerrors[]. Real answers carry"supported": true. Seedocs/tld-rdap-coverage.mdfor the full per-TLD map (which of the 1,438 delegated TLDs arebootstrap/supplement/none), regenerable withpython3 {baseDir}/scripts/gen_coverage.py. - Third state —
rdapdistinguishes "unreachable" from "unsupported". A TLD can be delegated in the IANA bootstrap yet unreachable from our egress: the registry's authoritative RDAP server resets the connection / RSTs the TLS handshake / read-times-out (errno 104 class). This is neither a clean answer nor a real capability gap, sordapemits a distinct{"supported": true, "rdap_source": "unreachable", "retryable": true, "reason": ...}result. The signal to a caller: the data exists, we could not fetch it — skip the field but know it is retryable, NOT "this TLD has no RDAP server". The trigger is deliberately narrow (connection reset / TLS RST / read timeout against a bootstrap- or supplement-listed endpoint); a429/ban or a genuine absence never lands here. Because the fetch did not succeed, this outcome carries its own exit code3(see Exit codes) rather than collapsing into0. Insideprofileit appears as a cleanunreachablesignal underapex.rdap, never inerrors[]. - Fourth state —
rdapdistinguishes "broken" from "unreachable". A delegated endpoint can respond, but with an unusable response: an untrusted/self-signed TLS certificate that fails verification, or an HTTP error status (4xx / 5xx). This is neither a clean answer, a real capability gap, nor a transport reset, sordapemits a distinct{"supported": true, "rdap_source": "broken", "cause": "", "http_status": , "retryable": , "reason": ...}result.causeisbad-certorhttp-(e.g.http-426,http-404,http-500);retryableisfalsefor a bad cert / 4xx (a persistent registry-side fault) andtruefor a 5xx (a server error a later attempt may clear). The signal to a caller: the endpoint is faulty — skip the field;retryablesays whether trying later helps. recon does not disable TLS verification or fake a fetch — it only labels the fault honestly. The trigger is narrow and mutually-exclusive withunreachable: a429/ban, a DNS-resolution failure, a connection-refused, and a genuine absence never land here, andbrokenis only emitted after both the authoritative server and the rdap.org redirector are exhausted (so it never fires where the redirector could still rescue the lookup). Exit code is driven byretryable(see Exit codes). Insideprofileit appears as a cleanbrokensignal underapex.rdap, never inerrors[]. profileruntime is bounded, not instant. A full profile fans out across ~6 sources and multiple hosts with courtesy rate-limit spacing, so a large domain (dozens of subdomains) takes roughly 1–1.5 min — it is working, not hung. The slowest source, the Wayback CDX index (single lookups seen in the tens of seconds), runs on a deliberately tight budget (short timeout, no retry) so it can never dominate; a timed-out archive lookup is fault-isolated intoerrors[]like any other. Use--no-waybackor a lower--ip-limitto make a profile faster.- Exit codes (quint-state). The code encodes the actionable retryability
tier; the JSON
rdap_sourcenames the mechanism. A caller branching on exit status can tell "clean result" from "skip, retry later" from "skip, don't bother":0— success: a real answer or a definitiveunsupported/WHOIS-only TLD (a terminal, non-retryable capability gap,rdap_source:"none").2— a handled error (bad input, upstream failure, 429/ban) with a message on stderr.3— retryable RDAP failure: the endpoint is delegated (a server exists) but we could not get usable data this time and a later attempt may succeed — eitherrdap_source:"unreachable"(transport reset / TLS-RST / read timeout) orrdap_source:"broken"with a 5xx (retryable:true).4— non-retryable endpoint fault:rdap_source:"broken"with an untrusted/self-signed TLS cert or an HTTP 4xx (retryable:false) — the server answered definitively; retrying will not help until the registry fixes it. Neither3nor4is folded into0: the field was not fetched, so the distinction (retry later vs. don't bother vs. clean) is preserved.
For maintainers — running the tests
The parsing/normalization logic is covered by an offline, deterministic pytest
suite (fixtures in scripts/tests/fixtures/, HTTP mocked — no network):
python3 -m pip install pytest # only dependency, tests-only
python3 -m pytest {baseDir}/scripts/tests/test_recon.py -q
An opt-in live smoke test verifies the real endpoints still match the expected schema (never part of the normal gate):
RECON_LIVE=1 python3 -m pytest {baseDir}/scripts/tests/test_live_smoke.py -q
See references/API_NOTES.md for endpoint details and references/CHANGELOG.md
for notable decisions (including the BGPView → RIPEstat swap).
Related skills
Analyze a specific domain using registration, DNS, website, safety, backlink, cross-TLD, and market and legal-risk evidence. Use when a user asks what is known about a domain, wants due diligence before acquiring one, or requests a technical domain analysis. Do not use for generating domain names, s
全功能域名研究工具。支持 RDAP (RFC 7480-7484) 结构化查询、WHOIS 传统查询、DNS 多类型记录解析 (A/AAAA/MX/NS/TXT/CNAME/SOA/CAA/SRV/PTR)、SSL/TLS 证书检查、域名可用性判断、多解析器 DNS 传播检测、子域名枚举、批量域名分析和交互式 H...
Produce a time-bounded domain-market news briefing with source tiers, event types, and explicit inference limits, covering notable sales, registration trends, and recent domain movements. Use when a user wants to know what is happening in the domain market now.
Map available evidence around a known keyword in the domain market, keeping search-audience, advertiser, new-registration open-market participation, supply and active offers, and completed transactions as distinct layers.
Search, buy, and manage domains plus run professional email from one API.