Bulk domain availability checking via RDAP, DNS, and WHOIS, with prefix/suffix permutations, regex patterns, MCP, and multiple output formats
1,918
stars
226
commits
Go
primary language
Sep 7, 2026
updated

tldx helps you brainstorm available domain names fast.
tldx openai -p get,use -s ly,hub -t com,io,ai --only-available
✅ getopenaily.com is available
✅ useopenaihub.io is available
...

text, json, json-stream, json-array, csv, grouped, or grouped-tldtldx mcp) for AI agentsUsage:
tldx [keywords] [flags]
tldx [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
config Inspect and manage the tldx config file
help Help about any command
mcp Start an MCP (Model Context Protocol) server over stdio
preset Manage custom TLD presets
Flags:
--dry-run Print domains that would be checked without making network calls
--for-sale Check taken domains for an RFC 10023 _for-sale TXT record
-f, --format string Format of output (text, json, json-stream, json-array, csv, grouped, grouped-tld) (default "text")
-h, --help help for tldx
-i, --input string File to read keywords from. Use "-" to read from stdin.
-l, --limit int Stop after finding this many available domains (0 = no limit)
-m, --max-domain-length int Maximum length of domain name (default 64)
--no-color Disable colored output
-a, --only-available Show only available domains
--only-for-sale Show only taken domains that are for sale (implies --for-sale)
-p, --prefixes strings Prefixes to add (e.g. get,my,use)
-r, --regex Enable regex pattern matching for domain keywords
--show-stats Show statistics at the end of execution
-s, --suffixes strings Suffixes to add (e.g. ify,ly)
--tld-preset string Use a tld preset (e.g. popular, tech)
-t, --tlds strings TLDs to check (e.g. com,io,ai)
-v, --verbose Show verbose output
--version version for tldx
Exit code 2 is returned when --only-available is set but no available domains are found.
$ tldx google
❌ google.com is not available
$ tldx google youtube reddit
❌ reddit.com is not available
❌ google.com is not available
❌ youtube.com is not available
--regex treats each keyword as a pattern and checks every combination it expands to:
# All 3-letter .com domains
$ tldx '[a-z]{3}' --regex --tlds com --only-available
✅ aaa.com is available
✅ aab.com is available
...
# All 2-letter domains on specific TLDs
$ tldx '[a-z]{2}' --regex --tlds io,ai --only-available
✅ qa.io is available
✅ zx.ai is available
...
# Patterns combine with prefixes
$ tldx '[a-z]{2}' --regex --prefixes my,get --tlds app --only-available
✅ myaa.app is available
✅ getab.app is available
...
Patterns that expand to more than 500,000 combinations are skipped.
$ tldx google --tld-preset popular
❌ google.com is not available
❌ google.io is not available
...
$ tldx google --tld-preset geo
❌ google.au is not available
❌ google.de is not available
❌ google.us is not available
...
You can see all available presets:
$ tldx preset list
TLD Presets (* = custom):
all (use all available TLDs)
cheap pw fun icu top xyz blog info shop site click
space store online website
popular ai me app com dev net org
tech io ai gg app dev tech codes tools cloud games
software digital network security systems
data technology
...
Save your own TLD presets and reuse them across runs:
# Create a preset
$ tldx preset add myteam com io ai
Saved preset "myteam" (com, io, ai) → ~/.config/tldx/config.toml
# Comma-separated also works
$ tldx preset add myteam com,io,ai
# Use it just like any built-in preset
$ tldx mystartup --tld-preset myteam
❌ mystartup.com is not available
✅ mystartup.io is available
✅ mystartup.ai is available
# List all presets.
$ tldx preset list
TLD Presets (* = custom):
all (use all available TLDs)
myteam * ai io com
popular ai io app com dev net org
...
Config file: ~/.config/tldx/config.toml
# Remove a custom preset
$ tldx preset remove myteam
Removed preset "myteam"
Set a default preset and it applies to every run:
$ tldx preset default nordic
Default preset set to "nordic" → ~/.config/tldx/config.toml
$ tldx mystartup
✅ mystartup.se is available
✅ mystartup.nu is available
❌ mystartup.dk is not available
# Show the current default, or drop it
$ tldx preset default
Default preset: nordic
$ tldx preset default --clear
Cleared default preset (was "nordic") → ~/.config/tldx/config.toml
Everything else goes in the config file. tldx config init writes a commented
template:
[defaults]
# TLDs checked when neither --tlds nor --tld-preset is given
tlds = ["com", "se", "nu"]
# ...or a preset name instead
# tld_preset = "nordic"
prefixes = ["get", "my"]
suffixes = ["ly"]
max_domain_length = 20
format = "json"
limit = 10
only_available = true
show_stats = true
no_color = false
verbose = false
# Read RFC 10023 "_for-sale" records on taken domains.
# only_for_sale implies for_sale.
for_sale = true
only_for_sale = false
# Custom presets, usable via --tld-preset nordic
[presets.nordic]
tlds = ["se", "nu", "dk", "no", "fi"]
Each key under [defaults] matches the flag of the same name, and flags passed
on the command line win. Since tlds and tld_preset both answer "which
TLDs?", passing either --tlds or --tld-preset ignores both configured
values rather than merging with them.
$ tldx config path # where the file lives
$ tldx config show # what's currently configured
$ tldx config init # write a commented template (--force to overwrite)
tldx config init --force replaces the whole file, custom presets included.
The file lives at ~/.config/tldx/config.toml (macOS/Linux) or
%APPDATA%\tldx\config.toml (Windows). A presets.toml from an earlier
version still works — add a [defaults] section to it. Set TLDX_CONFIG to
use a different file.
$ tldx google --prefixes get,my --suffixes ly,hub --tlds com,io,ai
✅ mygooglely.com is available
✅ getgooglely.ai is available
❌ mygoogle.ai is not available
...
Brace expansion works out of the box in bash/zsh:
tldx {get,use}{tldx,domains} {star,fork}ongithub
✅ gettldx.com is available
✅ usetldx.com is available
❌ getdomains.com is not available
...
RFC 10023 defines a _for-sale TXT record that a domain holder can
publish to advertise that the name is for sale, optionally with an asking price and a way to get in touch.
--for-sale reads it:
$ tldx acme -t com,io --for-sale
❌ acme.io is not available
💰 acme.com is taken but for sale — USD 750 · https://fs.example.com/
--only-for-sale keeps just the purchasable ones. Combine it with --only-available to see both kinds of
opportunity at once:
$ tldx acme wile coyote -t com,io --only-for-sale
$ tldx acme wile coyote -t com,io --only-available --only-for-sale
--verbose also prints the free text and broker codes from the record. The lookup costs one extra DNS query
per taken domain and never runs on domains that are already available, so it stays off unless you ask for it.
A holder publishes it like this:
_for-sale.acme.com. IN TXT "v=FORSALE1;fval=USD750"
IN TXT "v=FORSALE1;furi=https://fs.example.com/"
These records are written by the domain holder, so tldx treats them as untrusted: control characters are
stripped, and only http, https, mailto and tel links are shown by default. Any other scheme appears
under --verbose, flagged as unverified.
$ tldx google reddit facebook -p get,my -s ly,hub -t com,io,ai --only-available
✅ getgooglely.ai is available
✅ getreddithub.com is available
...
$ tldx stripe -p get,use -t com,io,ai --only-available --limit 3
✅ getstripe.io is available
✅ usestripe.ai is available
✅ stripe.ai is available
$ tldx stripe -p get,use -t com,io --dry-run
Would check 6 domain(s):
stripe.com
stripe.io
getstripe.com
...
$ tldx --input keywords.txt --tlds com,io --only-available
$ echo -e "stripe\natlas\nlinear" | tldx --input - --tlds com,io --only-available
Output is human-readable (text) by default. Change it with --format / -f.
Color is disabled automatically when stdout is not a terminal.
$ tldx openai -p use -s ly -t io --format json-array
[
{ "domain": "useopenaily.io", "available": true, "keyword": "openai", "prefix": "use", "suffix": "ly", "tld": "io" },
{ "domain": "openai.io", "available": false, "keyword": "openai", "tld": "io" },
...
]
With --show-stats the output is wrapped in an object:
$ tldx openai -p use -s ly -t io --format json-array --show-stats
{
"results": [ ... ],
"stats": { "total": 4, "available": 1, "not_available": 2, "errored": 1 }
}
Results include keyword, prefix, suffix, and tld metadata (empty fields are omitted).
$ tldx openai -p use -s ly -t io --format json-stream
{"domain":"useopenaily.io","available":true,"keyword":"openai","prefix":"use","suffix":"ly","tld":"io"}
{"domain":"openai.io","available":false,"keyword":"openai","tld":"io"}
$ tldx openai -p use -s ly -t io --format csv
domain,available,keyword,prefix,suffix,tld,details,error
useopenaily.io,true,openai,use,ly,io,
openai.io,false,openai,,,io,
$ tldx openai google -p get,use -t com,io --format grouped
google
getgoogle.com
getgoogle.io
google.com
google.io
usegoogle.com
usegoogle.io
openai
getopenai.com
...
$ tldx openai google -p get,use -t com,io --format grouped-tld
.com
getgoogle.com
getopenai.com
google.com
openai.com
usegoogle.com
useopenai.com
.io
getgoogle.io
...
tldx includes an MCP server for AI agents and IDEs.
tldx mcp
Example config (mcp.json / Claude Desktop / VS Code):
{
"mcpServers": {
"tldx": {
"command": "tldx",
"args": ["mcp"]
}
}
}
Two tools, both read-only and returning the same result shape:
| Tool | Use it when |
|---|---|
check_domains | You already know the exact names to test. |
generate_and_check | You want names built from keywords, prefixes, suffixes, and TLDs. |
Your custom presets and [defaults] from the config file apply here just as they
do on the command line. generate_and_check advertises every preset name in its tld_preset schema, so no
separate lookup call is needed.
Each result carries a status of available, taken, or unknown. unknown means the lookup failed, not
that the domain is free, and the available field is omitted entirely in that case.
Each response also reports checked, available_count, taken_count, and — when the search stopped early —
truncated: true plus a note explaining what to change.
One call resolves at most 1000 domains, and generate_and_check is rejected above that before any lookup
happens, naming the argument to shrink. Two ways to search a larger space:
only_available: true with limit: N stops the sweep once N available domains are found, which makes a
wide search cheap. This is usually what you want.dry_run: true returns the exact domain list and count with no network requests, so an agent can price a
call before making it, or see which TLDs a preset expands to.Collection also stops at 45 seconds, under the typical client timeout, returning partial results marked
truncated rather than failing outright.
Both tools accept check_for_sale: true, which adds a for_sale object to any taken domain that advertises
itself for sale, and only_for_sale: true to return just those. See
Domains For Sale.
brew install tldx
or
brew tap brandonyoungdev/tldx
brew install tldx
winget install --id=brandonyoungdev.tldx -e
Two options are available for Arch Linux users:
Visit the Releases page.
Download the archive for your OS and architecture:
tldx_<version>_<os>_<arch>.tar.gztldx_<version>_windows_<arch>.ziptar -xzf tldx_<version>_<os>_<arch>.tar.gz
mv tldx /usr/local/bin/
go install github.com/brandonyoungdev/tldx@latest
144 commits
50 commits
31 commits
1 commits
Go
99.8%
Bulk domain availability checking via RDAP, DNS, and WHOIS, with prefix/suffix permutations, regex patterns, MCP, and multiple output formats
1,918
stars
226
commits
Go
primary language
Sep 7, 2026
updated

tldx helps you brainstorm available domain names fast.
tldx openai -p get,use -s ly,hub -t com,io,ai --only-available
✅ getopenaily.com is available
✅ useopenaihub.io is available
...

text, json, json-stream, json-array, csv, grouped, or grouped-tldtldx mcp) for AI agentsUsage:
tldx [keywords] [flags]
tldx [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
config Inspect and manage the tldx config file
help Help about any command
mcp Start an MCP (Model Context Protocol) server over stdio
preset Manage custom TLD presets
Flags:
--dry-run Print domains that would be checked without making network calls
--for-sale Check taken domains for an RFC 10023 _for-sale TXT record
-f, --format string Format of output (text, json, json-stream, json-array, csv, grouped, grouped-tld) (default "text")
-h, --help help for tldx
-i, --input string File to read keywords from. Use "-" to read from stdin.
-l, --limit int Stop after finding this many available domains (0 = no limit)
-m, --max-domain-length int Maximum length of domain name (default 64)
--no-color Disable colored output
-a, --only-available Show only available domains
--only-for-sale Show only taken domains that are for sale (implies --for-sale)
-p, --prefixes strings Prefixes to add (e.g. get,my,use)
-r, --regex Enable regex pattern matching for domain keywords
--show-stats Show statistics at the end of execution
-s, --suffixes strings Suffixes to add (e.g. ify,ly)
--tld-preset string Use a tld preset (e.g. popular, tech)
-t, --tlds strings TLDs to check (e.g. com,io,ai)
-v, --verbose Show verbose output
--version version for tldx
Exit code 2 is returned when --only-available is set but no available domains are found.
$ tldx google
❌ google.com is not available
$ tldx google youtube reddit
❌ reddit.com is not available
❌ google.com is not available
❌ youtube.com is not available
--regex treats each keyword as a pattern and checks every combination it expands to:
# All 3-letter .com domains
$ tldx '[a-z]{3}' --regex --tlds com --only-available
✅ aaa.com is available
✅ aab.com is available
...
# All 2-letter domains on specific TLDs
$ tldx '[a-z]{2}' --regex --tlds io,ai --only-available
✅ qa.io is available
✅ zx.ai is available
...
# Patterns combine with prefixes
$ tldx '[a-z]{2}' --regex --prefixes my,get --tlds app --only-available
✅ myaa.app is available
✅ getab.app is available
...
Patterns that expand to more than 500,000 combinations are skipped.
$ tldx google --tld-preset popular
❌ google.com is not available
❌ google.io is not available
...
$ tldx google --tld-preset geo
❌ google.au is not available
❌ google.de is not available
❌ google.us is not available
...
You can see all available presets:
$ tldx preset list
TLD Presets (* = custom):
all (use all available TLDs)
cheap pw fun icu top xyz blog info shop site click
space store online website
popular ai me app com dev net org
tech io ai gg app dev tech codes tools cloud games
software digital network security systems
data technology
...
Save your own TLD presets and reuse them across runs:
# Create a preset
$ tldx preset add myteam com io ai
Saved preset "myteam" (com, io, ai) → ~/.config/tldx/config.toml
# Comma-separated also works
$ tldx preset add myteam com,io,ai
# Use it just like any built-in preset
$ tldx mystartup --tld-preset myteam
❌ mystartup.com is not available
✅ mystartup.io is available
✅ mystartup.ai is available
# List all presets.
$ tldx preset list
TLD Presets (* = custom):
all (use all available TLDs)
myteam * ai io com
popular ai io app com dev net org
...
Config file: ~/.config/tldx/config.toml
# Remove a custom preset
$ tldx preset remove myteam
Removed preset "myteam"
Set a default preset and it applies to every run:
$ tldx preset default nordic
Default preset set to "nordic" → ~/.config/tldx/config.toml
$ tldx mystartup
✅ mystartup.se is available
✅ mystartup.nu is available
❌ mystartup.dk is not available
# Show the current default, or drop it
$ tldx preset default
Default preset: nordic
$ tldx preset default --clear
Cleared default preset (was "nordic") → ~/.config/tldx/config.toml
Everything else goes in the config file. tldx config init writes a commented
template:
[defaults]
# TLDs checked when neither --tlds nor --tld-preset is given
tlds = ["com", "se", "nu"]
# ...or a preset name instead
# tld_preset = "nordic"
prefixes = ["get", "my"]
suffixes = ["ly"]
max_domain_length = 20
format = "json"
limit = 10
only_available = true
show_stats = true
no_color = false
verbose = false
# Read RFC 10023 "_for-sale" records on taken domains.
# only_for_sale implies for_sale.
for_sale = true
only_for_sale = false
# Custom presets, usable via --tld-preset nordic
[presets.nordic]
tlds = ["se", "nu", "dk", "no", "fi"]
Each key under [defaults] matches the flag of the same name, and flags passed
on the command line win. Since tlds and tld_preset both answer "which
TLDs?", passing either --tlds or --tld-preset ignores both configured
values rather than merging with them.
$ tldx config path # where the file lives
$ tldx config show # what's currently configured
$ tldx config init # write a commented template (--force to overwrite)
tldx config init --force replaces the whole file, custom presets included.
The file lives at ~/.config/tldx/config.toml (macOS/Linux) or
%APPDATA%\tldx\config.toml (Windows). A presets.toml from an earlier
version still works — add a [defaults] section to it. Set TLDX_CONFIG to
use a different file.
$ tldx google --prefixes get,my --suffixes ly,hub --tlds com,io,ai
✅ mygooglely.com is available
✅ getgooglely.ai is available
❌ mygoogle.ai is not available
...
Brace expansion works out of the box in bash/zsh:
tldx {get,use}{tldx,domains} {star,fork}ongithub
✅ gettldx.com is available
✅ usetldx.com is available
❌ getdomains.com is not available
...
RFC 10023 defines a _for-sale TXT record that a domain holder can
publish to advertise that the name is for sale, optionally with an asking price and a way to get in touch.
--for-sale reads it:
$ tldx acme -t com,io --for-sale
❌ acme.io is not available
💰 acme.com is taken but for sale — USD 750 · https://fs.example.com/
--only-for-sale keeps just the purchasable ones. Combine it with --only-available to see both kinds of
opportunity at once:
$ tldx acme wile coyote -t com,io --only-for-sale
$ tldx acme wile coyote -t com,io --only-available --only-for-sale
--verbose also prints the free text and broker codes from the record. The lookup costs one extra DNS query
per taken domain and never runs on domains that are already available, so it stays off unless you ask for it.
A holder publishes it like this:
_for-sale.acme.com. IN TXT "v=FORSALE1;fval=USD750"
IN TXT "v=FORSALE1;furi=https://fs.example.com/"
These records are written by the domain holder, so tldx treats them as untrusted: control characters are
stripped, and only http, https, mailto and tel links are shown by default. Any other scheme appears
under --verbose, flagged as unverified.
$ tldx google reddit facebook -p get,my -s ly,hub -t com,io,ai --only-available
✅ getgooglely.ai is available
✅ getreddithub.com is available
...
$ tldx stripe -p get,use -t com,io,ai --only-available --limit 3
✅ getstripe.io is available
✅ usestripe.ai is available
✅ stripe.ai is available
$ tldx stripe -p get,use -t com,io --dry-run
Would check 6 domain(s):
stripe.com
stripe.io
getstripe.com
...
$ tldx --input keywords.txt --tlds com,io --only-available
$ echo -e "stripe\natlas\nlinear" | tldx --input - --tlds com,io --only-available
Output is human-readable (text) by default. Change it with --format / -f.
Color is disabled automatically when stdout is not a terminal.
$ tldx openai -p use -s ly -t io --format json-array
[
{ "domain": "useopenaily.io", "available": true, "keyword": "openai", "prefix": "use", "suffix": "ly", "tld": "io" },
{ "domain": "openai.io", "available": false, "keyword": "openai", "tld": "io" },
...
]
With --show-stats the output is wrapped in an object:
$ tldx openai -p use -s ly -t io --format json-array --show-stats
{
"results": [ ... ],
"stats": { "total": 4, "available": 1, "not_available": 2, "errored": 1 }
}
Results include keyword, prefix, suffix, and tld metadata (empty fields are omitted).
$ tldx openai -p use -s ly -t io --format json-stream
{"domain":"useopenaily.io","available":true,"keyword":"openai","prefix":"use","suffix":"ly","tld":"io"}
{"domain":"openai.io","available":false,"keyword":"openai","tld":"io"}
$ tldx openai -p use -s ly -t io --format csv
domain,available,keyword,prefix,suffix,tld,details,error
useopenaily.io,true,openai,use,ly,io,
openai.io,false,openai,,,io,
$ tldx openai google -p get,use -t com,io --format grouped
google
getgoogle.com
getgoogle.io
google.com
google.io
usegoogle.com
usegoogle.io
openai
getopenai.com
...
$ tldx openai google -p get,use -t com,io --format grouped-tld
.com
getgoogle.com
getopenai.com
google.com
openai.com
usegoogle.com
useopenai.com
.io
getgoogle.io
...
tldx includes an MCP server for AI agents and IDEs.
tldx mcp
Example config (mcp.json / Claude Desktop / VS Code):
{
"mcpServers": {
"tldx": {
"command": "tldx",
"args": ["mcp"]
}
}
}
Two tools, both read-only and returning the same result shape:
| Tool | Use it when |
|---|---|
check_domains | You already know the exact names to test. |
generate_and_check | You want names built from keywords, prefixes, suffixes, and TLDs. |
Your custom presets and [defaults] from the config file apply here just as they
do on the command line. generate_and_check advertises every preset name in its tld_preset schema, so no
separate lookup call is needed.
Each result carries a status of available, taken, or unknown. unknown means the lookup failed, not
that the domain is free, and the available field is omitted entirely in that case.
Each response also reports checked, available_count, taken_count, and — when the search stopped early —
truncated: true plus a note explaining what to change.
One call resolves at most 1000 domains, and generate_and_check is rejected above that before any lookup
happens, naming the argument to shrink. Two ways to search a larger space:
only_available: true with limit: N stops the sweep once N available domains are found, which makes a
wide search cheap. This is usually what you want.dry_run: true returns the exact domain list and count with no network requests, so an agent can price a
call before making it, or see which TLDs a preset expands to.Collection also stops at 45 seconds, under the typical client timeout, returning partial results marked
truncated rather than failing outright.
Both tools accept check_for_sale: true, which adds a for_sale object to any taken domain that advertises
itself for sale, and only_for_sale: true to return just those. See
Domains For Sale.
brew install tldx
or
brew tap brandonyoungdev/tldx
brew install tldx
winget install --id=brandonyoungdev.tldx -e
Two options are available for Arch Linux users:
Visit the Releases page.
Download the archive for your OS and architecture:
tldx_<version>_<os>_<arch>.tar.gztldx_<version>_windows_<arch>.ziptar -xzf tldx_<version>_<os>_<arch>.tar.gz
mv tldx /usr/local/bin/
go install github.com/brandonyoungdev/tldx@latest
144 commits
50 commits
31 commits
1 commits
Go
99.8%