mcp-domain-purchaser
v0.1.0-draft.1770992906137
Published
MCP server for domain purchase across multiple registrars
Downloads
79
Maintainers
Readme
MCP Domain Purchaser
An MCP (Model Context Protocol) server for domain purchase operations across multiple registrars with a clean adapter-based architecture.
Features
- Multi-Registrar Support: Unified interface for multiple domain registrars (Porkbun, Namecheap, GoDaddy, Gandi)
- Adapter Pattern: Easy to add new registrars by implementing the
RegistrarAdapterinterface - IPv4-Safe Networking: Works reliably in Docker/WSL2 environments with IPv6 issues
- Type-Safe: Full TypeScript with Zod schemas for runtime validation
- MCP Standard: Implements the Model Context Protocol for AI assistant integration
Supported Registrars
| Registrar | Availability | Pricing | DNS | Balance | Sandbox | |-----------|--------------|---------|-----|---------|---------| | Porkbun | Yes | Yes | Yes | Yes | No | | name.com | Yes | Yes | Yes | No | Yes | | GoDaddy | Yes | Yes | Yes | No | Yes (OTE) | | Gandi | Yes | Yes | Yes | Yes | Yes | | Namecheap | Yes | Premium only* | Yes | Yes | Yes |
* Namecheap only returns pricing for premium domains via API. Standard domain pricing must be checked at namecheap.com.
name.com Setup
export NAME_USERNAME=your_namecom_username
export NAME_TOKEN=your_api_token
export NAME_USE_SANDBOX=true # Optional: use sandbox for testingGetting API Access:
- Log in to your name.com account
- Go to Account Settings -> API Settings
- Create an API token
- Important: Disable 2FA for API access (required by name.com)
Sandbox Environment:
- Uses
https://api.dev.name.com/v4endpoint - Username automatically gets
-testsuffix in sandbox mode - Same token works for both production and sandbox
Namecheap Setup
export NAMECHEAP_API_USER=your_api_username
export NAMECHEAP_API_KEY=your_api_key
export NAMECHEAP_USERNAME=your_username
export NAMECHEAP_CLIENT_IP=your_whitelisted_ip # REQUIRED!
export NAMECHEAP_USE_SANDBOX=true # Optional: use sandbox for testingImportant: Namecheap requires:
- API access enabled (requires $50 balance, 20+ domains, OR $50 spent in 2 years)
- Your IP address whitelisted in your Namecheap account
See Namecheap Adapter Documentation for detailed setup instructions.
Gandi Setup
export GANDI_PAT=your_personal_access_token
export GANDI_USE_SANDBOX=true # Optional: use sandbox for testingSee Gandi Adapter Documentation for detailed setup instructions.
Installation
npm install mcp-domain-purchaserAvailable Tools
The MCP server provides the following tools:
| Tool | Description |
|------|-------------|
| check_availability | Check domain availability across all configured registrars |
| compare_prices | Compare registration and renewal prices across registrars |
| get_balance | Get account balance from prepaid registrars |
| list_domains | List all domains owned across all registrars |
Usage
As an MCP Server
Add to your Claude Code MCP configuration:
{
"mcpServers": {
"domain-purchaser": {
"command": "npx",
"args": ["mcp-domain-purchaser"],
"env": {
"MAX_DOMAIN_PRICE": "50",
"CONFIRMATION_TIMEOUT_MINUTES": "5"
}
}
}
}Programmatic Usage
import {
DomainPurchaserServer,
BaseRegistrarAdapter,
type RegistrarCapabilities,
} from 'mcp-domain-purchaser';
// Create server with configuration
const server = new DomainPurchaserServer({
maxDomainPrice: 50,
confirmationTimeoutMinutes: 5,
auditLogPath: '~/.domain-purchaser/audit.log',
});
// Register your adapter(s)
// server.registerAdapter(new MyRegistrarAdapter(...));
// Start the server
await server.start();Creating a Custom Adapter
To add support for a new registrar, extend BaseRegistrarAdapter:
import {
BaseRegistrarAdapter,
type RegistrarCapabilities,
type AvailabilityResult,
type PricingResult,
type BalanceResult,
type DomainListResult,
type PendingTransaction,
type PurchaseResult,
type DnsRecord,
type DnsResult,
} from 'mcp-domain-purchaser';
export class MyRegistrarAdapter extends BaseRegistrarAdapter {
readonly name = 'myregistrar';
readonly priority = 1;
readonly capabilities: RegistrarCapabilities = {
supportsAvailability: true,
supportsPricing: true,
supportsBalance: true,
supportsListDomains: true,
supportsPurchase: true,
supportsDns: true,
hasSandbox: false,
};
private readonly apiKey: string;
constructor(apiKey: string, options?: { timeout?: number; debug?: boolean }) {
super(options);
this.apiKey = apiKey;
}
async checkAvailability(domain: string): Promise<AvailabilityResult> {
const validDomain = this.validateDomainInput(domain);
// Implement API call...
return {
domain: validDomain,
available: true,
status: 'available',
};
}
async getPricing(domain: string): Promise<PricingResult> {
// Implement...
}
async getBalance(): Promise<BalanceResult> {
// Implement...
}
async listDomains(): Promise<DomainListResult> {
// Implement...
}
async createPurchase(domain: string, years: number): Promise<PendingTransaction> {
// Implement...
}
async executePurchase(transactionId: string): Promise<PurchaseResult> {
// Implement...
}
async getDnsRecords(domain: string): Promise<DnsRecord[]> {
// Implement...
}
async setDnsRecords(domain: string, records: DnsRecord[]): Promise<DnsResult> {
// Implement...
}
isConfigured(): boolean {
return Boolean(this.apiKey);
}
async validateCredentials(): Promise<boolean> {
// Make a test API call to verify credentials
return true;
}
}Safety Controls
The domain purchaser includes comprehensive safety controls to protect users from accidental or unauthorized purchases.
Price Limits
Purchases over the configured maximum price (default $50) are automatically rejected:
import { SafetyService } from 'mcp-domain-purchaser';
const safety = new SafetyService();
const check = safety.checkPriceLimit(1500);
// check.allowed === false
// check.reason includes instructions to increase MAX_DOMAIN_PRICEPremium Domain Detection
Detects premium domains using multiple heuristics:
- Known premium TLDs (.ai, .io, .co, .dev, etc.)
- Short domain names (1-3 characters)
- Pure numeric domains
- High absolute price (>$100)
- Price significantly above TLD average
const result = safety.detectPremiumDomain('ai.io', 5000);
// result.isPremium === true
// result.confidence === 'high'
// result.reasons includes all detected premium indicatorsTwo-Step Confirmation
All purchases require explicit confirmation within a timeout period (default 5 minutes):
import { PendingTransactionService } from 'mcp-domain-purchaser';
const txnService = new PendingTransactionService();
// Step 1: Create pending transaction
const txn = txnService.createTransaction('example.com', 'Porkbun', 9.99);
// Step 2: Confirm within 5 minutes
const confirmed = txnService.confirmTransaction(txn.transactionId);
// Expired transactions are automatically rejectedAudit Logging
All operations are logged to a JSON Lines file for accountability:
import { AuditLogger } from 'mcp-domain-purchaser';
const audit = new AuditLogger();
await audit.logPurchaseInitiated('example.com', 'Porkbun', 9.99, 'txn_abc123');CRITICAL SECURITY: The audit logger NEVER logs API keys, secrets, or credentials. All sensitive data is automatically scrubbed before writing.
Environment Variables for Safety
| Variable | Description | Default |
|----------|-------------|---------|
| MAX_DOMAIN_PRICE | Maximum allowed domain price in USD | 50 |
| CONFIRMATION_TIMEOUT_MINUTES | Minutes before pending transactions expire | 5 |
| AUDIT_LOG_PATH | Path to audit log file | ~/.domain-purchaser/audit.log |
Architecture
mcp-domain-purchaser/
src/
index.ts # Entry point + exports
server.ts # DomainPurchaserServer class
adapters/
types.ts # RegistrarAdapter interface
base.ts # BaseRegistrarAdapter abstract class
gandi.ts # Gandi adapter (v5 API + LiveDNS)
godaddy.ts # GoDaddy adapter
namecheap.ts # Namecheap adapter (XML API)
namecom.ts # name.com adapter (v4 Core API)
porkbun.ts # Porkbun adapter
config/
limits.ts # Safety configuration loading
services/
safety.ts # SafetyService (price limits, premium detection)
pending-transactions.ts # PendingTransactionService (two-step confirmation)
audit.ts # AuditLogger (JSON Lines logging, credential scrubbing)
types/
domain.ts # Domain types + zod schemas
pricing.ts # Pricing types + zod schemas
transaction.ts # Transaction types + zod schemas
safety.ts # Safety types + zod schemas
utils/
fetch.ts # IPv4-safe fetch wrapper
validation.ts # Input validation utilities
xml.ts # XML parsing utilities (for Namecheap)
docs/
adapters/
gandi.md # Gandi adapter documentation
namecheap.md # Namecheap adapter documentationType Definitions
Domain Types
DomainStatus: 'available' | 'taken' | 'premium' | 'unknown' | 'error'AvailabilityResult: Result of domain availability checkOwnedDomain: Domain owned by the userDomainListResult: Result of listing owned domains
Pricing Types
PricingResult: Pricing information for a domainBalanceResult: Account balance from a registrarPriceComparison: Price comparison across registrars
Transaction Types
TransactionStatus: Status of a purchase transactionPendingTransaction: A pending purchase awaiting confirmationPurchaseResult: Result of an executed purchaseAuditLogEntry: Entry in the audit log
Environment Variables
General Configuration
| Variable | Description | Default |
|----------|-------------|---------|
| MAX_DOMAIN_PRICE | Maximum allowed domain price in USD | 50 |
| CONFIRMATION_TIMEOUT_MINUTES | Minutes before pending transactions expire | 5 |
| AUDIT_LOG_PATH | Path to audit log file | ~/.domain-purchaser/audit.log |
name.com
| Variable | Description | Required |
|----------|-------------|----------|
| NAME_USERNAME | name.com account username | Yes |
| NAME_TOKEN | API token from name.com account settings | Yes |
| NAME_USE_SANDBOX | Use sandbox environment (true/false) | No |
Sandbox Mode:
- When
NAME_USE_SANDBOX=true, requests go toapi.dev.name.com - Username is automatically suffixed with
-testfor sandbox auth - Allows safe testing without real charges
Gandi
| Variable | Description | Required |
|----------|-------------|----------|
| GANDI_PAT | Personal Access Token | Yes |
| GANDI_USE_SANDBOX | Use sandbox environment | No |
| GANDI_SHARING_ID | Organization sharing ID | No |
Namecheap
| Variable | Description | Required |
|----------|-------------|----------|
| NAMECHEAP_API_USER | API username (usually same as account username) | Yes |
| NAMECHEAP_API_KEY | API key from Namecheap account | Yes |
| NAMECHEAP_USERNAME | Namecheap account username | Yes |
| NAMECHEAP_CLIENT_IP | Whitelisted IP address for API access | Yes |
| NAMECHEAP_USE_SANDBOX | Use sandbox environment for testing | No |
IPv4 Networking
This package includes an IPv4-safe fetch wrapper to handle networking issues common in Docker and WSL2 environments where IPv6 connections fail or timeout. The wrapper uses undici with explicit IPv4 configuration.
import { fetchIPv4, fetch } from 'mcp-domain-purchaser';
// Use just like native fetch, but with guaranteed IPv4
const response = await fetchIPv4('https://api.example.com/data');License
MIT
