@shoppexio/mcp-commerce-server 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -1
- package/package.json +1 -1
- package/src/server.mjs +604 -0
package/README.md
CHANGED
|
@@ -1,3 +1,103 @@
|
|
|
1
1
|
# @shoppexio/mcp-commerce-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Model Context Protocol server for Shoppex commerce operations.
|
|
4
|
+
|
|
5
|
+
Connect Claude Desktop, Claude Code, Cursor, Windsurf, or Codex to your Shoppex store. Read products, orders, customers, and analytics, create payment links, manage coupons, and create or update products — directly from chat.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @shoppexio/mcp-commerce-server
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or run without installing:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx -y @shoppexio/mcp-commerce-server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Claude Desktop
|
|
20
|
+
|
|
21
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"mcpServers": {
|
|
26
|
+
"shoppex-commerce": {
|
|
27
|
+
"command": "npx",
|
|
28
|
+
"args": ["-y", "@shoppexio/mcp-commerce-server"],
|
|
29
|
+
"env": {
|
|
30
|
+
"SHOPPEX_SHOP_API_KEY": "shx_your_dev_api_key"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Restart Claude Desktop. Tools accept a `shop_api_key` argument on each call; the env var is available for clients that forward env to tool arguments.
|
|
38
|
+
|
|
39
|
+
## Cursor / Windsurf / Other
|
|
40
|
+
|
|
41
|
+
Any MCP client with stdio transport works. Set the same env var and point to `shoppex-mcp-commerce-server` as the command.
|
|
42
|
+
|
|
43
|
+
## Tools (12)
|
|
44
|
+
|
|
45
|
+
### Read
|
|
46
|
+
|
|
47
|
+
| Tool | Purpose |
|
|
48
|
+
|------|---------|
|
|
49
|
+
| `products.list` | Search or list products |
|
|
50
|
+
| `products.get` | Fetch one product by id or uniqid |
|
|
51
|
+
| `orders.list` | List recent orders, optionally filtered |
|
|
52
|
+
| `orders.get` | Fetch one order with line items |
|
|
53
|
+
| `customers.get` | Fetch a customer by id or email |
|
|
54
|
+
| `coupons.list` | List active coupons |
|
|
55
|
+
| `analytics.revenue` | Revenue totals for a date range |
|
|
56
|
+
|
|
57
|
+
### Write
|
|
58
|
+
|
|
59
|
+
| Tool | Purpose |
|
|
60
|
+
|------|---------|
|
|
61
|
+
| `products.create` | Create a product (service, serials, dynamic, file) |
|
|
62
|
+
| `products.update` | Update a product's price, title, gateways, stock, visibility |
|
|
63
|
+
| `coupons.create` | Create a coupon (percentage or fixed discount) |
|
|
64
|
+
| `coupons.update` | Update an existing coupon |
|
|
65
|
+
| `payment_links.create` | Create a payment link |
|
|
66
|
+
|
|
67
|
+
## Required Scopes
|
|
68
|
+
|
|
69
|
+
Your Shoppex Dev API key needs the scopes matching the tools you use (e.g. `products.read`, `products.write`, `orders.read`, `coupons.write`, `analytics.read`, `payment_links.write`).
|
|
70
|
+
|
|
71
|
+
Create one at [dashboard.shoppex.io/developer/api](https://dashboard.shoppex.io/developer/api).
|
|
72
|
+
|
|
73
|
+
## Environment Variables
|
|
74
|
+
|
|
75
|
+
| Variable | Required | Default |
|
|
76
|
+
|----------|----------|---------|
|
|
77
|
+
| `SHOPPEX_SHOP_API_KEY` | passed per call, or set here | — |
|
|
78
|
+
| `SHOPPEX_API_BASE_URL` | no | `https://api.shoppex.io` |
|
|
79
|
+
| `SHOPPEX_DEV_API_TIMEOUT_MS` | no | `10000` |
|
|
80
|
+
|
|
81
|
+
## Example Prompts
|
|
82
|
+
|
|
83
|
+
Once connected in Claude Desktop:
|
|
84
|
+
|
|
85
|
+
- "Create a Discord Nitro 3-month product for $14.99 paid in crypto."
|
|
86
|
+
- "Show me this month's top 10 customers by revenue."
|
|
87
|
+
- "Generate a 20% off coupon for my Discord members, valid until end of month."
|
|
88
|
+
- "Update the price of product `prd_abc123` to $12.99."
|
|
89
|
+
- "Make a payment link for a $50 USDT one-time purchase."
|
|
90
|
+
|
|
91
|
+
## Companion
|
|
92
|
+
|
|
93
|
+
Pair with [`@shoppexio/mcp-theme-server`](https://www.npmjs.com/package/@shoppexio/mcp-theme-server) for storefront theme operations.
|
|
94
|
+
|
|
95
|
+
## Docs
|
|
96
|
+
|
|
97
|
+
- [Developer API Reference](https://docs.shoppex.io/api-reference/introduction)
|
|
98
|
+
- [Quickstart](https://docs.shoppex.io/api-reference/quickstart)
|
|
99
|
+
- [Authentication](https://docs.shoppex.io/api-reference/authentication)
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
Proprietary. © Shoppex.
|
package/package.json
CHANGED
package/src/server.mjs
CHANGED
|
@@ -257,6 +257,180 @@ export class ShoppexCommerceDevApiClient {
|
|
|
257
257
|
body: input,
|
|
258
258
|
});
|
|
259
259
|
}
|
|
260
|
+
|
|
261
|
+
productsDelete(productId) {
|
|
262
|
+
return this.request('DELETE', `/dev/v1/products/${encodeURIComponent(productId)}`);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
productsDuplicate(productId) {
|
|
266
|
+
return this.request('POST', `/dev/v1/products/${encodeURIComponent(productId)}/duplicate`);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
productsUploadSerials(productId, input) {
|
|
270
|
+
return this.request('POST', `/dev/v1/products/${encodeURIComponent(productId)}/serials`, {
|
|
271
|
+
body: input,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
customersList(input = {}) {
|
|
276
|
+
return this.request('GET', '/dev/v1/customers', {
|
|
277
|
+
query: { limit: input.limit, filters: input.filters },
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
categoriesList() {
|
|
282
|
+
return this.request('GET', '/dev/v1/categories');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
categoriesCreate(input) {
|
|
286
|
+
return this.request('POST', '/dev/v1/categories', { body: input });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
categoriesUpdate(categoryId, input) {
|
|
290
|
+
return this.request('PATCH', `/dev/v1/categories/${encodeURIComponent(categoryId)}`, { body: input });
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
webhooksList() {
|
|
294
|
+
return this.request('GET', '/dev/v1/webhooks');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
webhooksCreate(input) {
|
|
298
|
+
return this.request('POST', '/dev/v1/webhooks', { body: input });
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
invoicesList(input = {}) {
|
|
302
|
+
return this.request('GET', '/dev/v1/invoices', {
|
|
303
|
+
query: { limit: input.limit, status: input.status, customer_email: input.customer_email },
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
invoicesGet(uniqid) {
|
|
308
|
+
return this.request('GET', `/dev/v1/invoices/${encodeURIComponent(uniqid)}`);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
disputesList(input = {}) {
|
|
312
|
+
return this.request('GET', '/dev/v1/disputes', {
|
|
313
|
+
query: { limit: input.limit, status: input.status },
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
licensesList() {
|
|
318
|
+
return this.request('GET', '/dev/v1/licenses');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
affiliatesList(input = {}) {
|
|
322
|
+
return this.request('GET', '/dev/v1/affiliates', {
|
|
323
|
+
query: { limit: input.limit },
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
subscriptionsList(input = {}) {
|
|
328
|
+
return this.request('GET', '/dev/v1/subscriptions', {
|
|
329
|
+
query: { limit: input.limit, status: input.status },
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
subscriptionsCancel(subscriptionId, input = {}) {
|
|
334
|
+
return this.request('POST', `/dev/v1/subscriptions/${encodeURIComponent(subscriptionId)}/cancel`, {
|
|
335
|
+
body: input,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
ordersUpdate(orderId, input) {
|
|
340
|
+
return this.request('PATCH', `/dev/v1/orders/${encodeURIComponent(orderId)}`, { body: input });
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
ordersFulfill(orderId, input = {}) {
|
|
344
|
+
return this.request('POST', `/dev/v1/orders/${encodeURIComponent(orderId)}/fulfill`, { body: input });
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
customersWalletCredit(customerId, input) {
|
|
348
|
+
return this.request('POST', `/dev/v1/customers/${encodeURIComponent(customerId)}/wallet/credit`, { body: input });
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
couponsGet(couponId) {
|
|
352
|
+
return this.request('GET', `/dev/v1/coupons/${encodeURIComponent(couponId)}`);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
couponsDelete(couponId) {
|
|
356
|
+
return this.request('DELETE', `/dev/v1/coupons/${encodeURIComponent(couponId)}`);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
paymentLinksList() {
|
|
360
|
+
return this.request('GET', '/dev/v1/payment-links');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
paymentLinksGet(linkId) {
|
|
364
|
+
return this.request('GET', `/dev/v1/payment-links/${encodeURIComponent(linkId)}`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
paymentLinksUpdate(linkId, input) {
|
|
368
|
+
return this.request('PATCH', `/dev/v1/payment-links/${encodeURIComponent(linkId)}`, { body: input });
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
paymentLinksDelete(linkId) {
|
|
372
|
+
return this.request('DELETE', `/dev/v1/payment-links/${encodeURIComponent(linkId)}`);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
paymentLinksToggle(linkId, input = {}) {
|
|
376
|
+
return this.request('POST', `/dev/v1/payment-links/${encodeURIComponent(linkId)}/toggle`, { body: input });
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
ticketsList(input = {}) {
|
|
380
|
+
return this.request('GET', '/dev/v1/tickets', {
|
|
381
|
+
query: { limit: input.limit, status: input.status },
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
ticketsGet(ticketId) {
|
|
386
|
+
return this.request('GET', `/dev/v1/tickets/${encodeURIComponent(ticketId)}`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
ticketsCreate(input) {
|
|
390
|
+
return this.request('POST', '/dev/v1/tickets', { body: input });
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
ticketsReply(ticketId, input) {
|
|
394
|
+
return this.request('POST', `/dev/v1/tickets/${encodeURIComponent(ticketId)}/messages`, { body: input });
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
ticketsClose(ticketId) {
|
|
398
|
+
return this.request('POST', `/dev/v1/tickets/${encodeURIComponent(ticketId)}/close`);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
blacklistList(input = {}) {
|
|
402
|
+
return this.request('GET', '/dev/v1/blacklist', {
|
|
403
|
+
query: { limit: input.limit, type: input.type },
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
blacklistAdd(input) {
|
|
408
|
+
return this.request('POST', '/dev/v1/blacklist', { body: input });
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
blacklistRemove(entryId) {
|
|
412
|
+
return this.request('DELETE', `/dev/v1/blacklist/${encodeURIComponent(entryId)}`);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
disputesGet(disputeId) {
|
|
416
|
+
return this.request('GET', `/dev/v1/disputes/${encodeURIComponent(disputeId)}`);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
licensesGet(licenseId) {
|
|
420
|
+
return this.request('GET', `/dev/v1/licenses/${encodeURIComponent(licenseId)}`);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
licensesUpdate(licenseId, input) {
|
|
424
|
+
return this.request('PATCH', `/dev/v1/licenses/${encodeURIComponent(licenseId)}`, { body: input });
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
analyticsReportsList() {
|
|
428
|
+
return this.request('GET', '/dev/v1/analytics/reports');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
analyticsReportGenerate(reportId) {
|
|
432
|
+
return this.request('POST', `/dev/v1/analytics/reports/${encodeURIComponent(reportId)}/generate`);
|
|
433
|
+
}
|
|
260
434
|
}
|
|
261
435
|
|
|
262
436
|
const BaseToolSchema = {
|
|
@@ -538,6 +712,436 @@ export function createCommerceToolCatalog() {
|
|
|
538
712
|
return createClient(args).productsUpdate(args.product_id, body);
|
|
539
713
|
},
|
|
540
714
|
},
|
|
715
|
+
{
|
|
716
|
+
name: 'products_delete',
|
|
717
|
+
description: 'Soft-delete a product by uniqid. The product is hidden from the storefront but kept for historical orders.',
|
|
718
|
+
inputSchema: { ...BaseToolSchema, product_id: z.string().trim().min(1) },
|
|
719
|
+
execute: async (args) => createClient(args).productsDelete(args.product_id),
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
name: 'products_duplicate',
|
|
723
|
+
description: 'Duplicate a product by uniqid. Returns the newly created product.',
|
|
724
|
+
inputSchema: { ...BaseToolSchema, product_id: z.string().trim().min(1) },
|
|
725
|
+
execute: async (args) => createClient(args).productsDuplicate(args.product_id),
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
name: 'products_upload_serials',
|
|
729
|
+
description: 'Upload additional serial keys (license keys) to a product whose type is SERIALS. Useful for restocking digital key-based products.',
|
|
730
|
+
inputSchema: {
|
|
731
|
+
...BaseToolSchema,
|
|
732
|
+
product_id: z.string().trim().min(1),
|
|
733
|
+
serials: z.array(z.string().trim().min(1)).min(1),
|
|
734
|
+
remove_duplicates: z.boolean().optional(),
|
|
735
|
+
},
|
|
736
|
+
execute: async (args) => createClient(args).productsUploadSerials(args.product_id, {
|
|
737
|
+
serials: args.serials,
|
|
738
|
+
serials_remove_duplicates: args.remove_duplicates ?? false,
|
|
739
|
+
}),
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
name: 'customers_list',
|
|
743
|
+
description: 'List customers for the authenticated shop. Supports Shoppex-style filter expressions (e.g. "email:john@example.com").',
|
|
744
|
+
inputSchema: {
|
|
745
|
+
...BaseToolSchema,
|
|
746
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
747
|
+
filters: z.string().trim().min(1).optional(),
|
|
748
|
+
},
|
|
749
|
+
execute: async (args) => createClient(args).customersList({
|
|
750
|
+
limit: args.limit,
|
|
751
|
+
filters: args.filters,
|
|
752
|
+
}),
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
name: 'categories_list',
|
|
756
|
+
description: 'List product categories for the authenticated shop.',
|
|
757
|
+
inputSchema: { ...BaseToolSchema },
|
|
758
|
+
execute: async (args) => createClient(args).categoriesList(),
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
name: 'categories_create',
|
|
762
|
+
description: 'Create a product category.',
|
|
763
|
+
inputSchema: {
|
|
764
|
+
...BaseToolSchema,
|
|
765
|
+
name: z.string().trim().min(1).max(128),
|
|
766
|
+
description: z.string().optional(),
|
|
767
|
+
parent_id: z.string().trim().min(1).optional().nullable(),
|
|
768
|
+
image_id: z.string().trim().min(1).optional().nullable(),
|
|
769
|
+
},
|
|
770
|
+
execute: async (args) => {
|
|
771
|
+
const body = { name: args.name };
|
|
772
|
+
if (args.description !== undefined) body.description = args.description;
|
|
773
|
+
if (args.parent_id !== undefined) body.parent_id = args.parent_id;
|
|
774
|
+
if (args.image_id !== undefined) body.image_id = args.image_id;
|
|
775
|
+
return createClient(args).categoriesCreate(body);
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
name: 'categories_update',
|
|
780
|
+
description: 'Update a category by id. Only provided fields change.',
|
|
781
|
+
inputSchema: {
|
|
782
|
+
...BaseToolSchema,
|
|
783
|
+
category_id: z.string().trim().min(1),
|
|
784
|
+
name: z.string().trim().min(1).max(128).optional(),
|
|
785
|
+
description: z.string().optional(),
|
|
786
|
+
parent_id: z.string().trim().min(1).optional().nullable(),
|
|
787
|
+
image_id: z.string().trim().min(1).optional().nullable(),
|
|
788
|
+
},
|
|
789
|
+
execute: async (args) => {
|
|
790
|
+
const body = {};
|
|
791
|
+
if (args.name !== undefined) body.name = args.name;
|
|
792
|
+
if (args.description !== undefined) body.description = args.description;
|
|
793
|
+
if (args.parent_id !== undefined) body.parent_id = args.parent_id;
|
|
794
|
+
if (args.image_id !== undefined) body.image_id = args.image_id;
|
|
795
|
+
return createClient(args).categoriesUpdate(args.category_id, body);
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
name: 'webhooks_list',
|
|
800
|
+
description: 'List webhook subscriptions registered for the authenticated shop.',
|
|
801
|
+
inputSchema: { ...BaseToolSchema },
|
|
802
|
+
execute: async (args) => createClient(args).webhooksList(),
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
name: 'webhooks_create',
|
|
806
|
+
description: 'Register a webhook subscription for shop events. Returns the webhook with its signing secret.',
|
|
807
|
+
inputSchema: {
|
|
808
|
+
...BaseToolSchema,
|
|
809
|
+
url: z.string().trim().url(),
|
|
810
|
+
events: z.array(z.string().trim().min(1)).min(1),
|
|
811
|
+
description: z.string().max(255).optional(),
|
|
812
|
+
},
|
|
813
|
+
execute: async (args) => {
|
|
814
|
+
const body = { url: args.url, events: args.events };
|
|
815
|
+
if (args.description !== undefined) body.description = args.description;
|
|
816
|
+
return createClient(args).webhooksCreate(body);
|
|
817
|
+
},
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
name: 'invoices_list',
|
|
821
|
+
description: 'List invoices. Can filter by status (pending, paid, cancelled, refunded) and customer email.',
|
|
822
|
+
inputSchema: {
|
|
823
|
+
...BaseToolSchema,
|
|
824
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
825
|
+
status: z.string().trim().min(1).optional(),
|
|
826
|
+
customer_email: z.string().trim().email().optional(),
|
|
827
|
+
},
|
|
828
|
+
execute: async (args) => createClient(args).invoicesList({
|
|
829
|
+
limit: args.limit,
|
|
830
|
+
status: args.status,
|
|
831
|
+
customer_email: args.customer_email,
|
|
832
|
+
}),
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
name: 'invoices_get',
|
|
836
|
+
description: 'Fetch one invoice with line items, payment, and customer by uniqid.',
|
|
837
|
+
inputSchema: { ...BaseToolSchema, invoice_id: z.string().trim().min(1) },
|
|
838
|
+
execute: async (args) => createClient(args).invoicesGet(args.invoice_id),
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
name: 'disputes_list',
|
|
842
|
+
description: 'List chargeback disputes. Filter by status (open, won, lost, warning).',
|
|
843
|
+
inputSchema: {
|
|
844
|
+
...BaseToolSchema,
|
|
845
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
846
|
+
status: z.string().trim().min(1).optional(),
|
|
847
|
+
},
|
|
848
|
+
execute: async (args) => createClient(args).disputesList({
|
|
849
|
+
limit: args.limit,
|
|
850
|
+
status: args.status,
|
|
851
|
+
}),
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
name: 'licenses_list',
|
|
855
|
+
description: 'List software licenses issued by the shop. Useful for validating or revoking customer license keys.',
|
|
856
|
+
inputSchema: { ...BaseToolSchema },
|
|
857
|
+
execute: async (args) => createClient(args).licensesList(),
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
name: 'affiliates_list',
|
|
861
|
+
description: 'List affiliates (customers with active affiliate links) for the authenticated shop.',
|
|
862
|
+
inputSchema: {
|
|
863
|
+
...BaseToolSchema,
|
|
864
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
865
|
+
},
|
|
866
|
+
execute: async (args) => createClient(args).affiliatesList({
|
|
867
|
+
limit: args.limit,
|
|
868
|
+
}),
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
name: 'subscriptions_list',
|
|
872
|
+
description: 'List recurring subscriptions. Filter by status (active, past_due, cancelled, paused, trialing).',
|
|
873
|
+
inputSchema: {
|
|
874
|
+
...BaseToolSchema,
|
|
875
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
876
|
+
status: z.string().trim().min(1).optional(),
|
|
877
|
+
},
|
|
878
|
+
execute: async (args) => createClient(args).subscriptionsList({
|
|
879
|
+
limit: args.limit,
|
|
880
|
+
status: args.status,
|
|
881
|
+
}),
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
name: 'subscriptions_cancel',
|
|
885
|
+
description: 'Cancel a subscription by id. Optionally cancel immediately or at end of current period.',
|
|
886
|
+
inputSchema: {
|
|
887
|
+
...BaseToolSchema,
|
|
888
|
+
subscription_id: z.string().trim().min(1),
|
|
889
|
+
cancel_at_period_end: z.boolean().optional(),
|
|
890
|
+
reason: z.string().max(255).optional(),
|
|
891
|
+
},
|
|
892
|
+
execute: async (args) => {
|
|
893
|
+
const body = {};
|
|
894
|
+
if (args.cancel_at_period_end !== undefined) body.cancel_at_period_end = args.cancel_at_period_end;
|
|
895
|
+
if (args.reason !== undefined) body.reason = args.reason;
|
|
896
|
+
return createClient(args).subscriptionsCancel(args.subscription_id, body);
|
|
897
|
+
},
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
name: 'orders_update',
|
|
901
|
+
description: 'Update an order (notes, internal state). Only provided fields change.',
|
|
902
|
+
inputSchema: {
|
|
903
|
+
...BaseToolSchema,
|
|
904
|
+
order_id: z.string().trim().min(1),
|
|
905
|
+
notes: z.string().max(2000).optional().nullable(),
|
|
906
|
+
internal_note: z.string().max(2000).optional().nullable(),
|
|
907
|
+
},
|
|
908
|
+
execute: async (args) => {
|
|
909
|
+
const body = {};
|
|
910
|
+
if (args.notes !== undefined) body.notes = args.notes;
|
|
911
|
+
if (args.internal_note !== undefined) body.internal_note = args.internal_note;
|
|
912
|
+
return createClient(args).ordersUpdate(args.order_id, body);
|
|
913
|
+
},
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
name: 'orders_fulfill',
|
|
917
|
+
description: 'Mark an order as fulfilled. For service products, this confirms delivery; for key-based products, the keys have already been delivered but this marks the order manually.',
|
|
918
|
+
inputSchema: {
|
|
919
|
+
...BaseToolSchema,
|
|
920
|
+
order_id: z.string().trim().min(1),
|
|
921
|
+
message: z.string().max(2000).optional(),
|
|
922
|
+
},
|
|
923
|
+
execute: async (args) => {
|
|
924
|
+
const body = {};
|
|
925
|
+
if (args.message !== undefined) body.message = args.message;
|
|
926
|
+
return createClient(args).ordersFulfill(args.order_id, body);
|
|
927
|
+
},
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
name: 'customers_wallet_credit',
|
|
931
|
+
description: 'Credit a customer wallet balance. Useful for refunds, goodwill credits, or promo grants.',
|
|
932
|
+
inputSchema: {
|
|
933
|
+
...BaseToolSchema,
|
|
934
|
+
customer_id: z.string().trim().min(1),
|
|
935
|
+
amount: z.number().positive(),
|
|
936
|
+
currency: z.string().trim().min(3).max(8).default('USD'),
|
|
937
|
+
reason: z.string().max(255).optional(),
|
|
938
|
+
},
|
|
939
|
+
execute: async (args) => createClient(args).customersWalletCredit(args.customer_id, {
|
|
940
|
+
amount: args.amount,
|
|
941
|
+
currency: args.currency,
|
|
942
|
+
reason: args.reason,
|
|
943
|
+
}),
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
name: 'coupons_get',
|
|
947
|
+
description: 'Fetch one coupon by uniqid.',
|
|
948
|
+
inputSchema: { ...BaseToolSchema, coupon_id: z.string().trim().min(1) },
|
|
949
|
+
execute: async (args) => createClient(args).couponsGet(args.coupon_id),
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
name: 'coupons_delete',
|
|
953
|
+
description: 'Delete a coupon by uniqid.',
|
|
954
|
+
inputSchema: { ...BaseToolSchema, coupon_id: z.string().trim().min(1) },
|
|
955
|
+
execute: async (args) => createClient(args).couponsDelete(args.coupon_id),
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
name: 'payment_links_list',
|
|
959
|
+
description: 'List payment links for the authenticated shop.',
|
|
960
|
+
inputSchema: { ...BaseToolSchema },
|
|
961
|
+
execute: async (args) => createClient(args).paymentLinksList(),
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
name: 'payment_links_get',
|
|
965
|
+
description: 'Fetch one payment link by uniqid.',
|
|
966
|
+
inputSchema: { ...BaseToolSchema, link_id: z.string().trim().min(1) },
|
|
967
|
+
execute: async (args) => createClient(args).paymentLinksGet(args.link_id),
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
name: 'payment_links_update',
|
|
971
|
+
description: 'Update a payment link by uniqid. Only provided fields change.',
|
|
972
|
+
inputSchema: {
|
|
973
|
+
...BaseToolSchema,
|
|
974
|
+
link_id: z.string().trim().min(1),
|
|
975
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
976
|
+
description: z.string().max(255).optional().nullable(),
|
|
977
|
+
price: z.number().positive().optional(),
|
|
978
|
+
currency: z.string().trim().min(3).max(8).optional(),
|
|
979
|
+
gateways: z.array(z.string().trim().min(1)).optional(),
|
|
980
|
+
active: z.boolean().optional(),
|
|
981
|
+
},
|
|
982
|
+
execute: async (args) => {
|
|
983
|
+
const body = {};
|
|
984
|
+
if (args.name !== undefined) body.name = args.name;
|
|
985
|
+
if (args.description !== undefined) body.description = args.description;
|
|
986
|
+
if (args.price !== undefined) body.price = args.price;
|
|
987
|
+
if (args.currency !== undefined) body.currency = args.currency;
|
|
988
|
+
if (args.gateways !== undefined) body.gateways = args.gateways.join(',');
|
|
989
|
+
if (args.active !== undefined) body.status = args.active;
|
|
990
|
+
return createClient(args).paymentLinksUpdate(args.link_id, body);
|
|
991
|
+
},
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
name: 'payment_links_delete',
|
|
995
|
+
description: 'Delete a payment link by uniqid.',
|
|
996
|
+
inputSchema: { ...BaseToolSchema, link_id: z.string().trim().min(1) },
|
|
997
|
+
execute: async (args) => createClient(args).paymentLinksDelete(args.link_id),
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
name: 'payment_links_toggle',
|
|
1001
|
+
description: 'Activate or deactivate a payment link.',
|
|
1002
|
+
inputSchema: {
|
|
1003
|
+
...BaseToolSchema,
|
|
1004
|
+
link_id: z.string().trim().min(1),
|
|
1005
|
+
active: z.boolean(),
|
|
1006
|
+
},
|
|
1007
|
+
execute: async (args) => createClient(args).paymentLinksToggle(args.link_id, { active: args.active }),
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
name: 'tickets_list',
|
|
1011
|
+
description: 'List customer support tickets. Filter by status (open, closed, etc.).',
|
|
1012
|
+
inputSchema: {
|
|
1013
|
+
...BaseToolSchema,
|
|
1014
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
1015
|
+
status: z.string().trim().min(1).optional(),
|
|
1016
|
+
},
|
|
1017
|
+
execute: async (args) => createClient(args).ticketsList({
|
|
1018
|
+
limit: args.limit,
|
|
1019
|
+
status: args.status,
|
|
1020
|
+
}),
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
name: 'tickets_get',
|
|
1024
|
+
description: 'Fetch one support ticket with all messages.',
|
|
1025
|
+
inputSchema: { ...BaseToolSchema, ticket_id: z.string().trim().min(1) },
|
|
1026
|
+
execute: async (args) => createClient(args).ticketsGet(args.ticket_id),
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
name: 'tickets_create',
|
|
1030
|
+
description: 'Create a new support ticket. Used when the merchant wants to proactively open a support conversation with a customer.',
|
|
1031
|
+
inputSchema: {
|
|
1032
|
+
...BaseToolSchema,
|
|
1033
|
+
subject: z.string().trim().min(1).max(255),
|
|
1034
|
+
message: z.string().trim().min(1),
|
|
1035
|
+
customer_id: z.string().trim().min(1).optional(),
|
|
1036
|
+
customer_email: z.string().trim().email().optional(),
|
|
1037
|
+
invoice_id: z.string().trim().min(1).optional(),
|
|
1038
|
+
order_id: z.string().trim().min(1).optional(),
|
|
1039
|
+
},
|
|
1040
|
+
execute: async (args) => {
|
|
1041
|
+
const body = { subject: args.subject, message: args.message };
|
|
1042
|
+
if (args.customer_id !== undefined) body.customer_id = args.customer_id;
|
|
1043
|
+
if (args.customer_email !== undefined) body.customer_email = args.customer_email;
|
|
1044
|
+
if (args.invoice_id !== undefined) body.invoice_id = args.invoice_id;
|
|
1045
|
+
if (args.order_id !== undefined) body.order_id = args.order_id;
|
|
1046
|
+
return createClient(args).ticketsCreate(body);
|
|
1047
|
+
},
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
name: 'tickets_reply',
|
|
1051
|
+
description: 'Post a reply message to a support ticket. The reply is visible to the customer.',
|
|
1052
|
+
inputSchema: {
|
|
1053
|
+
...BaseToolSchema,
|
|
1054
|
+
ticket_id: z.string().trim().min(1),
|
|
1055
|
+
message: z.string().trim().min(1),
|
|
1056
|
+
},
|
|
1057
|
+
execute: async (args) => createClient(args).ticketsReply(args.ticket_id, {
|
|
1058
|
+
message: args.message,
|
|
1059
|
+
}),
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
name: 'tickets_close',
|
|
1063
|
+
description: 'Close a support ticket.',
|
|
1064
|
+
inputSchema: { ...BaseToolSchema, ticket_id: z.string().trim().min(1) },
|
|
1065
|
+
execute: async (args) => createClient(args).ticketsClose(args.ticket_id),
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
name: 'blacklist_list',
|
|
1069
|
+
description: 'List blacklist entries (blocked emails, IPs, countries, etc.) for the authenticated shop. Use for fraud prevention.',
|
|
1070
|
+
inputSchema: {
|
|
1071
|
+
...BaseToolSchema,
|
|
1072
|
+
limit: z.number().int().min(1).max(100).optional(),
|
|
1073
|
+
type: z.enum(['email', 'ip', 'country', 'domain', 'phone']).optional(),
|
|
1074
|
+
},
|
|
1075
|
+
execute: async (args) => createClient(args).blacklistList({
|
|
1076
|
+
limit: args.limit,
|
|
1077
|
+
type: args.type,
|
|
1078
|
+
}),
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
name: 'blacklist_add',
|
|
1082
|
+
description: 'Add an entry to the shop blacklist. Blocks future checkouts from this email/IP/country/domain.',
|
|
1083
|
+
inputSchema: {
|
|
1084
|
+
...BaseToolSchema,
|
|
1085
|
+
type: z.enum(['email', 'ip', 'country', 'domain', 'phone']),
|
|
1086
|
+
value: z.string().trim().min(1),
|
|
1087
|
+
reason: z.string().max(255).optional(),
|
|
1088
|
+
},
|
|
1089
|
+
execute: async (args) => {
|
|
1090
|
+
const body = { type: args.type, value: args.value };
|
|
1091
|
+
if (args.reason !== undefined) body.reason = args.reason;
|
|
1092
|
+
return createClient(args).blacklistAdd(body);
|
|
1093
|
+
},
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
name: 'blacklist_remove',
|
|
1097
|
+
description: 'Remove a blacklist entry by uniqid.',
|
|
1098
|
+
inputSchema: { ...BaseToolSchema, entry_id: z.string().trim().min(1) },
|
|
1099
|
+
execute: async (args) => createClient(args).blacklistRemove(args.entry_id),
|
|
1100
|
+
},
|
|
1101
|
+
{
|
|
1102
|
+
name: 'disputes_get',
|
|
1103
|
+
description: 'Fetch one chargeback dispute with all evidence and history.',
|
|
1104
|
+
inputSchema: { ...BaseToolSchema, dispute_id: z.string().trim().min(1) },
|
|
1105
|
+
execute: async (args) => createClient(args).disputesGet(args.dispute_id),
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
name: 'licenses_get',
|
|
1109
|
+
description: 'Fetch one software license by uniqid with its activations and lock history.',
|
|
1110
|
+
inputSchema: { ...BaseToolSchema, license_id: z.string().trim().min(1) },
|
|
1111
|
+
execute: async (args) => createClient(args).licensesGet(args.license_id),
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
name: 'licenses_update',
|
|
1115
|
+
description: 'Update a license (revoke, extend validity, reset HWID/IP locks). Set active=false to revoke access.',
|
|
1116
|
+
inputSchema: {
|
|
1117
|
+
...BaseToolSchema,
|
|
1118
|
+
license_id: z.string().trim().min(1),
|
|
1119
|
+
active: z.boolean().optional(),
|
|
1120
|
+
valid_until: z.string().trim().optional().nullable(),
|
|
1121
|
+
hwid_lock: z.string().trim().optional().nullable(),
|
|
1122
|
+
ip_lock: z.string().trim().optional().nullable(),
|
|
1123
|
+
},
|
|
1124
|
+
execute: async (args) => {
|
|
1125
|
+
const body = {};
|
|
1126
|
+
if (args.active !== undefined) body.active = args.active;
|
|
1127
|
+
if (args.valid_until !== undefined) body.valid_until = args.valid_until;
|
|
1128
|
+
if (args.hwid_lock !== undefined) body.hwid_lock = args.hwid_lock;
|
|
1129
|
+
if (args.ip_lock !== undefined) body.ip_lock = args.ip_lock;
|
|
1130
|
+
return createClient(args).licensesUpdate(args.license_id, body);
|
|
1131
|
+
},
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
name: 'analytics_reports_list',
|
|
1135
|
+
description: 'List custom analytics reports configured for the shop.',
|
|
1136
|
+
inputSchema: { ...BaseToolSchema },
|
|
1137
|
+
execute: async (args) => createClient(args).analyticsReportsList(),
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
name: 'analytics_report_generate',
|
|
1141
|
+
description: 'Re-generate a custom analytics report by id. Useful to get fresh data for PDF/CSV exports.',
|
|
1142
|
+
inputSchema: { ...BaseToolSchema, report_id: z.string().trim().min(1) },
|
|
1143
|
+
execute: async (args) => createClient(args).analyticsReportGenerate(args.report_id),
|
|
1144
|
+
},
|
|
541
1145
|
];
|
|
542
1146
|
}
|
|
543
1147
|
|