check_domains
Check Domain Availability
Use this when the user wants to know whether one or more domains are available to register. Returns confidence, source, cache age, and ambiguous results when the lookup cannot be determined safely.
domains必填
io.github.einiba由 GitHub 帳號 einiba 發布v1.1.1更新於 Oct 24, 2026
Confidence-scored domain availability checking for AI agents via CanYouGrab.it
透過 CanYouGrab.it API 檢查網域是否可註冊並附上信心分數,同時回傳 WHOIS 註冊資訊與方案用量。
Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.einiba%2Fcanyougrab/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。把它新增到你客戶端的 mcpServers 設定中。
{
"mcpServers": {
"canyougrab-it": {
"type": "http",
"url": "https://api.canyougrab.it/mcp"
}
}
}Domain availability lookup API with subscription billing, built on FastAPI + DNS (Unbound resolver).
Live services:
https://api.canyougrab.ithttps://portal.canyougrab.ithttps://auth.canyougrab.it (Auth0 custom domain)Authorization: Bearer cyg_...)Authorization: Bearer cyg_<token>api_keys table (plaintext never stored)cyg_XXXXXXXX...) is stored for display in the portalrevoked_at timestamp, not physically deleted)dev-mqe5tavp6dr62e7uauth.canyougrab.ithttps://api.canyougrab.itDomain availability is checked by querying a dedicated Unbound recursive DNS resolver running on a separate DigitalOcean droplet. The worker sends NS record queries over the VPC private network and interprets the response:
The Unbound resolver caches aggressively (7 days for registered domains, 5 minutes for NXDOMAIN) and queries TLD authoritative servers directly, avoiding public resolver rate limits.
PostgreSQL is used for authentication, usage tracking, and billing — not for domain lookups.
Trigger: Push a git tag matching v* (e.g., v1.0.5)
Pipeline (.github/workflows/deploy.yml):
v* tag pushDEPLOY_HOST secret) using DEPLOY_SSH_KEYgit fetch + git checkout <tag>)/opt/canyougrab-repo/scripts/deploy-host.shTrigger: Push to the dev branch
Pipeline (.github/workflows/deploy-dev.yml):
devDEV_DEPLOY_HOST secret) using same DEPLOY_SSH_KEYdev ref on the server (git fetch + git checkout dev)/opt/canyougrab-repo/scripts/deploy-host.shBoth pipelines use a small inline SSH bootstrap to update /opt/canyougrab-repo to the target ref, then call scripts/deploy-host.sh from that checked-out revision. The repo-managed deploy script handles:
pip install -r requirements.txt for backend dependenciesrsync of backend, portal, and MCP source trees into their runtime directoriesmcp-server package/runtime when the host also runs canyougrab-mcp.serviceIf /mcp is served by the same host as the API, backend-only deploys are not enough. The MCP service must be updated and restarted during the same deploy or the OAuth metadata and live MCP behavior can drift apart.
An existing /opt/deploy.sh can still be kept as a manual compatibility shim if desired, but the automated pipeline should treat the repo copy of scripts/deploy-host.sh as the source of truth.
Requires DNS_RESOLVER_HOST pointing to an Unbound instance (or use 8.8.8.8 for basic testing), plus PostgreSQL and Valkey/Redis (local or tunneled to managed instances).
Or use the configured launch server:
Portal dev server hardcodes API_BASE to https://api.canyougrab.it in portal/docs/src/config.ts. To develop against a local backend, change this to http://localhost:8000.
Because canyougrab.it uses a .it country-code TLD (Italy), all user-facing HTML (portal, docs) must include signals that the content targets English speakers:
<html lang="en"> on every page.<head>:
<link rel="canonical" href="{page_url}" />.This applies to the portal (portal.canyougrab.it), API docs, and any other publicly rendered HTML.
available: null instead of a potentially dangerous false positive. Consumers should treat null as "could not determine."auth0_sub metadata on the Stripe customer object, avoiding a separate mapping table.usage_log_daily) and per-minute (usage_log_minute) usage are recorded for monthly quota and per-minute rate limiting respectively.3abef70). The Zuplo portal/docs framework is still used for the developer portal./mcp is hosted on this server): Serves remote MCP clientsInstall the monitoring stack with: sudo bash scripts/setup-monitoring.sh
All active services on the host must be managed via systemd and restarted during deployments.
All automated deploys should route through scripts/deploy-host.sh, which is responsible for restarting whichever of these services are installed on the host.
來源:README.md,提交 07a9ea8
Check Domain Availability
Use this when the user wants to know whether one or more domains are available to register. Returns confidence, source, cache age, and ambiguous results when the lookup cannot be determined safely.
domains必填Check API Usage
Use this when the user wants to see their CanYouGrab.it plan, usage, and remaining quota for the current billing period.
無需輸入參數。
Domain Information Lookup
Use this when the user wants WHOIS or registration information about a specific domain — such as who owns it, when it was registered, when it expires, or what nameservers it uses.
domain必填已滿足適用檢查項的 100%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
┌──────────────────────────────────────────────────────────────────┐│ Developer Portal ││ (Zudoku/React on portal.canyougrab.it) ││ Usage Dashboard · API Keys · Pricing · API Reference (OAS) │└──────────────────┬───────────────────────────────────────────────┘ │ Auth0 JWT (portal) / Bearer API key (API) ▼┌──────────────────────────────────────────────────────────────────┐│ FastAPI Backend (v5.0.0) ││ api.canyougrab.it:8000 ││ ││ ┌─────────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ ││ │ app.py │ │ keys.py │ │billing.py│ │ auth.py │ ││ │ /check/bulk │ │ /keys │ │/billing │ │ API key + │ ││ │ /usage │ │ CRUD │ │/stripe │ │ JWT auth │ ││ │ │ │ rotate │ │ webhook │ │ │ ││ └──────┬──────┘ └──────────┘ └────┬─────┘ └─────────────┘ ││ │ │ │└─────────┼────────────────────────────┼───────────────────────────┘ │ │ ▼ ▼┌─────────────────┐ ┌─────────────────┐│ Valkey (Redis) │ │ Stripe API ││ Job queue + │ │ Subscriptions ││ Rate limiting │ │ Webhooks │└────────┬────────┘ └─────────────────┘ │ ▼┌─────────────────┐ ┌──────────────────────────────┐│ RQ Worker │──DNS──▶ │ Unbound Resolver ││ (worker.py) │ │ (dedicated droplet) ││ ThreadPool(10) │ │ NS queries via VPC ││ via RQ queue │ └──────────────────────────────┘└─────────────────┘ ┌──────────────────────────────┐ ───────────────────▶│ PostgreSQL │ (auth, usage, │ API keys + Usage logs │ billing only) └──────────────────────────────┘zuplo/├── backend/ # Python FastAPI backend│ ├── app.py # Main API: /check/bulk, /usage, /health│ ├── auth.py # API key auth (SHA-256) + Auth0 JWT auth (RS256)│ ├── billing.py # Stripe checkout, portal, webhooks, card-on-file, usage details│ ├── keys.py # API key CRUD: create, list, rotate, revoke (+ Turnstile)│ ├── antifraud.py # Anti-fraud: Turnstile, device fingerprints, risk scoring│ ├── email_utils.py # Email normalization + disposable email detection│ ├── dns_client.py # DNS-based domain availability checking via Unbound│ ├── queries.py # PostgreSQL queries: usage tracking, auth, billing│ ├── valkey_client.py # Redis/Valkey job queue client (RQ-backed)│ ├── rq_tasks.py # RQ task function: process_domain_job()│ ├── worker.py # RQ worker process (ThreadPoolExecutor per job)│ ├── migrations/ # SQL migrations│ │ └── 001_free_tier_antifraud.sql│ └── requirements.txt # Python dependencies├── portal/ # Developer portal (Zuplo + Zudoku)│ ├── config/│ │ ├── routes.oas.json # OpenAPI 3.1 spec (public API documentation)│ │ └── policies.json # Zuplo policies (empty — all routing is direct)│ ├── docs/ # Zudoku documentation portal│ │ ├── src/│ │ │ ├── config.ts # API_BASE, Turnstile site key, Stripe PK│ │ │ ├── UsageDashboard.tsx # Usage + billing dashboard component│ │ │ ├── PricingPage.tsx # Plan selection + Stripe checkout│ │ │ ├── PricingPlans.tsx # Pricing card grid component│ │ │ └── CardSetupPage.tsx # Stripe Elements card-on-file for Free+│ │ ├── public/ # Static assets (logos, banners, CSS overrides)│ │ ├── zudoku.config.tsx # Portal config: theme, nav, Auth0, API key mgmt│ │ └── package.json # Frontend dependencies (React 19, Zudoku)│ ├── package.json # Workspace root (Zuplo v6, TypeScript v5)│ └── README.md # Zuplo boilerplate (not project-specific)├── mcp-server/ # MCP package for ChatGPT, Claude, and remote MCP clients│ ├── pyproject.toml # MCP package metadata + version│ ├── server.json # MCP registry/server metadata│ ├── uv.lock # Locked MCP runtime dependencies│ └── src/canyougrab_mcp/│ ├── __init__.py│ └── server.py # stdio + streamable-http MCP entrypoint├── .github/workflows/│ ├── deploy.yml # Production deploy (on tag push v*)│ └── deploy-dev.yml # Dev deploy (on push to dev branch)├── .claude/│ └── launch.json # Local dev server config (port 9200)└── package.json # Root workspace configClient FastAPI Valkey Worker Unbound │ │ │ │ │ │ POST /api/check/bulk │ │ │ │ │ { domains: [...] } │ │ │ │ │─────────────────────────▶│ │ │ │ │ │── validate key ──────────│ │ │ │ │── check minute rate ────▶│ INCR ratelimit:id:min │ │ │ │── check monthly quota ──▶│ (PostgreSQL) │ │ │ │── record usage ─────────▶│ (PostgreSQL) │ │ │ │── create_job() ─────────▶│ HSET job:{uuid} │ │ │ │ │ RQ enqueue (with retry) │ │ │ │ │ │ │ │ │ │◀── RQ Worker dequeues ───│ │ │ │ │ │ │ │ │ │──── claim_job() ────────▶│ │ │ │ │ │── ThreadPool(10) │ │ │ │ │── check_domain_dns() │ │ │ │── NS query ───────▶│ │ │ │ │◀── NOERROR/NXDOMAIN│ │ │ │◀── complete_job() ───────│ │ │ │ │ │ │ │ │◀─ poll get_job_status() ─│ │ │ │ │ (0.3s interval, 30s │ │ │ │ │ max timeout) │ │ │ │◀─────────────────────────│ │ │ │ │ { results: [...] } │ │ │ │User → Pricing Page → Select Plan → Auth0 login → POST /api/billing/checkout (JWT auth) → Find/create Stripe customer (linked by auth0_sub metadata) → Stripe Checkout Session created → redirect to Stripe → User pays → Stripe fires webhook → POST /api/stripe/webhook (HMAC-SHA256 verified) → checkout.session.completed → fetch subscription → get price ID → Map price to plan → UPDATE api_keys SET plan, lookups_limitgit tag v1.0.5 && git push origin v1.0.5git push origin dev# DNS Resolver (Unbound on dedicated droplet)DNS_RESOLVER_HOSTNAME=unbound.canyougrab.internal # VPC internal hostname (resolved via socket.gethostbyname)DNS_RESOLVER_PORT=53DNS_QUERY_TIMEOUT=5.0 # Per-query timeout in seconds
# PostgreSQL (DigitalOcean Managed Database — auth, usage, billing only)POSTGRES_HOST= # DB cluster hostnamePOSTGRES_PORT=5432POSTGRES_DB=canyougrabPOSTGRES_USER=canyougrabPOSTGRES_PASSWORD= # DB passwordPOSTGRES_SSLMODE=require
# Valkey / Redis (DigitalOcean Managed Database)VALKEY_HOST= # Valkey cluster hostnameVALKEY_PORT=25061VALKEY_USERNAME=defaultVALKEY_PASSWORD= # Valkey password
# Auth0AUTH0_DOMAIN=dev-mqe5tavp6dr62e7u.us.auth0.comAUTH0_AUDIENCE=https://api.canyougrab.it
# StripeSTRIPE_SECRET_KEY= # sk_live_... (prod) or sk_test_... (dev)STRIPE_WEBHOOK_SECRET= # whsec_... (per-environment)STRIPE_PRICE_BASIC= # price_... (live price ID for Basic plan)STRIPE_PRICE_PRO= # price_... (live price ID for Pro plan)STRIPE_PRICE_BUSINESS= # price_... (live price ID for Business plan)
# Cloudflare Turnstile (bot prevention on key creation)TURNSTILE_SECRET_KEY= # 0x4AAAA... (from Cloudflare dashboard)
# PortalPORTAL_URL=https://portal.canyougrab.it
# WorkerBATCH_CONCURRENCY=10 # Thread pool size for domain checksVALKEY_QUEUE_NAME=canyougrab-jobs # RQ queue name (default: canyougrab-jobs)
# Monitoring (optional — only if monitoring stack is installed)SLACK_ALERTS_WEBHOOK_URL= # Slack incoming webhook for AlertmanagerRQ_METRICS_PORT=9122 # Prometheus metrics exporter port
# Auto-scaler (optional — only on API host with autoscaler enabled)DO_API_TOKEN= # DigitalOcean API tokenDO_WORKER_SNAPSHOT_ID= # Snapshot ID for new worker dropletsAUTOSCALER_MIN_WORKERS=1AUTOSCALER_MAX_WORKERS=5AUTOSCALER_SCALE_UP_THRESHOLD=50AUTOSCALER_SCALE_DOWN_IDLE_MINUTES=10cd backendpip install -r requirements.txt
# Start API serveruvicorn app:app --reload --port 8000
# Start worker (separate terminal)python worker.pycd portal/docsnpm installnpm run dev # Starts Zudoku dev server (via zuplo)# From repo rootnpx zuplo dev # Starts on port 9200<link rel="alternate" hreflang="en-US" href="{page_url}" /><link rel="alternate" hreflang="en" href="{page_url}" /><link rel="alternate" hreflang="x-default" href="{page_url}" />