Skip to main content

Pre-flight checks before registering a domain for a new site or app: basic name checks, past content history, risk scoring.

Project description

domain-pre-flight

test License: MIT

⚠️ Status: experimental / under active validation. Heuristics, score weights, and thresholds are still being calibrated against real-world domain decisions. Use it as one input — not the only one — when deciding whether to register a domain.

Pre-flight checks before registering a domain for a new site or app.

domain-pre-flight answers a single question: "Is this domain safe to register for a new project, or should I keep looking?"

It is not a domain investing / drop-catching tool. It is the last-mile checklist for engineers and founders who already have a domain in mind and want a quick read on whether it is clean, memorable, and free of obvious legacy abuse.

What v0.1 does

Check What it tells you Source
Basic structural check length, hyphens, digits, IDN/punycode, syntactic validity (RFC 1035) offline, no API
TLD risk score per-TLD default risk based on Spamhaus / SURBL abuse statistics (.tk/.cf/.ml etc. heavily penalised) static table
Past content history Wayback Machine snapshot count, first/last archived date, archive span archive.org (free, no auth)
Same-name handle check GitHub / npm / PyPI / X / Instagram availability for the SLD public APIs / HEAD requests
Typosquat / brand similarity Levenshtein distance + homoglyph/bigram heuristics against ~120 widely-recognised brand stems bundled list, offline
Trademark conflict (opt-in) Pre-filled USPTO + EUIPO + J-PlatPat deeplinks for manual verification (deeplink-only — see ADR 0009) offline, no API queries
Multi-language semantics Negative-meaning scan across EN / ES / PT / JA / KO / ZH (curated bundled lists) bundled lists, offline
LLMO fitness (experimental) Pronunciation / memorability heuristic (cluster, vowel ratio, length, repeats) — 0–20 score offline heuristics
Aggregate verdict 0–100 score, 4 bands (GREEN / YELLOW / ORANGE / RED), itemised deductions derived

The CLI exits with 0 on GREEN/YELLOW, 1 on ORANGE, 2 on RED — convenient for CI gating in domain-procurement scripts.

Install

pip install domain-pre-flight        # not yet on PyPI — install from source while v0.1 is in flight
# or, from a clone:
pip install -e ".[dev]"

Usage

# Full check (basic + history + aggregate verdict)
domain-pre-flight check example.com

# Skip the network call to Wayback (offline only)
domain-pre-flight check example.com --no-history

# Include same-name handle availability across GitHub / npm / PyPI / X / Instagram
domain-pre-flight check example.com --check-handles

# JSON output for piping
domain-pre-flight check example.com --json

# History only
domain-pre-flight history example.com

# Handle availability only (subset selectable via --platforms)
domain-pre-flight handles example.com --platforms github,npm,pypi

# Typosquat / brand-similarity check only
domain-pre-flight typosquat goolge.com

# Trademark conflict (opt-in; queries USPTO + EUIPO, surfaces J-PlatPat deeplink)
domain-pre-flight check example.com --check-trademark
domain-pre-flight trademark example.com --jurisdictions us,eu

# Multi-language negative-meaning scan
domain-pre-flight semantics shineyo.com --languages ja

# LLMO fitness — pronunciation / memorability heuristic (experimental)
domain-pre-flight llmo apple.com

# Basic structural checks only
domain-pre-flight basic example.com

# Short alias
dpf check example.com

MCP server (use it from Claude Code / Claude Desktop / Cursor)

domain-pre-flight ships an MCP (Model Context Protocol) server so AI assistants can run the checks as tools:

pip install "domain-pre-flight[mcp]"
claude mcp add domain-pre-flight -- domain-pre-flight-mcp

Then ask your assistant things like "is shineyo.dev safe to register?" or "compare these three candidates and pick the safest."

