Imported from reason-machines/mcp-skills (
skills/commercevault-edd-mcp-server/SKILL.md). Install upstream withnpx skills add reason-machines/mcp-skills --skill commercevault-edd-mcp-server. Copyright stays with the author.
CommerceVault EDD MCP Server
Skill by ara.so — MCP Skills collection.
CommerceVault (mcp-edd-analytics-vantage) is an MCP (Model Context Protocol) server that provides natural language access to Easy Digital Downloads (EDD) WordPress e-commerce data. It enables AI assistants to query sales analytics, manage products, retrieve customer orders, and perform revenue analysis through a structured API interface.
What It Does
This MCP server acts as a middleware layer between AI coding agents and Easy Digital Downloads REST API, providing:
- Sales Analytics: Revenue reports, GMV, AOV, cohort analysis
- Product Management: Catalog synchronization, pricing, digital downloads
- Order Operations: Lifecycle management, fulfillment tracking, refunds
- Customer Data: Profiles, purchase history, LTV calculations
- License Management: Key generation, activation tracking, entitlements
- Webhook Relay: Event forwarding with transformation and enrichment
Installation
Prerequisites
- Node.js 18+ or Python 3.9+
- Easy Digital Downloads installed on WordPress site
- EDD REST API credentials (API key and token)
- MCP-compatible client (Claude Desktop, Cursor, etc.)
Install as MCP Server
- Clone or download the repository:
git clone https://github.com/dhapat3927/mcp-edd-analytics-vantage.git
cd mcp-edd-analytics-vantage
- Install dependencies:
npm install
# or
pip install -r requirements.txt
- Configure MCP client settings (e.g., Claude Desktop
claude_desktop_config.json):
{
"mcpServers": {
"commercevault-edd": {
"command": "node",
"args": ["/path/to/mcp-edd-analytics-vantage/server.js"],
"env": {
"EDD_API_URL": "https://yoursite.com/wp-json/edd/v2",
"EDD_API_KEY": "${EDD_API_KEY}",
"EDD_API_TOKEN": "${EDD_API_TOKEN}",
"CACHE_ENABLED": "true",
"CACHE_TTL": "300"
}
}
}
}
For Python implementation:
{
"mcpServers": {
"commercevault-edd": {
"command": "python",
"args": ["/path/to/mcp-edd-analytics-vantage/server.py"],
"env": {
"EDD_API_URL": "https://yoursite.com/wp-json/edd/v2",
"EDD_API_KEY": "${EDD_API_KEY}",
"EDD_API_TOKEN": "${EDD_API_TOKEN}"
}
}
}
}
Configuration
Environment Variables
| Variable | Required | Description | Default |
|---|---|---|---|
EDD_API_URL |
Yes | Full URL to EDD REST API endpoint | - |
EDD_API_KEY |
Yes | EDD API key from WordPress admin | - |
EDD_API_TOKEN |
Yes | EDD API token for authentication | - |
CACHE_ENABLED |
No | Enable Redis-backed response caching | false |
CACHE_TTL |
No | Cache time-to-live in seconds | 300 |
REDIS_URL |
No | Redis connection string | redis://localhost:6379 |
RATE_LIMIT_MAX |
No | Max requests per minute | 60 |
LOG_LEVEL |
No | Logging verbosity (debug/info/warn/error) | info |
HMAC_SECRET |
No | Shared secret for payload signatures | - |
Getting EDD API Credentials
- Log into WordPress admin
- Navigate to Downloads → Settings → API
- Click Generate API Keys
- Copy the Public Key (API_KEY) and Token (API_TOKEN)
- Set appropriate permissions for the key (read/write)
Key API Tools
The MCP server exposes these tools for AI agents:
Products
edd_get_products - Retrieve product catalog
// Parameters
{
"category": "software", // Filter by category slug
"tag": "featured", // Filter by tag
"search": "premium", // Search product titles
"per_page": 20, // Results per page (default: 10)
"page": 1 // Page number
}
edd_get_product - Get single product details
{
"product_id": 123 // Product ID
}
Orders
edd_get_orders - Retrieve order history
{
"status": "complete", // Order status filter
"customer": 456, // Customer ID
"start_date": "2026-01-01",
"end_date": "2026-06-30",
"per_page": 50
}
edd_get_order - Get single order details
{
"order_id": 789
}
edd_create_order - Create new order
{
"customer_id": 456,
"products": [
{
"product_id": 123,
"price": 49.99,
"quantity": 1
}
],
"status": "pending",
"gateway": "stripe"
}
Customers
edd_get_customers - Retrieve customer list
{
"email": "user@example.com",
"order_by": "purchase_count",
"order": "desc"
}
edd_get_customer_stats - Get customer analytics
{
"customer_id": 456
}
// Returns: total_spent, purchase_count, avg_order_value, lifetime_value
Analytics
edd_get_sales_stats - Revenue and sales metrics
{
"start_date": "2026-01-01",
"end_date": "2026-06-30",
"interval": "day", // day, week, month
"product_id": 123 // Optional: filter by product
}
// Returns: revenue, orders, avg_order_value, gross_merchandise_value
edd_get_top_products - Best-selling products report
{
"period": "30days", // 7days, 30days, 90days, year
"limit": 10
}
Licenses
edd_get_licenses - Retrieve license keys
{
"product_id": 123,
"status": "active", // active, inactive, expired
"customer_id": 456
}
edd_activate_license - Activate license key
{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"site_url": "https://customer-site.com",
"item_id": 123
}
Code Examples
Example 1: Fetch Monthly Revenue Report
// server.js implementation snippet
async function getSalesStats(params) {
const { start_date, end_date, interval = 'day' } = params;
const response = await fetch(
`${process.env.EDD_API_URL}/reports/sales?` +
`start_date=${start_date}&end_date=${end_date}&interval=${interval}`,
{
headers: {
'Authorization': `Basic ${Buffer.from(
`${process.env.EDD_API_KEY}:${process.env.EDD_API_TOKEN}`
).toString('base64')}`,
'Content-Type': 'application/json'
}
}
);
if (!response.ok) {
throw new Error(`EDD API error: ${response.statusText}`);
}
const data = await response.json();
return {
revenue: data.totals.revenue,
orders: data.totals.orders,
avg_order_value: data.totals.revenue / data.totals.orders,
interval_data: data.data
};
}
Example 2: Create Order with License
# server.py implementation snippet
import requests
import os
from base64 import b64encode
def create_order_with_license(customer_id, product_id, price):
auth_string = f"{os.getenv('EDD_API_KEY')}:{os.getenv('EDD_API_TOKEN')}"
auth_header = b64encode(auth_string.encode()).decode()
headers = {
'Authorization': f'Basic {auth_header}',
'Content-Type': 'application/json'
}
payload = {
'customer': customer_id,
'products': [{
'product_id': product_id,
'price': price,
'quantity': 1,
'options': {
'generate_license': True
}
}],
'status': 'complete',
'gateway': 'manual'
}
response = requests.post(
f"{os.getenv('EDD_API_URL')}/orders",
json=payload,
headers=headers
)
response.raise_for_status()
order_data = response.json()
return {
'order_id': order_data['id'],
'license_key': order_data['licenses'][0]['key'],
'total': order_data['total']
}
Example 3: Customer Lifetime Value Analysis
async function analyzeCustomerLTV(customer_id) {
const orders = await eddRequest('GET', '/orders', {
customer: customer_id,
status: 'complete'
});
const stats = orders.reduce((acc, order) => {
acc.total_spent += parseFloat(order.total);
acc.order_count += 1;
acc.products_purchased += order.items.length;
const orderDate = new Date(order.date_created);
if (!acc.first_purchase || orderDate < acc.first_purchase) {
acc.first_purchase = orderDate;
}
if (!acc.last_purchase || orderDate > acc.last_purchase) {
acc.last_purchase = orderDate;
}
return acc;
}, {
total_spent: 0,
order_count: 0,
products_purchased: 0,
first_purchase: null,
last_purchase: null
});
const daysSinceFirst = Math.floor(
(new Date() - stats.first_purchase) / (1000 * 60 * 60 * 24)
);
return {
lifetime_value: stats.total_spent,
avg_order_value: stats.total_spent / stats.order_count,
purchase_frequency: stats.order_count / (daysSinceFirst / 30),
customer_age_days: daysSinceFirst,
predicted_12mo_value: (stats.total_spent / daysSinceFirst) * 365
};
}
Common Patterns
Pattern 1: Product Catalog Sync with Caching
const CACHE = new Map();
const CACHE_TTL = parseInt(process.env.CACHE_TTL || '300') * 1000;
async function getCachedProducts(params) {
const cacheKey = JSON.stringify(params);
const cached = CACHE.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const products = await eddRequest('GET', '/products', params);
CACHE.set(cacheKey, {
data: products,
timestamp: Date.now()
});
return products;
}
Pattern 2: Webhook Event Processing
function processWebhook(event) {
const enriched = {
...event,
processed_at: new Date().toISOString(),
source: 'edd-webhook'
};
switch (event.event_type) {
case 'edd_complete_purchase':
return handleOrderComplete(enriched);
case 'edd_customer_created':
return handleCustomerCreated(enriched);
case 'edd_subscription_status_changed':
return handleSubscriptionChange(enriched);
default:
return { status: 'ignored', event_type: event.event_type };
}
}
Pattern 3: Rate-Limited Batch Operations
async function batchUpdateProducts(updates) {
const RATE_LIMIT = parseInt(process.env.RATE_LIMIT_MAX || '60');
const DELAY = (60 / RATE_LIMIT) * 1000;
const results = [];
for (const update of updates) {
try {
const result = await eddRequest('PUT', `/products/${update.id}`, update);
results.push({ success: true, id: update.id, result });
} catch (error) {
results.push({ success: false, id: update.id, error: error.message });
}
await new Promise(resolve => setTimeout(resolve, DELAY));
}
return results;
}
Troubleshooting
Authentication Failures
Symptom: 401 Unauthorized errors
Solution:
- Verify
EDD_API_KEYandEDD_API_TOKENare correct - Check API key permissions in WordPress admin
- Ensure key hasn't been revoked or expired
- Test credentials with curl:
curl -u "PUBLIC_KEY:TOKEN" https://yoursite.com/wp-json/edd/v2/products
Rate Limiting Issues
Symptom: 429 Too Many Requests errors
Solution:
- Reduce
RATE_LIMIT_MAXin configuration - Implement request queuing with delays
- Enable caching to reduce API calls
- Use batch endpoints where available
Missing Data in Responses
Symptom: Expected fields are null or missing
Solution:
- Verify EDD version supports the endpoint
- Check if required EDD extensions are installed (e.g., Software Licensing)
- Update API version in
EDD_API_URL(try/v2or/v3) - Review EDD plugin settings for disabled features
Connection Timeouts
Symptom: Requests hang or timeout
Solution:
- Increase timeout in fetch/requests configuration
- Check WordPress site performance and hosting
- Verify firewall rules allow MCP server IP
- Enable WordPress caching (Redis/Memcached)
Cache Staleness
Symptom: Outdated data returned after updates
Solution:
- Reduce
CACHE_TTLvalue - Implement cache invalidation on write operations
- Use Redis with TTL instead of in-memory cache
- Add cache-busting query parameters
HMAC Verification Errors
Symptom: Signature mismatch warnings
Solution:
- Ensure
HMAC_SECRETmatches across client and server - Verify payload hasn't been modified in transit
- Check for character encoding issues
- Use webhook signature verification from EDD settings
Advanced Usage
Custom Middleware Chain
const middleware = [
validateRequest,
enrichWithGeoData,
applyTaxCalculation,
logAuditTrail
];
async function processRequest(tool, params) {
let context = { tool, params, timestamp: Date.now() };
for (const fn of middleware) {
context = await fn(context);
}
return executeEDDTool(context.tool, context.params);
}
Multi-Store Support
const stores = {
'store1': {
url: process.env.EDD_STORE1_URL,
key: process.env.EDD_STORE1_KEY,
token: process.env.EDD_STORE1_TOKEN
},
'store2': {
url: process.env.EDD_STORE2_URL,
key: process.env.EDD_STORE2_KEY,
token: process.env.EDD_STORE2_TOKEN
}
};
function getStoreConfig(store_id) {
return stores[store_id] || stores['store1'];
}
This skill enables AI coding agents to interact with Easy Digital Downloads through natural language, performing complex e-commerce operations, analytics, and automation tasks seamlessly.