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
⚠️ 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
Same-name social / package availability — check whether the matching handle is free on GitHub, npm, PyPI, and major social networks.Shipped in v0.2 —dpf handlesand--check-handles.Typosquat / brand-similarity flag — Levenshtein distance and bigram similarity against a curated brand list.Shipped in v0.3 —dpf typosquat(default ON indpf check, disable with--no-typosquat).Trademark conflict check — query USPTO, EUIPO, and J-PlatPat for identical and confusingly similar marks.Shipped in v0.4, revised in v0.7.1 —dpf trademarkand--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
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.5 —dpf semantics(default ON indpf check, disable with--no-semantics). Word lists live atdata/negative_meanings/<lang>.txtand accept community PRs with citations.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 atdata/tld_risk.jsonand is loaded at runtime, with the embedded dict as a graceful fallback.scripts/refresh_tld_risk.pyis 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.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.7 —dpf llmo(default ON indpf 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)
- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
966e0ee72758d8d4de23a787f53b14f54c4d1930be18b09004bd82ff3e18a6b3
|
|
| MD5 |
3403236a6f85fa4dd90a816470d6dd30
|
|
| BLAKE2b-256 |
1b4740b815dd9402b7e4820b2a6f4d47243ef7a3576b71d0c7a4630cce130a49
|
Provenance
The following attestation bundles were made for domain_pre_flight-0.9.0.tar.gz:
Publisher:
publish.yml on kenimo49/domain-pre-flight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
domain_pre_flight-0.9.0.tar.gz -
Subject digest:
966e0ee72758d8d4de23a787f53b14f54c4d1930be18b09004bd82ff3e18a6b3 - Sigstore transparency entry: 2096438513
- Sigstore integration time:
-
Permalink:
kenimo49/domain-pre-flight@a13f91ae9ff7a7c648f3e6c49bc05fb354a54d57 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/kenimo49
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a13f91ae9ff7a7c648f3e6c49bc05fb354a54d57 -
Trigger Event:
push
-
Statement type:
File details
Details for the file domain_pre_flight-0.9.0-py3-none-any.whl.
File metadata
- Download URL: domain_pre_flight-0.9.0-py3-none-any.whl
- Upload date:
- Size: 46.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d64740358bf0b9c46c06d2a18fd63483a50cf203434562eb3dfffc5d37047b7
|
|
| MD5 |
4361e52c3a4e2fbb1d16553981324745
|
|
| BLAKE2b-256 |
0be3ccd07149fa42f3424898defbb30733dc0db22b8bd021c3ca60fb22672d3c
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
domain_pre_flight-0.9.0-py3-none-any.whl -
Subject digest:
1d64740358bf0b9c46c06d2a18fd63483a50cf203434562eb3dfffc5d37047b7 - Sigstore transparency entry: 2096438726
- Sigstore integration time:
-
Permalink:
kenimo49/domain-pre-flight@a13f91ae9ff7a7c648f3e6c49bc05fb354a54d57 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/kenimo49
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a13f91ae9ff7a7c648f3e6c49bc05fb354a54d57 -
Trigger Event:
push
-
Statement type: