Features: - Domain management (check, register, renew, contacts) - DNS management (nameservers, records) - Glue records (child nameserver) support - TLD price tracking with KRW conversion - FastAPI REST server with OpenAI schema - MCP server for Claude integration Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
271 lines
6.4 KiB
Python
271 lines
6.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Namecheap MCP Server
|
|
"""
|
|
|
|
import os
|
|
from dotenv import load_dotenv
|
|
from mcp.server.fastmcp import FastMCP
|
|
|
|
from namecheap import NamecheapAPI, NamecheapConfig, RegistrantInfo
|
|
|
|
load_dotenv()
|
|
|
|
# Initialize MCP server
|
|
mcp = FastMCP("namecheap")
|
|
|
|
# Initialize Namecheap API
|
|
config = NamecheapConfig(
|
|
api_user=os.getenv("NAMECHEAP_API_USER", ""),
|
|
api_key=os.getenv("NAMECHEAP_API_KEY", ""),
|
|
username=os.getenv("NAMECHEAP_USERNAME", ""),
|
|
client_ip=os.getenv("NAMECHEAP_CLIENT_IP", ""),
|
|
sandbox=os.getenv("NAMECHEAP_SANDBOX", "false").lower() == "true",
|
|
)
|
|
api = NamecheapAPI(config)
|
|
|
|
|
|
# ===== Domain Tools =====
|
|
|
|
@mcp.tool()
|
|
def domains_check(domains: str) -> dict:
|
|
"""
|
|
Check domain availability.
|
|
|
|
Args:
|
|
domains: Comma-separated domain names (e.g., "example.com,example.net")
|
|
"""
|
|
domain_list = [d.strip() for d in domains.split(",")]
|
|
return api.domains_check(domain_list)
|
|
|
|
|
|
@mcp.tool()
|
|
def domains_list(page: int = 1, page_size: int = 20) -> list[dict]:
|
|
"""
|
|
Get list of domains in account.
|
|
|
|
Args:
|
|
page: Page number (default: 1)
|
|
page_size: Number of domains per page (default: 20)
|
|
"""
|
|
return api.domains_get_list(page=page, page_size=page_size)
|
|
|
|
|
|
@mcp.tool()
|
|
def domains_info(domain: str) -> dict:
|
|
"""
|
|
Get detailed info about a domain.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
"""
|
|
return api.domains_get_info(domain)
|
|
|
|
|
|
@mcp.tool()
|
|
def domains_renew(domain: str, years: int = 1) -> dict:
|
|
"""
|
|
Renew a domain. WARNING: This will charge your account.
|
|
|
|
Args:
|
|
domain: Domain name to renew
|
|
years: Number of years (1-10)
|
|
"""
|
|
return api.domains_renew(domain, years=years)
|
|
|
|
|
|
@mcp.tool()
|
|
def domains_get_contacts(domain: str) -> dict:
|
|
"""
|
|
Get domain contact information.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
"""
|
|
return api.domains_get_contacts(domain)
|
|
|
|
|
|
# ===== DNS Tools =====
|
|
|
|
@mcp.tool()
|
|
def dns_get_nameservers(domain: str) -> dict:
|
|
"""
|
|
Get nameserver information for a domain.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com" or "sub.it.com")
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
return api.dns_get_list(sld, tld)
|
|
|
|
|
|
@mcp.tool()
|
|
def dns_set_nameservers(domain: str, nameservers: str) -> dict:
|
|
"""
|
|
Set custom nameservers for a domain.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
nameservers: Comma-separated nameservers (e.g., "ns1.cloudflare.com,ns2.cloudflare.com")
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
ns_list = [ns.strip() for ns in nameservers.split(",")]
|
|
success = api.dns_set_custom(sld, tld, ns_list)
|
|
|
|
return {"success": success, "domain": domain, "nameservers": ns_list}
|
|
|
|
|
|
@mcp.tool()
|
|
def dns_set_default(domain: str) -> dict:
|
|
"""
|
|
Set default Namecheap nameservers for a domain.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
success = api.dns_set_default(sld, tld)
|
|
|
|
return {"success": success, "domain": domain}
|
|
|
|
|
|
@mcp.tool()
|
|
def dns_get_records(domain: str) -> list[dict]:
|
|
"""
|
|
Get DNS records for a domain. Only works if using Namecheap DNS.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return [{"error": "Invalid domain format"}]
|
|
|
|
return api.dns_get_hosts(sld, tld)
|
|
|
|
|
|
# ===== Glue Record (Child Nameserver) Tools =====
|
|
|
|
@mcp.tool()
|
|
def glue_create(domain: str, nameserver: str, ip: str) -> dict:
|
|
"""
|
|
Create a glue record (child nameserver) for a domain.
|
|
Use this when you want to use your own domain as a nameserver (e.g., ns1.example.com for example.com).
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
nameserver: Full nameserver hostname (e.g., "ns1.example.com")
|
|
ip: IP address for the nameserver
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
return api.ns_create(sld, tld, nameserver, ip)
|
|
|
|
|
|
@mcp.tool()
|
|
def glue_get(domain: str, nameserver: str) -> dict:
|
|
"""
|
|
Get info about a glue record (child nameserver).
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
nameserver: Full nameserver hostname (e.g., "ns1.example.com")
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
return api.ns_get_info(sld, tld, nameserver)
|
|
|
|
|
|
@mcp.tool()
|
|
def glue_update(domain: str, nameserver: str, old_ip: str, ip: str) -> dict:
|
|
"""
|
|
Update a glue record (child nameserver) IP address.
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
nameserver: Full nameserver hostname (e.g., "ns1.example.com")
|
|
old_ip: Current IP address
|
|
ip: New IP address
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
return api.ns_update(sld, tld, nameserver, old_ip, ip)
|
|
|
|
|
|
@mcp.tool()
|
|
def glue_delete(domain: str, nameserver: str) -> dict:
|
|
"""
|
|
Delete a glue record (child nameserver).
|
|
|
|
Args:
|
|
domain: Domain name (e.g., "example.com")
|
|
nameserver: Full nameserver hostname to delete (e.g., "ns1.example.com")
|
|
"""
|
|
parts = domain.rsplit(".", 1)
|
|
if len(parts) == 2:
|
|
sld, tld = parts
|
|
else:
|
|
return {"error": "Invalid domain format"}
|
|
|
|
return api.ns_delete(sld, tld, nameserver)
|
|
|
|
|
|
# ===== Account Tools =====
|
|
|
|
@mcp.tool()
|
|
def account_balance() -> dict:
|
|
"""Get account balance."""
|
|
return api.users_get_balances()
|
|
|
|
|
|
@mcp.tool()
|
|
def price_check(tld: str) -> dict:
|
|
"""
|
|
Get registration price for a TLD.
|
|
|
|
Args:
|
|
tld: TLD to check (e.g., "com", "net", "io")
|
|
"""
|
|
from db import get_prices, init_db
|
|
init_db()
|
|
|
|
prices = get_prices()
|
|
for p in prices:
|
|
if p["tld"] == tld:
|
|
return {"tld": tld, "usd": p["usd"], "krw": p["krw"]}
|
|
|
|
return {"error": f"TLD '{tld}' not found"}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
mcp.run()
|