Skip to main content
Glama
LearnerSumit

domain-checker-mcp

by LearnerSumit

Domain Checker MCP

A production-ready remote MCP (Model Context Protocol) server that lets AI assistants such as Claude check whether a domain name is available for registration — powered by free, public RDAP lookups against the IANA-published registry servers. No API key, no signup, no rate-limited third-party plan.

"Check whether mybrand.ai is available." → Claude calls the check_domain_availability tool → clean, structured answer.

  • Transport: stateless Streamable HTTP (MCP spec 2026-07-28, mcp-handler v2 / MCP SDK v2)

  • Deploy target: Vercel serverless (also runs locally over stdio)

  • One tool: check_domain_availability


Live instance

A hosted instance is running here:

MCP endpoint

https://domain-checker-mcp.vercel.app/mcp

Landing page

https://domain-checker-mcp.vercel.app

Health

https://domain-checker-mcp.vercel.app/health

Add that endpoint URL to Claude (step by step below) and start asking. There's a per-IP rate limit to keep the shared instance fair to everyone — for anything real, run your own copy (free, ~2 minutes, no API key needed).


Related MCP server: Domain Checker MCP Server

Table of contents

  1. What it does

  2. Use it in Claude — step by step

  3. Run your own copy (recommended)

  4. Local development

  5. Architecture & project layout

  6. The MCP tool

  7. Configuration

  8. Error handling

  9. Security & abuse protection

  10. Notes for hosting a public shared instance


What it does

Tool

check_domain_availability

Input

{ "name": "mybrand", "tld": "ai" } (both required strings)

Output

Readable text + structuredContent (available, tldValid, checkMethod, …)

Input is normalised before the upstream call: trimmed, lower-cased, a leading dot on the TLD is removed (.AIai), a redundant TLD in the name is de-duplicated (mybrand.ai + aimybrand), and full URLs / invalid characters are rejected with a safe message.


Use it in Claude — step by step

Examples below use the live instance (https://domain-checker-mcp.vercel.app/mcp). If you deployed your own, swap in https://<your-project>.vercel.app/mcp.

📺 Watch a short video walkthrough of connecting this server to Claude.

A. Claude.ai (web) or Claude Desktop — custom connector

  1. Open Claude → click your name / avatar → Settings.

  2. Go to Connectors (on some plans: Feature preview → Model Context Protocol).

  3. Click Add custom connector (or Add connector → Custom).

  4. Fill in:

    • Name: Domain Checker

    • URL: https://domain-checker-mcp.vercel.app/mcp ← note the /mcp path

  5. Click Add / Save. The connector needs no authentication.

  6. Open a chat. Click the connectors / tools button (🔌 or the slider icon near the prompt box) and make sure Domain Checker is enabled for the conversation.

  7. Ask a question (see prompts to try). The first time, Claude will ask permission to use the tool — click Allow.

Requirements: custom/remote MCP connectors are available on Claude Pro, Max, Team, and Enterprise. On a free plan you can still use it locally over stdio (see Local: Claude Desktop over stdio).

B. Claude Code (CLI)

claude mcp add --transport http domain-checker https://domain-checker-mcp.vercel.app/mcp

Verify:

claude mcp list
# domain-checker   http   https://domain-checker-mcp.vercel.app/mcp   ✓ connected

Then in a Claude Code session just ask: "Is mybrand.io available?" To remove it later: claude mcp remove domain-checker.

C. Local: Claude Desktop over stdio

If you cloned the repo and want to run it locally (no hosting, works on any plan):

npm install
npm run build

Edit your claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "domain-checker": {
      "command": "node",
      "args": ["/absolute/path/to/domain-checker-mcp/dist/index.js"]
    }
  }
}

Restart Claude Desktop. The tool appears under the 🔌 menu.

D. Cursor / Windsurf / other MCP clients

Add to the client's MCP config (e.g. .cursor/mcp.json):

{
  "mcpServers": {
    "domain-checker": { "url": "https://domain-checker-mcp.vercel.app/mcp" }
  }
}

Prompts to try

Check mybrand.ai
Is mybrand.com available?
Check whether mybrand.io is available
Are any of these free: acme.dev, acme.io, acme.ai?

Claude should call check_domain_availability with, e.g., { "name": "mybrand", "tld": "ai" } and report the status.


The public repo is meant to be cloned and self-hosted. There's no API key to sign up for and no shared quota to worry about — RDAP is free and public. Takes ~2 minutes.

1. Get the code

git clone https://github.com/LearnerSumit/domain-checker-mcp.git
cd domain-checker-mcp
npm install

(Or click Fork on GitHub first, then clone your fork.)

2. Deploy to Vercel

