Skip to main content
Glama

NameInsight

CI

AI-powered domain name discovery. Generate brandable names, check availability across TLDs, and get rich insights (registry data, DNS, expiry, parking, email and TLS setup), as an MCP server for AI assistants or as a REST API.

Features

  • Authoritative availability: registry data over RDAP (with WHOIS fallback and parsing for TLDs without RDAP), plus DNS and ping signals, combined into a status (available, registered, parked, expiring, unknown) with a confidence level and plain-English reasons.

  • Registration facts: creation and expiry dates, domain age, days until expiry, registrar, EPP status and nameservers. Subdomains are looked up via their registrable domain (Public Suffix List).

  • Insights (?insights=true): nameservers, email setup (MX, SPF, DMARC policy) and an HTTPS/TLS certificate check.

  • AI name suggestions: brainstorm names for a business, then verify every one across TLDs with real lookups and rank by availability.

  • MCP server: check_domain, check_domains, check_name_across_tlds and suggest_domains, locally over stdio or hosted over Streamable HTTP.

  • Built for a public deployment: no authentication required. Abuse is limited by per-IP rate limits and lookup budgets, size and time limits on everything, and strict protection against reaching private networks (SSRF).

Related MCP server: Domain Checker MCP Server

Quick start

npm install && npm run build
npm start                     # REST API + hosted MCP on http://127.0.0.1:8080 (Swagger at /api-docs)
npm run start:mcp             # MCP server over stdio for local AI clients
curl http://127.0.0.1:8080/api/v1/domains/info/example.com
claude mcp add nameinsight -- node "$PWD/dist/app/mcp/stdio.js"

Then ask your assistant: "Is nameinsight available as a .com or .io?"

How it works

For each domain NameInsight:

  1. Resolves its A and AAAA records in DNS.

  2. Queries the registry over RDAP (registration status, dates, registrar, nameservers, DNSSEC), using IANA's bootstrap registry to find the right server.

  3. Runs a WHOIS lookup (fallback for TLDs without RDAP, such as .io and .de).

  4. Pings its first public IPv4 address (via the ping package).

Each result looks like this:

{
  "domain": "example.com",
  "status": "registered",
  "confidence": "high",
  "registration": { "source": "rdap", "registered": true, "created": "1995-08-14T04:00:00Z", "expires": "2027-08-13T04:00:00Z", "ageDays": 11387, "daysUntilExpiry": 299, "registrar": "…" },
  "reasons": ["Registry (RDAP) reports the domain is registered (registrar: …)"],
  "available": false,
  "probe": { "host": "example.com", "alive": true, "time": 38.9, "numeric_host": "104.20.23.154", "...": "..." },
  "dns": { "addresses": ["104.20.23.154", "2606:4700:10::6814:179a"] },
  "rdap": { "registered": true, "registrar": "…", "created": "1995-08-14T04:00:00Z", "expires": "2027-08-13T04:00:00Z", "…": "…" },
  "whois": "Domain Name: EXAMPLE.COM\n...",
  "…": "…"
}

status is one of available, registered, parked (nameservers at a parking or for-sale marketplace), expiring (expires within 30 days, or the registry is deleting it) or unknown. confidence says how sure it is:

Confidence

Meaning

high

The registry answered: RDAP, or WHOIS text that clearly says registered / not registered

medium

No registry data, but the domain has DNS records (so it is registered)

low

No registry data and no DNS records or ping replies: an estimate

reasons explains the decision in plain English, and available is shorthand for status === "available".

Prerequisites

  • Node.js 22 or newer (engines in package.json) and npm

  • Outbound network access for DNS, HTTPS (RDAP), ICMP ping and WHOIS (TCP port 43)

Getting started

npm install
npm run start:tsnode

The service starts on http://127.0.0.1:8080 (loopback only by default).

Script

What it does

npm start

Compile TypeScript, then run the compiled app (dist/app/index.js)

npm run start:dist

Run the already-compiled app without rebuilding

npm run start:mcp

Run the compiled MCP server over stdio (see MCP server)

npm run start:tsnode

Run the app from source with ts-node

npm run start-watch:tsnode

