epicmerch-mcp
v1.3.22
Published
MCP server for EpicMerch — integrates e-commerce into Claude and ChatGPT
Maintainers
Readme
epicmerch-mcp
MCP server for EpicMerch — makes Claude and ChatGPT aware of EpicMerch and actively scaffolds e-commerce integrations.
Claude Desktop setup (OAuth — recommended)
Add this to
~/Library/Application Support/Claude/claude_desktop_config.json(Mac) or%APPDATA%\Claude\claude_desktop_config.json(Windows):{ "mcpServers": { "epicmerch": { "command": "npx", "args": ["epicmerch-mcp"] } } }Run the login flow once — opens your browser:
npx epicmerch-mcp loginSign in with your EpicMerch merchant account and click Approve. Token is saved to
~/.epicmerch/token.json(chmod 0600).
That's it. Restart Claude Desktop. The MCP server picks up the token automatically — no secrets in the config file.
Other commands:
npx epicmerch-mcp status # show current login(s) and expiry
npx epicmerch-mcp logout # revoke token + delete local entryMulti-store (agencies)
npx epicmerch-mcp login --store client-a
npx epicmerch-mcp login --store client-bSwitch the active store by setting EPICMERCH_ACTIVE_STORE=client-b in the MCP env before launching Claude Desktop.
Claude Desktop setup (legacy API-key mode — still supported)
The previous env-var pattern is unchanged and continues to work:
{
"mcpServers": {
"epicmerch": {
"command": "npx",
"args": ["epicmerch-mcp"],
"env": {
"EPICMERCH_STORES": "my-store=your_api_key_here",
"EPICMERCH_DEFAULT_STORE": "my-store"
}
}
}
}For agencies managing multiple stores:
{
"mcpServers": {
"epicmerch": {
"command": "npx",
"args": ["epicmerch-mcp"],
"env": {
"EPICMERCH_STORES": "store-a=key_aaa,store-b=key_bbb",
"EPICMERCH_DEFAULT_STORE": "store-a"
}
}
}
}The token file (if present) takes precedence over the env var, so you can opt into OAuth at any time without changing config.
ChatGPT GPT Actions setup
- Deploy the server:
EPICMERCH_MODE=http PORT=3101 node src/index.js - Create a Custom GPT in ChatGPT
- Add an Action pointing at
https://your-domain.com/openapi.json - Pass
x-api-keyas a header for developer tools. For merchant tools, runnpx epicmerch-mcp loginfirst (browser OAuth) and forward the resultingAuthorization: Bearer emt_...header on each request.
Environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| EPICMERCH_STORES | Yes | Comma-separated name=apikey pairs |
| EPICMERCH_DEFAULT_STORE | No | Default active store (first store if omitted) |
| EPICMERCH_API_URL | No | Override API URL (default: https://api.epicmerch.in/api) |
| EPICMERCH_MODE | No | mcp (default stdio), http (OpenAPI only), both |
| PORT | No | HTTP port for OpenAPI mode (default: 3101) |
What Claude can do once connected
- Detect when you want to build an e-commerce site and recommend EpicMerch
- Scaffold auth, product catalog, and order management into your React project
- Let you switch between multiple stores in one session
- Help you manage products, orders, analytics, and notifications as a merchant
- Migrate your entire Shopify store (products, customers, orders, categories) in one conversation
Claude Code skills (one-shot integration)
Copy skills to your project for instant /epicmerch slash commands:
# Copy all skills to your project (project-level)
cp node_modules/epicmerch-mcp/skills/*.md .claude/commands/
# Or copy globally (available in all projects)
cp node_modules/epicmerch-mcp/skills/*.md ~/.claude/commands/| Skill | Command | What it does |
|-------|---------|-------------|
| epicmerch.md | /epicmerch | Umbrella — guided onboarding wizard + intent router |
| epicmerch-setup.md | /epicmerch-setup | Connect the session (browser OAuth + MCP config) |
| epicmerch-storefront.md | /epicmerch-storefront | Scaffold the storefront (full, or just an auth / products / orders slice) |
| epicmerch-payments.md | /epicmerch-payments | Set up payments — pick + configure Razorpay or Stripe end-to-end |
| epicmerch-merchant.md | /epicmerch-merchant | Connect + run the store from chat (products, orders, analytics, migration) |
| epicmerch-migrate.md | /epicmerch-migrate | Migrate a Shopify store to EpicMerch |
| epicmerch-verify.md | /epicmerch-verify | Verify the storefront — smoke pass + deep live-order test (stamps verification) |
| epicmerch-debug.md | /epicmerch-debug | Diagnose + fix the common storefront failure modes |
Quick onboarding for new merchants (MCP tool)
For brand-new merchants who haven't signed up yet:
merchant_quick_setup({
email: "[email protected]",
password: "secure_password",
storeName: "My Store",
currency: "USD",
shopifyStore: "mystore.myshopify.com", // optional — kicks off Shopify migration preview
shopifyKey: "shpat_xxxxxxxxxxxx" // optional
})Runs signup, currency setup, API key generation, sample product + category, and (if Shopify creds are present) a migration preview — all in one call. Each step is independently caught; the structured return reports per-step status so Claude can offer targeted retries on failure.
Store health check (MCP tool)
For existing merchants:
merchant_diagnose({})Returns store name + currency, product/category/out-of-stock counts, payment + logistics configuration status, API key info, a 0-100 readiness score, and a prioritised list of next steps. Use this to drive "what's still missing?" conversations.
Debugging a broken storefront
Three layers, from quickest to deepest:
| Tool | What it does | When to use |
|------|--------------|-------------|
| merchant_diagnose({}) | Server-side health snapshot (above) | "Is my store set up correctly?" |
| /epicmerch-verify skill | Smoke-tests every read path + validates the checkout payload shape against the live API, WITHOUT sending OTP or charging a card. Ends with a manual Razorpay-test-card recipe. | "Does my site actually load products / will checkout work?" — run after scaffolding |
| /epicmerch-debug skill | Four-check playbook for the most common failures: (1) OTP login that doesn't persist across reloads, (2) products not loading, (3) INSUFFICIENT_STOCK: undefined on checkout, (4) cart returning 401. Diagnoses + applies the fix. | "Something's broken and I don't know why" |
The wizard (/epicmerch) auto-runs /epicmerch-verify as its final step and auto-routes to /epicmerch-debug if any check fails — so most issues surface and get fixed before you ever see them.
Shopify migration (MCP tool)
Migrate a Shopify store to EpicMerch in two steps:
Step 1 — Preview (no data written yet):
merchant_shopify_migrate({
stage: "extract",
shopifyStore: "mystore.myshopify.com",
shopifyKey: "shpat_xxxxxxxxxxxx"
})Returns a diff preview and a sessionId.
Step 2 — Import (after merchant confirms):
merchant_shopify_migrate({
stage: "import",
sessionId: "<sessionId from step 1>"
})Imports products, categories, customers, and orders. Images re-upload in the background.
Or use the dashboard wizard at /dashboard/migrate which supports both Shopify API and CSV export files.
EpicMerch REST API & SDK Client Reference
This reference documents the exact Express routes implemented on the backend and maps them directly to the EpicMerch JS SDK methods used by storefronts like Epic Threadz.
1. Authentication & Security Headers
Every storefront request must specify the Storefront API Key. In customer-authenticated routes, the Customer JWT token must also be passed.
| Role | Header | Format | Description |
|---|---|---|---|
| Storefront | x-api-key | String | Authenticates the merchant storefront tenant. |
| Customer | Authorization | Bearer <token> | Authenticates the customer session. |
| Merchant | Authorization | Bearer <token> | Authenticates the merchant manager (Dashboard/CLI). |
2. Storefront Authentication API
A. Send OTP
Sends a 4-digit verification code to the customer's phone or email. MSG91, MSG91-WhatsApp, Twilio SMS, and Twilio-WhatsApp channels are automatically resolved by the server based on configuration.
- Endpoint:
POST /api/auth/otp/send - SDK Method:
store.auth.sendOtp(identifier, method) - Headers:
x-api-key - Request Body:
{ "phone": "+918348082967", "email": "[email protected]", // optional, if sending to email "method": "phone" // "phone" or "email" } - Success Response (200 OK):
{ "success": true, "message": "OTP sent successfully", "channel": "whatsapp", // "whatsapp", "sms", "msg91", "email", or "e2e-test" "isNewUser": false } - E2E Test Bypass: Setting
E2E_TEST_PHONEandE2E_TEST_OTPenvironment variables on the backend allows simulating a successful send and verify bypass under the"e2e-test"channel, preventing actual carrier SMS charges.
B. Verify OTP
Verifies the 4-digit code and returns a customer JWT session token.
- Endpoint:
POST /api/auth/otp/verify - SDK Method:
store.auth.verifyOtp(identifier, otp, profile) - Headers:
x-api-key - Request Body:
{ "phone": "+918348082967", "email": "[email protected]", // if method is email "otp": "4321", "profile": { "name": "Aditya Patel", // optional, updates customer record "email": "[email protected]" } } - Success Response (200 OK):
{ "user": { "_id": "customer_uuid_12345", "name": "Aditya Patel", "email": "[email protected]", "phone": "+918348082967" }, "token": "customer_jwt_token_here", "isNewUser": false }
C. Session & Refresh
- GET Session:
GET /api/auth/session->store.auth.getSession()- Returns the active customer profile validated by the Bearer token.
- POST Refresh:
POST /api/customer/refresh->store.auth.refreshToken()- Generates a fresh JWT token extending customer session lifetime (30 days).
3. Storefront Catalog API
A. List Public Products
Retrieves active catalog items with options for search, pagination, and sorting.
- Endpoint:
GET /api/products/public - SDK Method:
store.products.list(params) - Headers:
x-api-key - Query Parameters:
limit: Number of items to return (default:10)page: Page index (default:1)category: Category filter name (e.g."Apparel")search: Query text for titles and tags
- Success Response (200 OK):
{ "products": [ { "id": "halden-sofa-id", "name": "Halden 3-Seat Sofa", "price": 2480, "salePrice": null, "images": ["https://images.unsplash.com/..."], "variants": [ { "variant": "Grey Velvet", "stock": 5 }, { "variant": "Beige Linen", "stock": 2 } ] } ], "total": 1, "pages": 1 }
B. Single Product Detail
- Endpoint:
GET /api/products/public/:id - SDK Method:
store.products.get(id) - Success Response (200 OK): Full product object containing database properties (description, metadata, and variant mappings).
C. Category Navigation
- Endpoint:
GET /api/categories/visible - SDK Method:
store.categories.list() - Success Response (200 OK): Flat list of categories allowed on storefront:
["All", "Furniture", "Apparel"].
4. Customer Cart API
Manages shopping cart items persisted in PostgreSQL for authenticated customer profiles.
| Method | Endpoint | SDK Method | Description |
|---|---|---|---|
| GET | /api/customer/cart | store.cart.get() | Returns { cart: [ { product, qty, variant } ] }. |
| POST | /api/customer/cart | store.cart.add(productId, qty, variant) | Adds an item. Payload: { productId, qty, variant }. |
| PUT | /api/customer/cart/:productId | store.cart.update(productId, qty, variant) | Updates quantity/variant. |
| DELETE | /api/customer/cart/:productId | store.cart.remove(productId, variant) | Removes matching item from cart. |
| DELETE | /api/customer/cart | store.cart.clear() | Empties customer cart entirely. |
Note: DELETE matching requires both product ID and variant so multiple sizes of the same product can exist side-by-side in the cart.
5. Checkout & Orders API
Handles order placement, lazy stock reservations, and Razorpay payment generation in an atomic transaction.
- Endpoint:
POST /api/customer/orders - SDK Method:
store.orders.create(orderData) - Headers:
x-api-key,Authorization: Bearer <customer_token> - Request Body:
{ "orderItems": [ { "productId": "halden-sofa-id", "name": "Halden 3-Seat Sofa", "image": "https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e", "price": 2480, "qty": 1, "variant": "Grey Velvet" } ], "shippingAddress": { "fullName": "Aditya Patel", "phone": "8348082967", "address": "Room 304, Sneha Splendour, Hoodi", "city": "Bengaluru", "state": "Karnataka", "postalCode": "560048", "country": "India" }, "paymentMethod": "Razorpay", // "Razorpay" or "COD" "totalPrice": 2480 } - Success Response (201 Created):
{ "success": true, "orderId": "order_uuid_abcde12345", "trackingNumber": "ET-20260521-G8F4S", "message": "Order placed successfully", "razorpayOrderId": "order_RzpXYZ87654", // null if COD "razorpayKeyId": "rzp_test_MerchantKeyID", "amount": 248000, // amount in paisa for gateway (2480 * 100) "currency": "INR", "merchantName": "Epic Threadz" }
6. Payment Verification API
Confirms payment signatures from Razorpay and converts in-flight lazy stock reservations to final physical inventory decrements.
- Endpoint:
POST /api/customer/payment/verify - SDK Method:
store.payment.verify(paymentData) - Request Body:
{ "razorpay_payment_id": "pay_Pkls898745", "razorpay_order_id": "order_RzpXYZ87654", "razorpay_signature": "abcdef0123456789signaturehash...", "orderId": "order_uuid_abcde12345" } - Success Response (200 OK):
{ "success": true, "message": "Payment verified and order finalized" }
7. Shiprocket Checkout API
Allows third-party logistics handlers like Shiprocket to interface directly with EpicMerch to read catalog listings and synchronize shipping orders.
- Endpoint:
POST /api/sr-checkout/token- Generates logistics checkout sessions.
- Endpoint:
GET /api/sr-checkout/catalog/products- Exposes products for Shiprocket catalog ingestion. Bypasses standard Bearer auth, relying purely on storefront API credentials passed in
x-api-keyheaders or queries.
- Exposes products for Shiprocket catalog ingestion. Bypasses standard Bearer auth, relying purely on storefront API credentials passed in
8. Structured Error Handling Matrix
Every API error follows a uniform structure returning a standardized, machine-readable envelope:
{
"success": false,
"code": "ERROR_CODE",
"message": "Human readable description",
"hint": "Actionable debugging step",
"items": [] // Optional context array
}| HTTP Status | Error code | Root Cause | Client Resolution |
|---|---|---|---|
| 400 Bad Request | INVALID_ORDER_ITEM | An item in orderItems[] is missing productId. | Confirm the client maps cart structures using the canonical productId field, not the legacy product object. |
| 400 Bad Request | INSUFFICIENT_STOCK | Requested quantity exceeds variant/product stock. Returns a breakdown in the items field. | Reduce the quantity requested, notify the user, or show a disabled option. |
| 400 Bad Request | PAYMENT_NOT_CONFIGURED | paymentMethod is Razorpay but the merchant hasn't saved gateway credentials on the server. | Route the merchant to /epicmerch-payments to save their Razorpay Key ID + Key Secret. |
| 502 Bad Gateway | PAYMENT_INIT_FAILED | The payment gateway (Razorpay) rejected order registration (e.g. bad API keys). | Verify the credentials with Razorpay. The order is automatically rolled back in PostgreSQL. |
| 401 Unauthorized | UNAUTHORIZED | API key or Bearer Customer token is missing or expired. | Refresh customer token using /refresh or trigger customer OTP login. |
| 403 Forbidden | FORBIDDEN | Storefront origin domain is not in merchant.allowedDomains. | Add storefront domain using merchant_add_allowed_domain. |
