Skip to main content
Glama
3viky

MCP Domain Checker Price

by 3viky
README.md
# MCP Domain Checker Price

**Model Context Protocol server for domain pricing and affiliate purchase links from Joker.com**

This MCP server provides domain registration pricing via the official [Joker.com DMAPI](https://dmapi.joker.com) and generates affiliate purchase links with automatic browser integration.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://github.com/3viky/mcp-domain-checker-price)

## Features

- ⚔ **Two-Tier Pricing System** - Static JSON (default, zero-config) + optional real-time API
- šŸš€ **Zero Configuration** - Works immediately with bundled pricing data
- šŸ’° **Comprehensive Pricing** - Registration, renewal, and transfer prices
- šŸ’¾ **Smart Caching** - 6-hour TTL cache reduces API load
- šŸ”— **Affiliate Links** - Optional affiliate tracking for purchase links
- 🌐 **Browser Integration** - Works with mcp-opener for automatic Firefox opening
- šŸ”’ **Optional Real-Time Pricing** - Use Joker.com DMAPI for current prices (requires credentials)
- šŸ“¦ **Lightweight** - No browser automation, pure API integration

## Quick Start

### 1. Installation

```bash
# Navigate to package directory
cd /var/home/viky/Code/packages/src/@mcp/mcp-domain-checker-price

# Run setup script
./setup.sh
```

### 2. Configuration (Optional)

The server works immediately with built-in pricing data. Configuration is only needed for:
- Real-time pricing updates (requires Joker.com credentials)
- Affiliate commission tracking

```bash
# Copy environment template (optional)
cp .env.example .env

# Edit .env with your credentials (optional)
nano .env
```

**Optional - For Real-Time Pricing:** Set Joker.com authentication:
- **Option A (Recommended):** API Key from [Joker.com → My Profile → API Access Keys](https://joker.com/user/profile)
- **Option B:** Username + Password

**Optional - For Affiliate Tracking:** Set affiliate ID for commission tracking

### 3. Add to Claude Code

Add to `.claude/settings.json` or global MCP configuration:

```json
{
  "mcpServers": {
    "domain-checker-price": {
      "command": "node",
      "args": ["/var/home/viky/Code/packages/src/@mcp/mcp-domain-checker-price/dist/index.js"]
    }
  }
}
```

## Available Tools

### 1. `get_version`
Get server version and capabilities

**Parameters:** None

**Example:**
```javascript
mcp__mcp-domain-checker-price__get_version()
```

---

### 2. `get_domain_pricing`
Fetch domain pricing from Joker.com (static data by default, real-time DMAPI optional)

**Parameters:**
- `domain` (string, required) - Domain name to check (e.g., "example.com")
- `force_refresh` (boolean, optional) - Bypass cache, default: false
- `use_api` (boolean, optional) - Use real-time DMAPI instead of static data (requires credentials), default: false

**Response:**
```json
{
  "domain": "example.com",
  "pricing": {
    "registration_1yr": 12.36,
    "renewal_1yr": 14.50,
    "transfer": 12.36,
    "currency": "EUR"
  },
  "special_offers": [
    {
      "description": "create discount until 12/31/2024",
      "discount_price": 10.00
    }
  ],
  "source_url": "https://dmapi.joker.com/request/query-price-list",
  "last_updated": "2025-12-11T14:30:00.000Z",
  "from_cache": false
}
```

**Example:**
```javascript
// Static pricing (default, fast, no auth required)
mcp__mcp-domain-checker-price__get_domain_pricing({ domain: "myapp.com" })

// Real-time pricing (requires Joker.com credentials)
mcp__mcp-domain-checker-price__get_domain_pricing({
  domain: "myapp.com",
  use_api: true
})

// Force refresh from cache
mcp__mcp-domain-checker-price__get_domain_pricing({
  domain: "myapp.com",
  force_refresh: true
})
```

---

### 3. `open_purchase_link`
Generate purchase links with optional affiliate tracking

**Parameters:**
- `domain` (string) - Single domain to purchase *(mutually exclusive with domains)*
- `domains` (array) - Multiple domains to purchase *(mutually exclusive with domain)*
- `open_all` (boolean, optional) - Open all URLs (true) or just first (false), default: false

**Response (Single Domain):**
```json
{
  "message": "Purchase link generated",
  "link": {
    "registrar": "joker",
    "domain": "example.com",
    "url": "https://joker.com/domain/registration?domain=example.com&aff=YOUR_ID",
    "is_affiliate": true,
    "price_estimate": 12.36,
    "currency": "EUR"
  },
  "suggestion": "Use mcp__opener__open_browser to open this URL in Firefox"
}
```

**Response (Multiple Domains):**
```json
{
  "message": "Purchase links generated for 3 domain(s)",
  "links": [...],
  "urls_to_open": ["https://joker.com/..."],
  "open_all": false,
  "total_estimate": {
    "total": 37.08,
    "currency": "EUR",
    "domains_with_pricing": 3,
    "domains_without_pricing": 0
  },
  "suggestion": "Use mcp__opener__open_browser to open 1 URL(s) in Firefox"
}
```

**Examples:**
```javascript
// Single domain
mcp__mcp-domain-checker-price__open_purchase_link({ domain: "myapp.com" })

// Multiple domains (open first only)
mcp__mcp-domain-checker-price__open_purchase_link({
  domains: ["app.com", "app.io", "app.dev"]
})

// Multiple domains (open all in separate tabs)
mcp__mcp-domain-checker-price__open_purchase_link({
  domains: ["app.com", "app.io", "app.dev"],
  open_all: true
})
```

## Integration with Opener MCP

**Recommended Workflow:**
```javascript
// Step 1: Get pricing
const pricing = await mcp__mcp-domain-checker-price__get_domain_pricing({
  domain: "myapp.com"
});

// Step 2: Generate purchase link
const purchase = await mcp__mcp-domain-checker-price__open_purchase_link({
  domain: "myapp.com"
});

// Step 3: Open in Firefox
await mcp__opener__open_browser({
  url: purchase.link.url
});
```

## Pricing System

### Two-Tier Architecture

**Static Pricing (Default):**
- āœ… Zero configuration required
- āœ… Instant response (no API calls)
- āœ… No authentication needed
- āš ļø Data may be slightly outdated (refresh with `./update-pricing.sh`)
- šŸ“Š Covers 10+ common TLDs by default (com, net, org, io, app, dev, etc.)

**Real-Time DMAPI (Optional):**
- āœ… Current prices directly from Joker.com
- āœ… Automatically updated
- āš ļø Requires Joker.com credentials
- āš ļø Slower (API call per request)

### Updating Static Pricing

```bash
# Option 1: Use the shell script (recommended)
./update-pricing.sh

# Option 2: Use pnpm script
pnpm fetch-pricing
```

This fetches current pricing from Joker.com DMAPI and updates `data/pricing.json`. The MCP server will automatically use the updated data on next restart.

**Note:** Requires Joker.com credentials configured in `.env`

## Configuration Reference

### Environment Variables

```bash
# ============================================================================
# Joker.com DMAPI Authentication (OPTIONAL - for real-time pricing)
# ============================================================================

# Option 1: API Key (Recommended)
# Create at: Joker.com → My Profile → Manage API access keys
MCP_JOKER_API_KEY="your-api-key-here"

# Option 2: Username & Password (Alternative)
MCP_JOKER_USERNAME="your-username"
MCP_JOKER_PASSWORD="your-password"

# ============================================================================
# Joker.com Affiliate Configuration (OPTIONAL - for commission tracking)
# ============================================================================

# Sign up: https://joker.com/affiliate
# Leave empty for non-affiliate links
MCP_AFFILIATE_JOKER_ID="your-affiliate-id"

# ============================================================================
# Pricing Cache Configuration
# ============================================================================

# Cache duration in hours (default: 6)
# Set to 0 to disable caching (not recommended)
MCP_DOMAIN_PRICING_CACHE_TTL_HOURS=6
```

### API Key vs Username/Password

| Method | Security | Features | Recommended |
|--------|----------|----------|-------------|
| **API Key** | āœ… Higher (revocable) | Can be read-only | āœ… Yes |
| **Username/Password** | āš ļø Lower | Full account access | āš ļø Only if needed |

**API Key Advantages:**
- Don't expose main credentials
- Can be restricted to read-only mode
- Can be revoked without changing password
- Can create multiple keys for different uses

## Architecture

```
mcp-domain-checker-price/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ index.ts                 # MCP server entry point
│   ā”œā”€ā”€ dmapi-client.ts          # Joker.com API authentication
│   ā”œā”€ā”€ pricing-fetcher.ts       # Two-tier pricing system
│   ā”œā”€ā”€ static-pricing.ts        # Static JSON loader (default)
│   ā”œā”€ā”€ affiliate-links.ts       # Purchase URL generation
│   ā”œā”€ā”€ price-cache.ts           # LRU cache with TTL
│   └── tools/
│       ā”œā”€ā”€ get-version.ts       # Version info tool
│       ā”œā”€ā”€ get-domain-pricing.ts    # Pricing tool
│       └── open-purchase-link.ts    # Purchase link tool
ā”œā”€ā”€ scripts/
│   └── fetch-pricing.ts         # DMAPI pricing fetcher
ā”œā”€ā”€ data/
│   └── pricing.json             # Static pricing database (optional)
ā”œā”€ā”€ dist/                        # Compiled JavaScript
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tsconfig.json
ā”œā”€ā”€ .env.example                 # Configuration template
ā”œā”€ā”€ setup.sh                     # Setup script
└── update-pricing.sh            # Update static pricing data
```

## How It Works

### Pricing Fetch Flow (Default - Static)
1. Check cache for domain pricing
2. If cache miss → Load from `data/pricing.json` (or use bundled defaults)
3. Extract pricing for domain's TLD
4. Cache result for 6 hours
5. Return pricing data

### Pricing Fetch Flow (Real-Time - use_api=true)
1. Check if DMAPI credentials configured
2. If not configured → Fall back to static pricing
3. Authenticate with Joker.com DMAPI (session valid 1 hour)
4. Call `query-price-list` API
5. Parse TSV response (tab-separated values)
6. Extract pricing for domain's TLD
7. Cache result for 6 hours
8. Return pricing data

### Affiliate Link Flow
1. Load affiliate ID from environment
2. Generate Joker.com registration URL
3. Append `&aff=YOUR_ID` if affiliate configured
4. Return URL with price estimate (if available)

## Troubleshooting

### āŒ "No pricing data found for TLD .xyz"
**Solution:**
- Using static pricing: TLD not in bundled data. Run `./update-pricing.sh` to fetch all Joker.com TLDs
- Using real-time pricing: TLD might not be available through Joker.com or not in your reseller account's price list

### āš ļø "DMAPI requested but not configured, using static pricing"
**Info:** You requested `use_api=true` but credentials not set. Server automatically falls back to static pricing. To use real-time pricing, set `MCP_JOKER_API_KEY` or `MCP_JOKER_USERNAME` + `MCP_JOKER_PASSWORD` in `.env`

### āŒ "DMAPI login failed (HTTP 401)"
**Solution:** Check credentials - API key may be expired or invalid

### āš ļø Cache always returns `from_cache: false`
**Solution:** Check `MCP_DOMAIN_PRICING_CACHE_TTL_HOURS` is > 0 in `.env`

### āš ļø Affiliate links show `is_affiliate: false`
**Solution:** Set `MCP_AFFILIATE_JOKER_ID` in `.env` and restart server

## Development

```bash
# Install dependencies
pnpm install

# Build TypeScript
pnpm build

# Watch mode
pnpm dev

# Update static pricing data (requires .env)
./update-pricing.sh

# Run tests (if available)
pnpm test
```

## API Reference

### Joker.com DMAPI Endpoints Used

- **`/request/login`** - Authentication
- **`/request/query-price-list`** - Complete TLD pricing list

**Documentation:** https://dmapi.joker.com/docs/

## License

MIT Ā© Victoria Lackey

## Sources

- [Joker.com DMAPI Documentation](https://dmapi.joker.com/docs/)
- [Joker.com Domain Management API](https://dmapi.joker.com/)
- [Joker.com FAQ - DMAPI](https://joker.com/faq/books/reseller-documentation-en/chapter/dmapi)

## Contributing

This package is part of the [@3viky/mcp](https://github.com/3viky) monorepo ecosystem.

For issues and contributions, please visit the [GitHub repository](https://github.com/3viky/mcp-domain-checker-price).

---

**Built with** [Model Context Protocol](https://modelcontextprotocol.io/) | **Powered by** [Joker.com DMAPI](https://dmapi.joker.com/)