Run from source and restart when a file changes (Node's built-in --watch)

npm run inspect:tsnode

Run with the Node inspector attached, for debugging

npm run build

Delete dist/, then compile TypeScript into it

npm run clean

Delete dist/

npm run lint

Lint app/ with ESLint and typescript-eslint (eslint.config.mjs)

npm run typecheck

Type-check without emitting files

npm test

Run the test suite (npm run test:coverage for coverage)

npm run secrets

Scan the project for committed secrets (API keys, tokens, private keys) with secretlint

Git hooks are managed by husky and installed by npm install (the prepare script):

  • pre-commit blocks commits containing secrets. It runs npm run secrets, plus gitleaks on the staged changes if gitleaks is installed (brew install gitleaks).

  • pre-push runs npm run lint and npm run typecheck.

TypeScript and ts-node are development dependencies. For a production install (npm ci --omit=dev), build first (e.g. in CI or a Docker build stage) and run npm run start:dist.

Configuration

All settings are optional environment variables (see app/config/global.config.ts). .env.example lists them all; copy it to .env (gitignored) and run with node --env-file=.env ./dist/app/index.js.

Never commit secrets. API keys and tokens belong only in environment variables or an untracked .env file. .env* (except .env.example), .npmrc and key/certificate files are gitignored, and commits are scanned for secrets.

Variable

Default

Description

API_PORT

8080

Port the server listens on

API_HOST

127.0.0.1

Address the server binds to. Set 0.0.0.0 to serve other machines (e.g. in a container)

APP_NAME

NameInsight

API title shown in Swagger UI

LOG_REQUESTS

true

Set to false to turn off the per-request access log

SHUTDOWN_TIMEOUT_MS

10000

On SIGTERM/SIGINT, how long in-flight requests may finish before connections are force-closed

CORS_ORIGINS

(empty)

Comma-separated origins allowed to call the API from a browser, e.g. https://app.example.com. Empty means no cross-origin access

TRUST_PROXY_HOPS

0

Number of reverse proxies in front of the service. Set this behind a load balancer so rate limiting uses the real client IP

RATE_LIMIT_MAX

30

Requests allowed per client IP per window on /api/*

RATE_LIMIT_WINDOW_MS

60000

Rate-limit window in milliseconds

LOOKUP_BUDGET_MAX

200

Domains each client IP may look up per window (a bulk request costs one per domain)

LOOKUP_BUDGET_WINDOW_MS

60000

Lookup-budget window in milliseconds

MAX_DOMAINS_PER_REQUEST

50

Maximum domains in one bulk request

LOOKUP_CONCURRENCY

5

Domains looked up at the same time within one request

MAX_CONCURRENT_LOOKUPS

20

Domains looked up at the same time across all requests

MAX_QUEUED_LOOKUPS

100

Lookups allowed to wait for a slot; beyond this, requests get 503 + Retry-After

MAX_CONCURRENT_REQUESTS_PER_CLIENT

2

Requests one client IP may have in flight on /api and /mcp

DNS_SERVERS

(system resolvers)

Comma-separated DNS server IPs, e.g. 1.1.1.1,8.8.8.8. Set this when the host's resolver also answers for internal zones

MAX_BODY_BYTES

16384

Maximum JSON / form body size

MAX_UPLOAD_BYTES

65536

Maximum uploaded file size

DNS_TIMEOUT_MS

5000

DNS query timeout

PING_TIMEOUT_SECONDS

2

Ping reply timeout

WHOIS_TIMEOUT_MS

10000

Hard deadline per WHOIS server (a lookup can follow up to 2 referrals)

MAX_WHOIS_RESPONSE_BYTES

131072

WHOIS responses longer than this are truncated

RDAP_TIMEOUT_MS

5000

Hard deadline per RDAP request

MAX_RDAP_RESPONSE_BYTES

262144

Larger RDAP responses are discarded

WEB_CHECK_TIMEOUT_MS

5000

Hard deadline for the insights HTTPS check

ANTHROPIC_API_KEY

(empty)

Secret. Enables REST AI suggestions (and the MCP fallback). Set only in the environment; never commit

AI_MODEL

claude-opus-5-5

Claude model used for suggestions

AI_EFFORT

medium

Effort level for suggestions (low, medium, high)

SUGGEST_RATE_LIMIT_MAX

5

Suggestion requests per client IP per rate-limit window (REST and MCP combined)

GLOBAL_SUGGEST_MAX_PER_HOUR

100

Claude API suggestion calls per hour for the whole process (caps spend on the server key)

MAX_CONCURRENT_AI_CALLS

2

Claude API calls in flight at once

ALLOWED_HOSTS

(empty)

Comma-separated Host headers the server accepts (DNS-rebinding protection). Empty: localhost names only on a loopback bind, any host otherwise (with a startup warning). MCP_ALLOWED_HOSTS is an older alias

Numeric values must be non-negative integers; the app refuses to start otherwise.

For example: API_PORT=3000 npm run start:tsnode

AI name suggestions

NameInsight can brainstorm brandable names for a business and then verify every one across TLDs with real registry lookups, ranking them by availability (.com weighted highest). The model only proposes names; every status comes from NameInsight's own lookups.

  • REST: POST /api/v1/domains/suggest with { "description": "...", "count": 8, "tlds": ["com","io"], "style": "brandable" } (style: any, brandable, descriptive, short, compound). Uses the Claude API (claude-opus-5-5 by default) and is enabled only when ANTHROPIC_API_KEY is set in the server's environment; otherwise it returns 503. It is limited to SUGGEST_RATE_LIMIT_MAX requests per client IP per window, and its lookups count toward the lookup budget.

  • MCP: the suggest_domains tool uses your own AI client's model through MCP sampling (no key needed on the server). If the client doesn't support sampling, it falls back to the server's Claude API key if one is configured.

Spend on the server's key is capped by the per-IP suggestion limit, a process-wide hourly limit (GLOBAL_SUGGEST_MAX_PER_HOUR), a cap on concurrent AI calls, a 30 s timeout and one retry. For a public deployment, also set a spend limit in the Anthropic Console, and consider a lower-cost AI_MODEL.

API keys are secrets. Set ANTHROPIC_API_KEY only in the runtime environment or an untracked .env file. Never commit it. NameInsight never logs, stores or returns it.

The business description is treated as untrusted data: it is length-limited, clearly delimited in the prompt, and the model can only return names, which are cleaned, validated and checked before anyone sees them.

MCP server

NameInsight is also an MCP server, so AI assistants such as Claude can check domains directly. It runs locally over stdio:

npm install && npm run build
npm run start:mcp          # or: node dist/app/mcp/stdio.js

Claude Code:

claude mcp add nameinsight -- node /absolute/path/to/name-insight/dist/app/mcp/stdio.js

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "nameinsight": {
      "command": "node",
      "args": ["/absolute/path/to/name-insight/dist/app/mcp/stdio.js"]
    }
  }
}

Tool

What it does

check_domain

One domain: status, confidence, reasons, registration (dates, registrar), DNS and ping. insights: true adds nameservers, email setup and HTTPS/TLS; include_raw_whois: true adds the raw WHOIS text

check_domains

Up to 50 domains at once

check_name_across_tlds

One name across TLDs (default .com .net .org .io .ai .dev .app .co, or your own list), listing which are available

suggest_domains

Brainstorms names for a description (via MCP sampling, or the server's Claude API key), checks them across TLDs and ranks by availability

Hosted (Streamable HTTP)

The REST server also exposes a public, stateless MCP endpoint at POST /mcp (no API keys), so remote clients can connect without installing anything:

claude mcp add --transport http nameinsight https://your-host.example/mcp

Each request gets a fresh server, and tool calls draw on the same per-IP limits as the REST API (one shared request limit, lookup budget and suggestion limit). Over HTTP the server can't use client sampling, so suggest_domains needs ANTHROPIC_API_KEY on the server there. Set ALLOWED_HOSTS to your public hostname(s) to turn on DNS-rebinding protection. GET and DELETE return 405, and JSON-RPC batches are rejected.

All tools are read-only. Results are compact (no raw WHOIS or ping output unless asked) and come with a typed structuredContent payload plus a one-line summary per domain. Invalid input returns a readable tool error. Logs go to stderr so they never interfere with the protocol on stdout.

Try asking: "Is nameinsight available as a .com or .io?" or "Check these five names and tell me which ones expire soon."

API documentation (Swagger)

With the server running, open:

Swagger UI lists every endpoint, with sample request bodies, example responses and the response schemas. Use Try it out to send real requests to your local server.

Request and response schemas are generated from the zod contract in app/core/schemas.ts (also the source of the TypeScript types and, later, the MCP tool inputs), so they can't drift from the code. Paths, descriptions and examples live in app/http/docs/openapi.ts; contract tests check real responses and the documented examples against the schemas.

Endpoints

Method

Path

Input

GET

/api/v1/domains/info/:domain

A single domain in the URL

POST

/api/v1/domains/info/_payload

JSON body: { "domains": ["a.com", "b.com"] }

POST

/api/v1/domains/info/_file

multipart/form-data with a file field: a text/plain file, one domain per line

GET

/healthz

Health check: 200 {"status":"ok"}, or 503 once shutdown has started

POST

/api/v1/domains/suggest

AI name suggestions, verified by real lookups (see AI name suggestions)

POST

/mcp

Hosted MCP endpoint (Streamable HTTP, JSON-RPC; see MCP server)

The bulk endpoints return an array with one result per unique domain, in input order.

Add ?insights=true to any lookup endpoint for extra signals (slower): DNS nameservers, email setup (MX, whether it accepts mail, SPF, DMARC policy) and an HTTPS check of https://<domain>/ (status, redirect target, TLS certificate validity, issuer and days remaining). Nameservers found this way also feed parking detection.

On SIGTERM/SIGINT the server stops accepting connections, lets in-flight lookups finish (up to SHUTDOWN_TIMEOUT_MS), then exits. A second signal exits immediately.

Input rules and errors

  • Subdomains are accepted: registry data and status refer to the registrable domain (Public Suffix List), e.g. news.bbc.co.uk is looked up as bbc.co.uk (returned as registrableDomain), while DNS and web checks use the full name. Public suffixes themselves (co.uk, com.au) are rejected.

  • Only public domain names are accepted. IP addresses, localhost, internal suffixes (.local, .internal, .lan, .test, ...) and malformed names are rejected with 400. Internationalized names (e.g. münchen.de) are converted to punycode. Only real (ICANN) top-level domains are accepted.

  • Bulk requests accept at most 50 domains (MAX_DOMAINS_PER_REQUEST). If any domain is invalid, the whole request is rejected with 400 and details.invalid lists each bad entry.

  • Uploaded files must be text/plain and at most 64 KB. Blank lines and lines starting with # are ignored. Files are processed in memory and never written to disk.

  • Domains that resolve to private or reserved addresses (e.g. 10.x, 127.x, 169.254.x) are never pinged; their probe.skipped is "non-public-address". Private addresses are left out of dns.addresses, and dns.nonPublic is set to true instead.

  • WHOIS referrals (the registry pointing to the registrar's WHOIS server) are only followed to public addresses on port 43. If the registrar's server fails, the registry's response is returned.

  • RDAP requests use HTTPS only (certificates validated), connect only to public IPv4 addresses, never follow redirects or links, and are size- and time-limited.

  • The insights website check connects only to public IPv4 addresses, sends a HEAD request (headers only), never follows redirects, and accepts invalid certificates only so it can report them (nothing sensitive is sent).

  • A WHOIS failure doesn't fail the request: that domain gets whois: null and a whoisError message.

  • POST bodies must be JSON (Content-Type: application/json); other content types get 415. This stops other websites from triggering requests from their visitors' browsers with plain HTML forms.

  • Each client IP may have a few requests in flight at once (429 beyond that), and work for a client that disconnects is cancelled. When the server is saturated, requests get 503 with Retry-After.

  • Errors are JSON: { "error": "message", "details": { ... } }. Too many requests, or more domains than the client's lookup budget allows, returns 429 (the budget response includes Retry-After).

Quick test with curl

# Single domain
curl http://localhost:8080/api/v1/domains/info/example.com

# Several domains in a JSON body
curl -X POST http://localhost:8080/api/v1/domains/info/_payload \
  -H 'Content-Type: application/json' \
  -d '{"domains": ["example.com", "some-unregistered-name-xyz.com"]}'

# File upload
printf "example.com\ngoogle.com\n" > domains.txt
curl -F "file=@domains.txt;type=text/plain" http://localhost:8080/api/v1/domains/info/_file

Project structure

app/
├── index.ts                    # Entry point: starts the HTTP server
├── config/global.config.ts     # Environment-based configuration
├── core/                       # Transport-independent logic, shared by REST and MCP
│   ├── index.ts                # Public core API
│   ├── domain-service.ts       # DNS, ping and WHOIS per domain; text-file parsing
│   ├── validation.ts           # Domain name validation and public-IP checks
│   ├── dns.ts                  # DNS resolver with timeout and optional DNS_SERVERS
│   ├── whois.ts                # WHOIS client: referral checks, size cap, hard deadline
│   ├── rdap.ts                 # RDAP client with cached IANA bootstrap
│   ├── whois-parse.ts          # Registration facts from raw WHOIS text
│   ├── availability.ts         # status / confidence / reasons from all signals
│   ├── insights.ts             # optional NS, MX/SPF/DMARC and HTTPS/TLS checks
│   ├── suggestions.ts          # AI name suggestions: prompt, validation, verification, ranking
│   ├── claude-generator.ts     # Claude API name generator (structured output)
│   ├── http-client.ts          # HTTPS JSON client: public-address pinning, size cap, deadline
│   ├── schemas.ts              # zod data contract: types, OpenAPI schemas, MCP inputs
│   └── errors.ts               # ValidationError (mapped to 400 by the HTTP layer)
├── mcp/                        # MCP server (tools) and stdio entry point
├── http/                       # REST API (Express)
│   ├── app.ts                  # createApp(): middleware, Swagger mount, routes, error handling
│   ├── mcp-route.ts            # Hosted stateless MCP endpoint (POST /mcp)
│   ├── budgets.ts              # Per-IP lookup and suggestion budgets shared by REST and MCP
│   ├── http-error.ts           # Error type carrying an HTTP status
│   ├── docs/openapi.ts         # OpenAPI spec (generated from core schemas) served at /api-docs
│   └── routes/                 # Route registration, domain endpoints, file uploads
├── types/                      # Type declarations for untyped packages
└── utils/async.ts              # Timeout, concurrency, semaphore and error helpers

Testing

npm test               # Jest unit + HTTP tests (no network access needed)
npm run test:coverage  # with a coverage report

CI (.github/workflows/ci.yml) runs lint, typecheck, tests, build, npm audit and a secret scan (gitleaks on the full git history plus secretlint) on every pull request. Dependabot opens weekly dependency update PRs.

Tests live in test/. DNS, ping and WHOIS are mocked or served by local fake servers, so the suite is fast and deterministic. HTTP behavior is tested with supertest against createApp() (app/http/app.ts), which builds the Express app without listening on a port.

Known limitations

  • Public by design. There is no authentication; abuse is limited by per-IP rate limits and lookup budgets, request size/time limits, and the private-network protections. Set TRUST_PROXY_HOPS behind a load balancer so limits apply to real client IPs.

  • Rate limits and lookup budgets are per process and in memory. They reset on restart, and N instances allow N times the limits.

  • WHOIS servers rate-limit heavy use. Large or frequent bulk requests may start getting whoisError results.

  • Confidence varies by TLD. With RDAP or a clear WHOIS answer, status is authoritative (high). Some registries offer neither, and then the answer is an estimate (medium or low); check confidence before relying on it.

  • Parking detection is a heuristic based on a list of known parking and marketplace nameservers.

  • RDAP redirects are not followed (to keep outbound requests predictable); such registries fall back to WHOIS. Registry-reserved or premium names can appear as "available" when the registry reports them as not registered.

  • Deploying publicly: bind API_HOST=0.0.0.0, set ALLOWED_HOSTS to your hostname(s), set TRUST_PROXY_HOPS to the exact number of proxies in front of the service, and consider DNS_SERVERS (public resolvers) so internal DNS views are never consulted. The server warns at startup about the first two.

Status and roadmap

Shipped: RDAP and WHOIS registry data with availability status and confidence, registration facts, subdomain handling, DNS, email and TLS insights, AI name suggestions (Claude API and MCP sampling), MCP server (stdio and hosted HTTP), zod-generated OpenAPI docs, per-IP abuse limits, graceful shutdown and health checks, and CI with secret scanning.

Ideas under consideration (not yet planned or promised):

  • Container image and a deployment guide

  • Shared rate-limit and budget storage (e.g. Redis) for multi-instance deployments

  • Short-lived caching of lookup results

  • Trademark and look-alike checks for suggested names

  • A small web UI

Suggestions and contributions are welcome; see below.

Contributing and security

See CONTRIBUTING.md for the branch naming convention and PR workflow. Report vulnerabilities privately as described in SECURITY.md.

License

MIT © 2026 Himan Patel

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to check domain availability across multiple TLDs with real-time pricing, brainstorm creative domain names, analyze domains for brandability and SEO potential, and search for domains by price and category without CAPTCHAs.
    17 npm
    3
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to check domain availability, perform batch domain lookups, and generate intelligent domain name suggestions across multiple TLDs using WHOIS integration.
    3
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to check domain name availability for single or multiple domains using DNS, RDAP, and WHOIS lookups. It provides detailed registration status including registrar information and expiration dates while supporting bulk checks of up to 50 domains.
    2
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables domain name availability checking through DNS and WHOIS lookups with confidence scoring. It supports searching across alternative TLDs and generating domain name variations for branding purposes.
    4
    -