🔮 Seer
Domain intelligence at your fingertips.
A high-performance, multi-interface domain utility suite — query WHOIS, RDAP, DNS, SSL, and more from the terminal, Python, REST API, or AI assistants.
Features · Quick Start · CLI Usage · Python · REST API · MCP Server
✨ Features
🔍 Lookups & Discovery
- Smart Lookup — concurrent RDAP + WHOIS with fallback
- WHOIS — registrant, registrar, and expiration data
- RDAP — modern protocol for domains, IPs, and ASNs
- Domain Info — merged RDAP + WHOIS in a flat structure
- Reverse DNS — PTR lookups for IP addresses
- TLD Info — WHOIS server, RDAP endpoint, and registry
- Subdomain Enumeration — CT logs, with live/dead + takeover-risk classification and baseline diffing
- Domain Availability — check if a domain is registered
🌐 DNS & Propagation
- DNS Resolution — 16 record types with custom nameservers
- Encrypted DNS — DoT (
tls://) and DoH (https://) transports - DNS Propagation — 30 servers across 6 global regions
- DNS Monitoring — track record changes over time
- DNS Comparison — compare records across two nameservers
- DNSSEC Validation — check DNSSEC configuration
- NS Delegation Check — parent delegation vs. zone NS, with lame-server probing
🛡️ Security & Health
- Domain Status — HTTP status, title, SSL, and expiration
- SSL Chain Inspection — full chain, SANs, key details, validity
- CAA Policy — who may issue certs, vs. actual issuer
- Email Posture — SPF, DMARC, MTA-STS, BIMI, and DANE checks
- Look-alike Detection — confusable/homoglyph domains
- Registration Drift — diff live registration vs. a baseline
- Domain Watchlist — monitor expiring certs and registrations, with optional webhook alerts
- SSRF Protection — blocks requests to private/reserved IPs
⚡ Power Features
- Bulk Operations — process domain lists with CSV export
- Domain Diff — side-by-side comparison of two domains
- Field Extraction —
--quiet --fieldsfor scriptable output - 4 Output Formats — human, JSON, YAML, markdown
- Interactive REPL — with tab completion and history
- Environment Doctor — one-shot config/DNS/WHOIS/RDAP diagnosis
- Semantic Exit Codes — for CI/CD scripting
- Shell Completions — bash, zsh, fish, PowerShell (plus man pages)
🏗️ Four Interfaces, One Core
┌──────────────────────────────────────────────────────────────────┐
│ User Interfaces │
├─────────────┬─────────────┬──────────────┬───────────────────────┤
│ seer-cli │ seer-py │ seer-api │ seer-api │
│ Terminal │ Python │ REST API │ MCP Server │
└──────┬──────┴──────┬──────┴──────┬───────┴──────────┬────────────┘
│ │ │ │
│ └─────────────┼──────────────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────────────────────┐
│ seer-core │
│ Core Rust Library │
├──────────┬────────┬──────┬────────┬──────┬──────┬────────────────┤
│ WHOIS │ RDAP │ DNS │ Status │ SSL │ Bulk │ Diff/Watch │
└──────────┴────────┴──────┴────────┴──────┴──────┴────────────────┘
🚀 Quick Start
Install the CLI
Homebrew (macOS/Linux — prebuilt binary, no Rust toolchain required):
Cargo (builds from source):
Prebuilt binaries and shell/PowerShell installers for each release are also on the Releases page.
Run your first lookup
Using Seer from Rust code instead? See Rust Library.
Requirements: Rust 1.89+ · Python 3.10+ (for Python bindings/API)
📦 Packages
| Package | Type | Install | Description |
|---|---|---|---|
| seer-core | Rust library | cargo add seer-core |
Core library — all business logic |
| seer-cli | Rust binary | brew install TheZacillac/tap/seer or cargo install seer-cli |
The seer command-line tool |
| seer-py | Python extension | pip install ./seer-py |
Python bindings via PyO3 (import seer); PyPI (domain-seer) planned |
| seer-api | Python package | pip install -e . |
REST API + MCP server |
| seer-cli | seer-core | |
|---|---|---|
| What | Executable binary | Rust library crate |
| Install | brew install TheZacillac/tap/seer or cargo install seer-cli |
cargo add seer-core |
| Use | Run seer in your terminal |
use seer_core::* in Rust code |
| Provides | Commands, REPL, formatted output | Structs, clients, async APIs |
| Depends on | seer-core internally | Nothing — it's the foundation |
💻 CLI Usage
Interactive TUI
Launch the full-screen, keyboard-first terminal UI (Catppuccin Frappé, with a Latte light theme):
The lens sidebar covers every Seer capability, grouped, each pulling live data from the same seer-core engine as the CLI with full in-pane controls:
- LOOKUP — Overview · WHOIS · RDAP (Domain · IP · ASN) · Reverse DNS · Availability · TLD Info
- DNS — Records (+ custom nameserver) · DNSSEC · Compare (two resolvers) · Propagation · Follow (live monitor)
- SECURITY — SSL / Cert · Status · Subdomains · HTTP Headers · Takeover
- POWER — Diff · Bulk (streaming + CSV export) · Watchlist · History
Keys: j/k move · 1–9 jump to a lens · Tab focus nav⇄pane · [ ] sub-tabs · r raw output (json/yaml/markdown) · y copy · / look up a domain · : command · ? help · :q quit. In-pane: switchers (TLD, nameserver, Compare resolvers, Bulk op) and editable fields (Diff's 2nd domain, Follow interval/count, Bulk file path).
Commands (:): lookup, whois, rdap <domain|ip|AS####>, dig, ssl, status, headers, takeover, reverse <ip>, tld <.tld>, compare <domain> <nsA> <nsB>, diff <a> <b>, set output <human|json|yaml|markdown>, theme <frappe|latte>, copy, q.
The startup theme comes from [tui] theme in ~/.seer/config.toml ("frappe" — the default — or "latte"; unknown names fall back to Frappé). Switch live with :theme latte.
Command Mode
# Smart lookup (concurrent RDAP + WHOIS)
# Comprehensive domain info (merged RDAP + WHOIS)
# WHOIS / RDAP
# DNS queries
# DNS propagation & monitoring
# DNSSEC & DNS comparison
# Domain health & SSL
# Security intel
# Reverse DNS
# Discovery
# Domain diff
# Watchlist
# Lookup history
# Bulk operations (with CSV export) — ops: lookup, whois, rdap, dig, prop,
# status, avail, info, ssl, caa, posture, confusables
|
# Environment diagnosis (config, DNS, WHOIS port 43, RDAP bootstrap HTTPS)
# Scriptable field extraction
# Shell completions & man pages
seer watch --webhook (or webhook_url under [watch] in ~/.seer/config.toml — the flag wins) POSTs the check-all report as JSON. Delivery is best-effort: a failed POST prints a stderr warning and never changes the exit code, and the URL passes the same SSRF guard as every other outbound request.
Output Formats
Exit Codes
Every command follows the same contract, so $? is safe to gate cron jobs and CI on:
| Code | Meaning |
|---|---|
0 |
Success (and, for check commands, the check passed) |
1 |
Operational error (network, parse, invalid input) — or a check command's negative result |
2 |
Usage error (bad flags or arguments) |
Check commands exit 1 on a negative result even when the command itself ran fine:
| Command | Exits 1 when… |
|---|---|
seer status |
HTTP status is missing or non-2xx, the SSL cert is invalid or expires within 30 days, or the domain expires within 30 days |
seer avail |
The domain is not available (already registered) |
seer dnssec |
The zone's status is anything other than signed (i.e. unsigned, partial, or misconfigured) |
seer compare |
The two nameservers return different record sets |
seer delegation |
The parent's delegation NS set and the zone's own NS RRset are out of sync, or any delegated server answers lamely |
seer doctor |
Any check reports FAIL. WARN (degraded but usable, e.g. a malformed config file running on defaults) still exits 0 |
seer drift |
Material drift is found vs. the stored baseline (a first run with no baseline exits 0) |
seer subdomains --diff |
New names appeared vs. the stored baseline (removals and a missing baseline exit 0) |
seer watch |
Issues at or above the --fail-on threshold: critical (default) fails only on critical issues, warning fails on warnings too. add/remove/list exit 0 on success |
seer bulk |
Every domain in the batch failed — partial failures exit 0, since per-row status is already in the CSV/JSON output |
All other commands exit 0 on success and 1 on error. With --format json, yaml, or markdown, errors are written to stderr in that format (e.g. {"error": "..."}) instead of colored prose.
Interactive REPL
Launch by running seer with no arguments:
$ seer
seer> lookup example.com
seer> dig github.com MX
seer> status cloudflare.com
seer> delegation example.com
seer> doctor
seer> set output json
seer> help
seer> exit
Features: command history (~/.seer_history), tab completion, loading spinners, persistent session state.
🐍 Python Library
# Smart lookup
=
# WHOIS / RDAP
=
= # Auto-routes IP / ASN / domain (alias: rdap_auto)
=
=
=
# DNS
=
=
= # Parent vs. zone NS + lameness
=
# Stop a running dns_follow from another thread
= # The 16 supported record types
# Domain health & SSL
=
=
=
=
# Security intel
= # SPF / DMARC / MTA-STS
= # HTTP security headers, graded A+-F
= # Subdomain takeover scan
= # Look-alike domains
# Availability & info
=
=
= # WHOIS server, RDAP endpoint, registry
= # Every TLD seer knows about
# Comparison & enumeration
=
=
=
= # live/dead + takeover risk
# Bulk operations
=
=
=
=
=
=
=
=
# bulk_* calls return one dict per domain:
# {"operation": {"type": ..., "domain": ...}, "success": bool,
# "data": ... or None, "error": str or None, "duration_ms": int}
# Every bulk_* call takes an optional keyword-only progress callback
=
# SSRF helpers (used by seer-api before any user-supplied connect target)
# ValueError on reserved/private addresses
# ("1.1.1.1", 853); None if the spec is invalid
=
🦀 Rust Library
[]
= "0.49"
= { = "1", = ["full"] }
use ;
async
See docs.rs/seer-core for the full API reference.
🌍 REST API
Each lookup is a GET endpoint (/lookup/{domain}, /dns/{domain}/{record_type},
/ssl/{domain}, /takeover/{domain}, …). lookup, whois, dns,
propagation, status, ssl, availability, and info also accept a
POST …/bulk domain list, and all but availability and info can stream
bulk results as Server-Sent Events from …/bulk/stream. The full endpoint
table is in seer-api/README.md.
Secure by default: the server binds loopback only, refuses a non-loopback
SEER_HOST without SEER_API_KEY, serves /docs only when
SEER_DOCS_ENABLED=true, and refuses multi-worker runs on the in-memory
rate-limit store. See
Deployment defaults.
# Examples
API docs (when SEER_DOCS_ENABLED=true):
Swagger UI · ReDoc
🤖 MCP Server
Integrate Seer with AI assistants via the Model Context Protocol. Two transports expose the same tools:
# Local subprocess transport (Claude Desktop, etc.)
# Remote / web transport (mounted on the REST API)
The Streamable HTTP endpoint runs stateless inside the existing seer-api
process and inherits SEER_API_KEY auth, request logging, and the body-size
cap. See seer-api/README.md
for the wire format.
Generate a random bearer token for the connector:
# Capture into a shell var
KEY=
# Or eval directly into the current shell
SEER_API_KEY= SEER_HOST=0.0.0.0
30 tools: one per lookup (seer_lookup, seer_dig, seer_ssl,
seer_takeover, …) plus bulk variants (seer_bulk_status, …). The full tool
list and the Claude Desktop configuration are in
seer-api/README.md.
📡 DNS Record Types
| Type | Description | Type | Description | |
|---|---|---|---|---|
A |
IPv4 address | PTR |
Pointer record | |
AAAA |
IPv6 address | SRV |
Service locator | |
MX |
Mail exchange | NAPTR |
Naming authority pointer | |
TXT |
Text records | DNSKEY |
DNSSEC public key | |
NS |
Nameserver | DS |
Delegation signer | |
SOA |
Start of authority | SSHFP |
SSH key fingerprint | |
CNAME |
Canonical name | TLSA |
DANE TLS association | |
CAA |
CA authorization | ANY |
All records |
🌏 Global DNS Propagation Servers
Propagation checks query 30 nameservers across 6 regions:
| Region | Servers |
|---|---|
| 🇺🇸 North America | Google 8.8.8.8 · Cloudflare 1.1.1.1 · OpenDNS · Quad9 · Level3 |
| 🇪🇺 Europe | DNS.Watch · Mullvad · dns0.eu · Yandex · UncensoredDNS |
| 🌏 Asia Pacific | AliDNS · 114DNS · Tencent DNSPod · TWNIC · HiNet |
| 🌎 Latin America | Claro Brasil · Telefonica Brasil · Antel Uruguay · Telmex · CenturyLink |
| 🌍 Africa | Liquid Telecom · SEACOM · Safaricom · MTN South Africa · Telecom Egypt |
| 🌐 Middle East | Etisalat UAE · STC Saudi · Bezeq Israel · Turk Telekom · Ooredoo Qatar |
⚙️ Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
RUST_LOG |
Logging level (trace / debug / info / warn / error) |
— |
SEER_LOG_LEVEL |
API log level; ARCANUM_LOG_LEVEL takes precedence when set |
INFO |
SEER_DOMAIN_ALLOWLIST |
Comma-separated allowlist restricting which domains may be queried | — |
SEER_HOST |
API bind host. Non-loopback requires SEER_API_KEY |
127.0.0.1 |
SEER_PORT |
API bind port | 8000 |
SEER_API_KEY |
Bearer token required for all non-/health requests |
— |
SEER_CORS_ORIGINS |
Comma-separated CORS origins for REST API | * |
SEER_DOCS_ENABLED |
Expose /docs, /redoc, /openapi.json |
false |
SEER_METRICS_ENABLED |
Expose /metrics to non-loopback clients |
false |
SEER_RATE_LIMIT |
Per-client limit for the MCP endpoint (POST /mcp) as <count>/<period>; ;-separated limits are all enforced. REST routes keep their own fixed limits |
30/minute |
SEER_RATE_LIMIT_STORAGE |
Rate-limit storage URI (e.g. redis://host:6379) |
memory:// |
SEER_REQUEST_TIMEOUT |
Per-request deadline (seconds) for dispatched core calls; on expiry the client gets a 504. 0 disables |
0 |
SEER_DISPATCH_THREADS |
Max threads in the pool running blocking core calls (REST + /mcp) |
50 |
SEER_MAX_CONCURRENT_STREAMS |
Max in-flight bulk SSE stream jobs per worker process | 8 |
SEER_TRUST_PROXY |
Trust X-Forwarded-For from SEER_TRUSTED_PROXY_IPS |
false |
SEER_TRUSTED_PROXY_IPS |
Comma-separated IPs allowed to set X-Forwarded-For |
— |
SEER_MCP_ALLOWED_HOSTS |
Comma-separated Host: values for the MCP /mcp endpoint — setting this turns on DNS-rebinding protection |
— |
SEER_MCP_ALLOWED_ORIGINS |
Comma-separated Origin: values for the MCP /mcp endpoint (browser hosts) |
— |
WEB_CONCURRENCY |
Uvicorn worker count. >1 requires a non-memory:// store |
1 |
UVICORN_WORKERS |
Fallback worker count when WEB_CONCURRENCY is unset (same >1 store rule) |
1 |
SEER_RELOAD |
Uvicorn auto-reload for the seer-api entry point (dev only) |
false |
Config File
Initialize a config file at ~/.seer/config.toml:
Settings: default output format, nameserver (UDP, tls://, or https://),
per-protocol timeouts, bulk concurrency, rate-limit delay — all clamped to
safe ranges — plus a [watch] table (webhook_url for seer watch report
delivery) and a [tui] table (theme = "frappe" or "latte"). Applies to
the CLI and REPL; the TUI reads the output format and theme.
Timeouts
| Client | Default |
|---|---|
| WHOIS | 15s |
| RDAP | 15s |
| DNS | 5s (2 retries) |
| HTTP / SSL | 10s |
| Propagation | 15s |
Bulk Operations
- Input: plain text (one domain per line) or CSV (first column)
- Comments: lines starting with
#are skipped - Concurrency: default 10, max 50
- API limit: max 100 domains per request
🔮 Roadmap
- Scheduled Monitoring Daemon —
seer monitor --config monitors.tomlas a background service with notifications (email, Slack, PagerDuty) for expiring domains, SSL certificates, and unexpected DNS changes. The natural evolution ofwatch,follow, andstatusinto persistent monitoring.
🛠️ Development
Building
&& &&
Testing
&& RUST_LOG=debug
Linting
Project Structure
The four packages are listed under Packages; all business
logic lives in seer-core, and the other three are thin interfaces over it.
The annotated per-module map is in
CLAUDE.md → Codebase Structure.
🔧 Technology Stack
| Layer | Technologies |
|---|---|
| Core | Rust · Tokio · Reqwest (rustls) · Hickory-resolver (DNSSEC) · Serde · OpenTelemetry |
| CLI | Clap v4 · Rustyline · Indicatif · Colored · Crossterm |
| Python | PyO3 (ABI3) · FastAPI · Pydantic · MCP |
| Data | WHOIS servers from WooMai/whois-servers · IANA RDAP bootstrap |
📄 License
MIT License — Copyright (c) 2026 Zac Roach
See LICENSE for the full text.