Почему проверка доменов через ИИ — это не просто "ещё один скрипт"
Представьте ситуацию: вы придумали гениальное название для стартапа. Или для нового продукта. Или для блога. Вы открываете браузер, заходите на регистратора, вбиваете название... и получаете разочарование. Домен занят. Вы пробуете варианты с дефисами, с разными зонами, с префиксами — всё занято. Через час вы уже ненавидите весь интернет.
Теперь представьте другой сценарий. Вы говорите Cursor: "Придумай 10 вариантов названий для SaaS-сервиса аналитики на основе AI, проверь доступность доменов в .com, .ai и .dev". И через 30 секунд получаете таблицу со свободными вариантами, ценами и даже рекомендациями по выбору.
Разница как между копанием лопатой и экскаватором. И этот экскаватор — MCP-сервер для проверки доменов.
MCP (Model Context Protocol) на 2026 год — это не просто "ещё один протокол". Это стандарт де-факто для подключения внешних инструментов к AI-ассистентам. Если в 2024-2025 это была экспериментальная фича, то сейчас это must-have для любого серьёзного разработчика.
Что ломается в типичных решениях (и как мы это починим)
Большинство скриптов для проверки доменов страдают от трёх болезней:
- Хрупкость парсинга: WHOIS-ответы меняются чаще, чем погода. Регистраторы постоянно обновляют форматы, добавляют капчи, меняют структуру.
- Ограниченность масштабирования: 10 запросов в минуту — и вас блокируют. Нужны прокси, задержки, ротация.
- Нулевая интеграция с рабочим процессом: Отдельное окно терминала, отдельный скрипт, отдельный файл с результатами. Контекст теряется.
MCP-сервер решает все три проблемы. Он живёт внутри Cursor (или Claude Desktop), становится частью диалога с ИИ, использует профессиональные API вместо парсинга, а масштабирование встроено в архитектуру.
Архитектура: что внутри нашего MCP-сервера
Не будем делать "просто обёртку над whois". Наш сервер будет умным:
| Компонент | Зачем нужен | Альтернатива "в лоб" |
|---|---|---|
| WHOIS API (не парсинг!) | Стабильность, скорость, легальность | python-whois с регулярками (хрупко) |
| Кэширование Redis | Не дудосить API, экономия денег | Запрос каждый раз (дорого и медленно) |
| Генератор вариантов | Автоматический подбор по шаблонам | Ручной перебор (скучно) |
| Метрики TLD | .com vs .io vs .ai — что лучше? | "Берём что первое свободно" (неоптимально) |
1 Выбираем WHOIS API (спойлер: не whois)
Первый и самый важный выбор. На 2026 год python-whois библиотека — это музейный экспонат. Она ломается на каждом втором запросе. Вместо этого используем профессиональные API:
# НЕ ТАК (2024 год):
import whois
try:
w = whois.whois('example.com') # Устарело, нестабильно
print(w.domain_name)
except:
print('Ошибка парсинга')
# ТАК (2026 год):
import httpx
from datetime import datetime
class DomainChecker:
def __init__(self, api_key: str):
# Используем WHOIS XML API или аналоги
self.base_url = "https://api.whoisxmlapi.com/v1"
self.api_key = api_key
self.client = httpx.AsyncClient(timeout=30.0)
async def check_domain(self, domain: str) -> dict:
"""Проверяем домен через стабильный API"""
params = {
'domainName': domain,
'apiKey': self.api_key,
'outputFormat': 'JSON',
'da': 2 # Подробный вывод
}
try:
response = await self.client.get(
f"{self.base_url}/whois",
params=params
)
response.raise_for_status()
return response.json()
except httpx.HTTPStatusError as e:
# Логируем, но не падаем
return {
'domain': domain,
'available': False,
'error': f'HTTP error: {e.response.status_code}'
}
2 Проектируем инструменты MCP (не просто check_domain)
Глупая ошибка — сделать один инструмент check_domain. Умный подход — разделить функциональность:
# mcp_domain_tools.py
from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationOptions
import mcp.server.stdio
import asyncio
from typing import List
import json
class DomainMCPServer:
def __init__(self):
self.server = Server("domain-checker")
# Регистрируем инструменты
self.server.list_tools().add(self.list_available_tools)
# Основные инструменты
self.server.tool(
name="check_domain_availability",
description="Проверяет доступность домена в различных зонах",
inputSchema={
"type": "object",
"properties": {
"domain": {"type": "string", "description": "Домен без TLD (например: google)"},
"tlds": {
"type": "array",
"items": {"type": "string"},
"default": [".com", ".io", ".dev", ".ai", ".app"],
"description": "Список TLD для проверки"
}
},
"required": ["domain"]
}
)(self.check_domain_handler)
# Генератор вариантов
self.server.tool(
name="generate_domain_variants",
description="Генерирует варианты доменов на основе ключевых слов",
inputSchema={
"type": "object",
"properties": {
"keywords": {
"type": "array",
"items": {"type": "string"},
"description": "Ключевые слова (например: [\"ai\", \"analytics\"])"
},
"strategy": {
"type": "string",
"enum": ["combine", "prefix", "suffix", "all"],
"default": "combine",
"description": "Стратегия генерации"
}
},
"required": ["keywords"]
}
)(self.generate_variants_handler)
# Массовая проверка
self.server.tool(
name="bulk_domain_check",
description="Массовая проверка списка доменов",
inputSchema={
"type": "object",
"properties": {
"domains": {
"type": "array",
"items": {"type": "string"},
"description": "Список доменов для проверки"
},
"concurrency": {
"type": "integer",
"default": 5,
"description": "Количество одновременных запросов"
}
},
"required": ["domains"]
}
)(self.bulk_check_handler)
async def check_domain_handler(self, domain: str, tlds: List[str]) -> dict:
"""Обработчик проверки домена"""
results = []
for tld in tlds:
full_domain = f"{domain}{tld}"
status = await self.check_single_domain(full_domain)
results.append({
"domain": full_domain,
"available": status["available"],
"price": status.get("price"),
"tld": tld
})
return {
"content": [{
"type": "text",
"text": json.dumps(results, indent=2, ensure_ascii=False)
}]
}
async def generate_variants_handler(self, keywords: List[str], strategy: str = "combine") -> dict:
"""Генератор вариантов доменов"""
variants = []
if strategy == "combine" and len(keywords) >= 2:
# Комбинации: ai + analytics = aianalytics, analyticsai
variants.append(f"{keywords[0]}{keywords[1]}")
variants.append(f"{keywords[1]}{keywords[0]}")
if strategy == "prefix":
# Добавляем префиксы: get, try, use, my
prefixes = ["get", "try", "use", "my", "the", "go"]
for prefix in prefixes:
for keyword in keywords:
variants.append(f"{prefix}{keyword}")
# И так далее...
return {
"content": [{
"type": "text",
"text": json.dumps({"variants": variants}, indent=2)
}]
}
3 Конфигурация mcp.json для Cursor (2026 edition)
Cursor на 2026 год использует MCP версии 1.1+ с улучшенной системой конфигурации. Старые гайды уже не работают:
{
"mcpServers": {
"domain-checker": {
"command": "uv",
"args": [
"run",
"--with", "mcp[cli]>=1.2.0",
"--with", "httpx>=0.28.0",
"--with", "redis>=5.2.0",
"python",
"-m",
"mcp_domain_tools"
],
"env": {
"WHOIS_API_KEY": "your_api_key_here",
"REDIS_URL": "redis://localhost:6379/0",
"RATE_LIMIT_PER_MINUTE": "60"
},
"disabled": false,
"autoApprove": [
"check_domain_availability",
"generate_domain_variants"
],
"alwaysConfirm": [
"bulk_domain_check"
]
}
}
}
Важное изменение 2026 года: Cursor теперь требует явного указания версий Python-пакетов через uv. Старый способ с "python -m" без uv может не работать в новых версиях.
4 Интеграция с кэшированием (без этого сожжёте все лимиты)
Каждый запрос к WHOIS API стоит денег. Кэширование — не опция, а необходимость:
import redis.asyncio as redis
from datetime import timedelta
import pickle
class DomainCache:
def __init__(self, redis_url: str = "redis://localhost:6379/0"):
self.redis = redis.from_url(redis_url, decode_responses=False)
self.ttl = timedelta(hours=24) # WHOIS данные меняются редко
async def get_domain_status(self, domain: str) -> dict | None:
"""Получаем из кэша"""
try:
cached = await self.redis.get(f"domain:{domain}")
if cached:
return pickle.loads(cached)
except Exception as e:
print(f"Cache error: {e}")
return None
async def set_domain_status(self, domain: str, status: dict):
"""Сохраняем в кэш"""
try:
await self.redis.setex(
f"domain:{domain}",
self.ttl,
pickle.dumps(status)
)
except Exception as e:
print(f"Cache set error: {e}")
async def bulk_cache(self, domains: List[str], results: List[dict]):
"""Массовое кэширование"""
pipe = self.redis.pipeline()
for domain, result in zip(domains, results):
pipe.setex(
f"domain:{domain}",
self.ttl,
pickle.dumps(result)
)
await pipe.execute()
Рабочий процесс: как это выглядит в Cursor
После настройки вы получаете совершенно новый опыт:
Вы: Придумай названия для сервиса AI-транскрипции, проверь домены в .com, .ai и .app
Cursor (используя MCP-сервер):
Генерирую варианты...
Проверяю доступность доменов:
| Домен | Доступен | Цена (примерно) | Рекомендация |
|-------|----------|-----------------|--------------|
| whisperai.com | ❌ Занят | - | Избегать, конкурент |
| transcribe.ai | ❌ Занят | - | Дорогой на вторичном рынке |
| audioscribe.app | ✅ Свободен | $20/год | Хороший вариант |
| speakflow.com | ✅ Свободен | $12/год | Лучший по цене |
| aivoicetext.com | ✅ Свободен | $10/год | Дешёвый, но длинный |
Рекомендую speakflow.com — короткий, запоминающийся, .com зона.
Хотите проверить ещё варианты с префиксами (get, try, use)?
Ошибки, которые сломают ваш сервер (и как их избежать)
| Ошибка | Почему происходит | Как исправить |
|---|---|---|
| "Tool execution failed: timeout" | WHOIS API отвечает медленно, нет таймаутов | Добавить timeout=10 в httpx, использовать async |
| "API key invalid or expired" | Ключ в .env, но Cursor не видит переменные | Указывать env прямо в mcp.json |
| "Too many requests" | Нет rate limiting, API блокирует | Добавить asyncio.Semaphore(5) для ограничения |
| Cursor не видит инструменты | Неправильная версия MCP протокола | Использовать mcp>=1.2.0, перезапустить Cursor |
Продвинутые фичи: куда расти дальше
Базовый сервер работает? Отлично. Теперь делаем его профессиональным:
- Интеграция с регистраторами: Не просто проверка, а автоматическая регистрация через API Namecheap/GoDaddy.
- Анализ истории домена
WHOIS-история: был ли домен в спам-рассылках? Подключить SecurityTrails API Оценка стоимости Сколько стоит домен на вторичном рынке? Интеграция с Estibot или аналоги Мониторинг истёкших доменов Отслеживание, когда занятый домен освободится Планировщик задач + уведомления FAQ: вопросы, которые вы зададите через неделю
Вопрос: MCP-сервер работает в Cursor, но не в Claude Desktop. Почему?
Ответ: Cursor и Claude Desktop используют разные версии MCP протокола на 2026 год. Cursor обычно на версии впереди. Решение — указать минимальную совместимую версию в pyproject.toml:
mcp>=1.1.0, <2.0.0.Вопрос: API WHOIS стоит денег. Есть бесплатные альтернативы?
Ответ: Есть, но они ограничены 10-50 запросами в день и медленные. Для профессионального использования — только платные API. Альтернатива — кэшировать агрессивно и проверять только новые варианты.
Вопрос: Можно ли использовать этот сервер для мониторинга доменов конкурентов?
Ответ: Технически — да. Этически — спорно. Юридически — проверьте условия WHOIS API. Многие запрещают массовый мониторинг. Используйте разумно.
Что дальше? Интеграция с другими MCP-серверами
Наш доменный сервер не существует в вакууме. Представьте цепочку:
- Kindly ищет в интернете тренды ниш
- Наш сервер проверяет доступность доменов для этих ниш
- MCP-сервер для комплаенса проверяет юридические аспекты названий
- ИИ выбирает лучший вариант и регистрирует его
Это и есть сила MCP в 2026 году — не отдельные инструменты, а экосистема. Если вы ещё не используете MCP Doctor для отладки конфигов — начните с него. Потом добавьте PlexMCP для подключения локальных моделей.
Последний совет: не пытайтесь сделать "идеальный" сервер с первого раза. Сделайте минимальную рабочую версию, подключите к Cursor, проверьте 5-10 доменов. Увидите, как это меняет workflow. Потом уже добавляйте кэширование, генерацию вариантов, интеграции.
Через месяц вы будете удивляться: "Как я раньше жил без этого?"