Exposed tools (deliberately fewer than the CLI's subcommands — one tool per use case, not per flag):

Tool What it answers
check_domain "Is this name safe to register?" — full verdict + section reports; slow checks opt-in via include_handles / include_trademark / include_rdap / include_dns
check_handles "Is the same name free on GitHub / npm / PyPI / X / Instagram?"
check_trademark "Any exact/contains trademark hits in US / EU / JP registries?" (mechanical pre-screen, not legal advice)
list_typo_permutations "What look-alike names could someone register against me?"

A deliberately naive subprocess-based variant lives in examples/subprocess-variant/ as the "before" half of a security / latency comparison — do not use it in production.

Example output

example.com  →  GREEN  score=100/100  — Looks clean. Proceed.

Basic checks
┃ Field              ┃ Value
┃ SLD                ┃ example
┃ TLD                ┃ com
┃ length / SLD label ┃ 11 / 7
┃ hyphens / digits   ┃ 0 / 0
┃ IDN / punycode     ┃ no
┃ syntax valid       ┃ yes
┃ TLD risk score     ┃ 0

Roadmap

The features below are planned but not yet implemented. Order is rough; PRs welcome.

Near-term — eliminate the most common "should not have registered this" failure modes

  1. Same-name social / package availability — check whether the matching handle is free on GitHub, npm, PyPI, and major social networks. Shipped in v0.2dpf handles and --check-handles.
  2. Typosquat / brand-similarity flag — Levenshtein distance and bigram similarity against a curated brand list. Shipped in v0.3dpf typosquat (default ON in dpf check, disable with --no-typosquat).
  3. Trademark conflict check — query USPTO, EUIPO, and J-PlatPat for identical and confusingly similar marks. Shipped in v0.4, revised in v0.7.1dpf trademark and --check-trademark (opt-in). All three jurisdictions surface a pre-filled deeplink for manual verification; the live-query path was removed (ADR 0009) because none of the registries publishes a stable, documented, no-auth search API. This tool flags candidates, not legal opinions — consult counsel before acting on a flag.

Medium-term — quality-of-life and global readiness

  1. Multi-language negative-meaning check — scan the SLD against major languages (EN / ZH / ES / PT / KO / JA) for slurs, vulgarities, or unfortunate readings. Shipped in v0.5dpf semantics (default ON in dpf check, disable with --no-semantics). Word lists live at data/negative_meanings/<lang>.txt and accept community PRs with citations.
  2. Per-TLD default risk score (deeper) — extend the TLD table to use live Spamhaus / SURBL feed data instead of the static table. Refactored in v0.6 — TLD-risk table now lives at data/tld_risk.json and is loaded at runtime, with the embedded dict as a graceful fallback. scripts/refresh_tld_risk.py is the entry point; a monthly GitHub Actions workflow opens an auto-PR. Live feed integration (Interisle / DAAR) is currently a no-op stub — the script writes the curated baseline if no live source is available, so the bundle is always valid.
  3. Pronunciation / memorability heuristics (LLMO fitness) — score how easily the domain can be dictated, spelled-back over voice, and recognised by AI search assistants. Shipped in v0.7dpf llmo (default ON in dpf check, disable with --no-llmo). 0–20 fitness score across four axes (cluster / vowel / length / repeats); marked experimental in output because the heuristics are subjective and English-leaning.

Opt-in — paid-API features (default OFF, not yet implemented)

  1. Detailed backlink evaluation — referring-domain quality, anchor-text spam ratio, and historical link velocity from a paid provider (Ahrefs / Majestic / Moz). Will be exposed as an opt-in flag (planned name: --enable-backlinks) once the integration lands; provider and credentials will be configured via environment variables. Designed as a strict superset, not a replacement, for the free signals.

Out of scope (for now)

  • Domain valuation / sale-price history (drifts into domain-investing territory)
  • WHOIS scraping for marketing intelligence
  • Bulk domain monitoring (this is a per-decision pre-flight, not an asset-management tool)

Design notes

  • Free signals first. The default code path uses only public, no-auth APIs (Wayback Machine) and offline heuristics. Anything paid is opt-in.
  • Deterministic where possible. The basic check and the score formula are pure functions; only the history check makes a network call.
  • Not a replacement for human judgement. A green verdict is a "no obvious red flags," not a sign-off. Always inspect older Wayback snapshots manually before adopting a domain that has prior content.

Development

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Unit tests
pytest -q

# CLI smoke tests (offline mode skips the Wayback network call)
bash scripts/smoke.sh --offline
bash scripts/smoke.sh             # full run, hits Wayback Machine

CI runs pytest against Python 3.10 / 3.11 / 3.12 plus the offline smoke suite on every push and PR.

License

MIT — see LICENSE.

Documentation

This repo is structured for both human readers and AI coding agents (Claude Code, Cursor, etc.). Pick the doc that matches your task:

If you want to… Read
Use the CLI docs/guide/usage.md
Understand the codebase as a whole CLAUDE.md, then docs/architecture.md
Add a new check / extend an existing one docs/agents/extending-checks.md
Edit only data (brand list, word lists, TLDs) docs/agents/data-updates.md
Tune scoring weights docs/agents/tuning-scores.md
Understand why a design choice was made docs/decisions/
Get the smallest possible context for one module docs/context-cards/

The docs/agents/ and docs/context-cards/ directories are written for tasks that span exactly one module — load only the relevant card to keep context cost predictable.

Background

This project is a tools-side companion to the (Japanese-language) book 「2人ではじめる中古ドメイン・ビジネス: 目利き×運用の協業設計」 by Ken Imoto, which covers expired-domain-abuse policy boundaries, LLMO-era authority evaluation, revenue-share contracts, and exit-route economics for domain-and-content businesses. domain-pre-flight distils the "will I regret registering this name?" pre-flight subset of that material into a runnable check.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

domain_pre_flight-0.9.0.tar.gz (98.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

domain_pre_flight-0.9.0-py3-none-any.whl (46.2 kB view details)

Uploaded Python 3

File details

Details for the file domain_pre_flight-0.9.0.tar.gz.

File metadata

  • Download URL: domain_pre_flight-0.9.0.tar.gz
  • Upload date:
  • Size: 98.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for domain_pre_flight-0.9.0.tar.gz
Algorithm Hash digest
SHA256 966e0ee72758d8d4de23a787f53b14f54c4d1930be18b09004bd82ff3e18a6b3
MD5 3403236a6f85fa4dd90a816470d6dd30
BLAKE2b-256 1b4740b815dd9402b7e4820b2a6f4d47243ef7a3576b71d0c7a4630cce130a49

See more details on using hashes here.

Provenance

The following attestation bundles were made for domain_pre_flight-0.9.0.tar.gz:

Publisher: publish.yml on kenimo49/domain-pre-flight

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file domain_pre_flight-0.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for domain_pre_flight-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1d64740358bf0b9c46c06d2a18fd63483a50cf203434562eb3dfffc5d37047b7
MD5 4361e52c3a4e2fbb1d16553981324745
BLAKE2b-256 0be3ccd07149fa42f3424898defbb30733dc0db22b8bd021c3ca60fb22672d3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for domain_pre_flight-0.9.0-py3-none-any.whl:

Publisher: publish.yml on kenimo49/domain-pre-flight

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page