Option A — Dashboard (easiest)

  1. Push your copy to GitHub (git push).

  2. Go to https://vercel.com/new and import the repository.

  3. Leave build settings as detected (the included vercel.json handles everything — no framework, no build command, no environment variables required). Application Preset "Node" is fine.

  4. Click Deploy.

Option B — Vercel CLI

npm i -g vercel
vercel login
vercel link
vercel --prod

3. Verify

curl https://your-project.vercel.app/health
# {"status":"ok","server":"domain-checker-mcp","version":"1.0.0"}

curl -s -X POST https://your-project.vercel.app/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Visiting https://your-project.vercel.app/ in a browser shows a small landing page with the endpoint and connect instructions.

4. Connect it to Claude

Use the URL https://your-project.vercel.app/mcp and follow Use it in Claude.


Local development

cp .env.example .env        # optional — safe defaults work out of the box
npm run dev                 # HTTP dev server → http://localhost:3000/mcp  (+ /health, + landing page)
npm run dev:stdio           # stdio transport with hot reload
npm run typecheck           # tsc --noEmit
npm test                    # Vitest (RDAP mocked — no network needed)
npm run build               # compile src/ → dist/
npm start                   # run the compiled stdio server (dist/index.js)
npm run inspect             # open the MCP Inspector

Test the running dev server with the Inspector (Streamable HTTP, URL http://localhost:3000/mcp) or curl:

curl -s -X POST http://localhost:3000/mcp \
  -H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_domain_availability","arguments":{"name":"mybrand","tld":"ai"}}}'

Architecture & project layout

Claude ──HTTPS──▶ Vercel Function (api/mcp.ts)
                       │
                       ▼
                 mcp-handler  (Streamable HTTP, stateless)
                       │
                       ▼
        check_domain_availability tool  (src/tools/domain.ts)
              │                    │
              ▼                    ▼
   per-client rate limit    validation/domain.ts   ──▶  services/rdap.ts
   (src/utils/rateLimit)    (normalise + validate)      (the only outbound calls:
                                                         timeout + error mapping)
                                                              │
                                    ┌─────────────────────────┴─────────────────────────┐
                                    ▼                                                    ▼
                    GET https://data.iana.org/rdap/dns.json          GET https://<registry-rdap-server>/domain/<name>
                    (bootstrap: resolve TLD → RDAP server,             (200 = registered, 404 = available)
                     cached in memory)

Path

Purpose

api/mcp.ts

Vercel Function — the remote MCP endpoint (GET/POST/DELETE)

api/health.ts

Vercel Function — GET /health

public/index.html

Landing page served at /

src/server.ts

Builds the mcp-handler handler; registers capabilities

src/index.ts

Local stdio entrypoint (npm start)

src/dev.ts

Local HTTP dev server — same handler as Vercel

src/tools/domain.ts

The check_domain_availability tool (rate limit + thin handler + formatter)

src/services/rdap.ts

The only module that talks to RDAP (IANA bootstrap + registry servers)

src/validation/domain.ts

Input normalisation & validation

src/types/domain.ts

Clean result types

src/config.ts

Env-var configuration

src/utils/rateLimit.ts

In-memory per-client rate limiter

src/utils/errors.ts

AppError taxonomy

src/utils/logger.ts

Minimal structured logger (stderr, redacts sensitive fields)

src/utils/env.ts

Loads .env locally (no-op on Vercel)

tests/

Vitest unit tests (RDAP mocked)


The MCP tool

Name: check_domain_availability

Input schema — both fields required strings:

{ "name": "mybrand", "tld": "ai" }

Input

Behaviour

{ "name": " MyBrand ", "tld": ".AI" }

{ "name": "mybrand", "tld": "ai" }

{ "name": "mybrand.ai", "tld": "ai" }

{ "name": "mybrand", "tld": "ai" }

{ "name": "https://mybrand.ai", "tld": "ai" }

❌ rejected — "…not a URL"

{ "name": "hello world", "tld": "com" }

❌ rejected — "Invalid domain name."

any TLD (com, ai, io, co, dev, co.uk, …)

✅ generic validation, nothing hard-coded

Result:

Domain: mybrand.ai
Status: AVAILABLE
TLD Valid: Yes
Check Method: RDAP
Lookup Time: 583ms
{
  "domain": "mybrand.ai",
  "name": "mybrand",
  "tld": "ai",
  "available": true,
  "tldValid": true,
  "checkMethod": "rdap",
  "elapsed": "583ms"
}

Configuration

No credentials are required. Everything below is optional, via environment variables (.env locally, project settings on Vercel):

Variable

Required

Default

Notes

REQUEST_TIMEOUT_MS

10000

RDAP request timeout (clamped 1 000–60 000).

RATE_LIMIT_MAX

15

Tool calls per client per window. 0 disables.

RATE_LIMIT_WINDOW_MS

60000

Rate-limit window length.

LOG_LEVEL

info

debug | info | warn | error | silent

PORT

3000

Local HTTP dev server only.


Error handling

Every failure becomes a safe tool result with isError: true — never a stack trace, never a raw upstream body.

Situation

HTTP

Message

Invalid input

Invalid domain name. … / Invalid TLD. …

TLD not in the RDAP bootstrap registry

No RDAP server is registered for "…". …

Auth failure

401 / 403

The domain registry rejected the request.

Rate limited (upstream)

429

…is rate limiting requests. …

Rate limited (this server)

Rate limit reached for this client. Please wait Ns…

Upstream down

5xx

…is temporarily unavailable. …

Timeout

…request timed out. …

Malformed / unexpected body

…could not be parsed.


Security & abuse protection

  • ✅ No credentials anywhere — RDAP is a public, unauthenticated protocol, so there is nothing to leak, rotate, or bill

  • ✅ Input validated & normalised; full URLs and bad characters rejected

  • ✅ No user-controlled URLs — only the IANA bootstrap registry and the RDAP server it resolves for a given TLD are ever called (no SSRF surface)

  • ✅ Request timeout via AbortController (default 10 s, capped)

  • ✅ Per-client (per-IP) rate limiting on tool calls

  • ✅ Stateless transport — no session data persisted


Notes for hosting a public shared instance

If you deploy one instance and share the URL publicly (e.g. on Reddit) so strangers connect their Claude to it:

  • No shared quota or bill — RDAP has no per-account key, so there's nothing to run out of. The limiting factor is each registry's own (undocumented, generally generous) per-IP fair-use throttling on their RDAP server, not anything you provision.

  • Keep RATE_LIMIT_MAX sane (default 15/min/IP). It is per-serverless-instance, so it caps a single abuser but is not a strict global limit. For hard limits put Vercel Firewall or a KV-backed limiter in front.

  • There is no auth on the tool by design (so "anyone can use it"). If you want to restrict access, mcp-handler ships withMcpAuth — wrap the handler in src/server.ts.

  • The safest public model is still share the repo, not just the endpoint — point people at Run your own copy so no single instance takes all the traffic.


Tech stack

Node.js 20+ · TypeScript (strict) · @modelcontextprotocol/server v2 · mcp-handler v2 (Streamable HTTP) · zod v4 · native fetch · Vitest · Vercel.

Author

Sumit Kumar · GitHub · LinkedIn · sumitdbg255@gmail.com

If this saved you some time, a ⭐ on the repo is appreciated.

License

MIT

Available Tools

1 tool
check_domain_availabilityCheck domain availabilityA
Read-onlyIdempotent

Check whether a domain name is available for registration. Provide the name and TLD separately (e.g. name "mybrand", tld "ai"). Returns availability, whether the TLD is valid, and which lookup method (usually WHOIS) was used.

ParametersJSON Schema
NameRequiredDescriptionDefault
tldYesThe top-level domain, e.g. "ai", "com", "io". A leading dot (".ai") is accepted.
nameYesThe domain name without the TLD or a leading dot, e.g. "mybrand". Do not pass a full URL.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld, and non-destructive behavior. The description adds useful behavioral detail beyond that by naming the return fields (availability, TLD validity, lookup method) and noting WHOIS is typical. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences: the first states purpose, the second gives input guidance, the third describes the output. No filler or redundant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with two fully documented parameters, the description covers invocation and return values, and annotations cover side-effect safety. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents both `name` and `tld` with examples and constraints. The description's 'provide name and TLD separately' mostly reinforces the schema rather than adding new semantic meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Check whether a domain name is available for registration') and a clear resource. It also explains the input pattern, making the tool's purpose unambiguous even without sibling tools to differentiate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the usage context clear: use it to check domain availability for registration. There are no sibling tools to contrast with, so explicit exclusions aren't necessary. It could be more explicit about when not to use it, but the intent is obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev1.0.0
    • First observedcheck_domain_availability

TDQS

A4.4/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so an agent cannot confuse it with any other operation. The name and description clearly explain what it does and what inputs it expects.

Naming Consistency5/5

The single tool uses a clear verb_noun convention: check_domain_availability. With only one tool, there are no naming clashes or inconsistent patterns to create confusion.

Tool Count4/5

One tool is slightly under the typical 3-15 range, but for the server's narrow purpose of checking domain availability, it is a reasonable and focused surface. It could arguably include additional domain-related tools, but the count is not excessive or trivially mismatched.

Completeness5/5

For the stated purpose of checking whether a domain is available for registration, the tool covers the core operation fully: it validates the TLD, returns availability, and indicates the lookup method. There are no obvious dead ends within this narrow domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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.
    5 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
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to perform real-time domain name availability checks and validate domain syntax according to RFC standards. It supports both stdio and SSE transports to bridge the gap between AI models and domain registration services.
    1
    -