@codespar/mcp-tienda-nube 0.1.0 → 0.2.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/dist/index.d.ts CHANGED
@@ -7,12 +7,26 @@
7
7
  * - get_product: Get product by ID
8
8
  * - create_product: Create a product
9
9
  * - update_product: Update a product
10
+ * - delete_product: Delete a product
11
+ * - list_product_variants: List variants of a product
12
+ * - update_product_variant: Update a product variant (price, stock, sku)
10
13
  * - list_orders: List orders
11
14
  * - get_order: Get order by ID
15
+ * - update_order_status: Update order fulfillment/shipping status
16
+ * - close_order: Close an order
17
+ * - cancel_order: Cancel an order
12
18
  * - list_customers: List customers
13
19
  * - get_customer: Get customer by ID
14
20
  * - list_categories: List product categories
15
- * - update_order_status: Update order fulfillment status
21
+ * - create_category: Create a category
22
+ * - update_category: Update a category
23
+ * - delete_category: Delete a category
24
+ * - list_webhooks: List configured webhooks
25
+ * - create_webhook: Subscribe to a webhook event
26
+ * - delete_webhook: Delete a webhook
27
+ * - list_discount_coupons: List discount coupons
28
+ * - create_discount_coupon: Create a discount coupon
29
+ * - list_abandoned_carts: List abandoned checkouts
16
30
  *
17
31
  * Environment:
18
32
  * TIENDANUBE_ACCESS_TOKEN — Access token
package/dist/index.js CHANGED
@@ -7,12 +7,26 @@
7
7
  * - get_product: Get product by ID
8
8
  * - create_product: Create a product
9
9
  * - update_product: Update a product
10
+ * - delete_product: Delete a product
11
+ * - list_product_variants: List variants of a product
12
+ * - update_product_variant: Update a product variant (price, stock, sku)
10
13
  * - list_orders: List orders
11
14
  * - get_order: Get order by ID
15
+ * - update_order_status: Update order fulfillment/shipping status
16
+ * - close_order: Close an order
17
+ * - cancel_order: Cancel an order
12
18
  * - list_customers: List customers
13
19
  * - get_customer: Get customer by ID
14
20
  * - list_categories: List product categories
15
- * - update_order_status: Update order fulfillment status
21
+ * - create_category: Create a category
22
+ * - update_category: Update a category
23
+ * - delete_category: Delete a category
24
+ * - list_webhooks: List configured webhooks
25
+ * - create_webhook: Subscribe to a webhook event
26
+ * - delete_webhook: Delete a webhook
27
+ * - list_discount_coupons: List discount coupons
28
+ * - create_discount_coupon: Create a discount coupon
29
+ * - list_abandoned_carts: List abandoned checkouts
16
30
  *
17
31
  * Environment:
18
32
  * TIENDANUBE_ACCESS_TOKEN — Access token
@@ -31,7 +45,7 @@ async function tiendaNubeRequest(method, path, body) {
31
45
  "Content-Type": "application/json",
32
46
  "Accept": "application/json",
33
47
  "Authentication": `bearer ${ACCESS_TOKEN}`,
34
- "User-Agent": "MCP Tienda Nube Server/0.1.0",
48
+ "User-Agent": "MCP Tienda Nube Server/0.2.0",
35
49
  };
36
50
  const res = await fetch(`${BASE_URL}${path}`, {
37
51
  method,
@@ -44,7 +58,7 @@ async function tiendaNubeRequest(method, path, body) {
44
58
  }
45
59
  return res.json();
46
60
  }
47
- const server = new Server({ name: "mcp-tienda-nube", version: "0.1.0" }, { capabilities: { tools: {} } });
61
+ const server = new Server({ name: "mcp-tienda-nube", version: "0.2.0" }, { capabilities: { tools: {} } });
48
62
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
49
63
  tools: [
50
64
  {
@@ -184,6 +198,178 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
184
198
  required: ["orderId"],
185
199
  },
186
200
  },
201
+ {
202
+ name: "delete_product",
203
+ description: "Delete a product by ID",
204
+ inputSchema: {
205
+ type: "object",
206
+ properties: { productId: { type: "number", description: "Product ID" } },
207
+ required: ["productId"],
208
+ },
209
+ },
210
+ {
211
+ name: "list_product_variants",
212
+ description: "List variants of a product",
213
+ inputSchema: {
214
+ type: "object",
215
+ properties: { productId: { type: "number", description: "Product ID" } },
216
+ required: ["productId"],
217
+ },
218
+ },
219
+ {
220
+ name: "update_product_variant",
221
+ description: "Update a product variant (price, stock, sku, weight)",
222
+ inputSchema: {
223
+ type: "object",
224
+ properties: {
225
+ productId: { type: "number", description: "Product ID" },
226
+ variantId: { type: "number", description: "Variant ID" },
227
+ price: { type: "string", description: "Price" },
228
+ promotional_price: { type: "string", description: "Promotional price" },
229
+ stock: { type: "number", description: "Stock quantity" },
230
+ sku: { type: "string", description: "SKU" },
231
+ weight: { type: "string", description: "Weight in kg" },
232
+ },
233
+ required: ["productId", "variantId"],
234
+ },
235
+ },
236
+ {
237
+ name: "close_order",
238
+ description: "Close an order (mark as fulfilled/closed)",
239
+ inputSchema: {
240
+ type: "object",
241
+ properties: { orderId: { type: "number", description: "Order ID" } },
242
+ required: ["orderId"],
243
+ },
244
+ },
245
+ {
246
+ name: "cancel_order",
247
+ description: "Cancel an order, optionally restocking and refunding",
248
+ inputSchema: {
249
+ type: "object",
250
+ properties: {
251
+ orderId: { type: "number", description: "Order ID" },
252
+ reason: { type: "string", description: "Cancellation reason (customer, inventory, fraud, other)" },
253
+ email: { type: "boolean", description: "Whether to notify the customer by email" },
254
+ restock: { type: "boolean", description: "Whether to restock items" },
255
+ },
256
+ required: ["orderId"],
257
+ },
258
+ },
259
+ {
260
+ name: "create_category",
261
+ description: "Create a product category",
262
+ inputSchema: {
263
+ type: "object",
264
+ properties: {
265
+ name: { type: "object", description: "Category name by locale, e.g. {\"es\":\"Categoría\"}", properties: { es: { type: "string" }, pt: { type: "string" }, en: { type: "string" } } },
266
+ description: { type: "object", description: "Description by locale", properties: { es: { type: "string" }, pt: { type: "string" } } },
267
+ parent: { type: "number", description: "Parent category ID (optional)" },
268
+ },
269
+ required: ["name"],
270
+ },
271
+ },
272
+ {
273
+ name: "update_category",
274
+ description: "Update a product category",
275
+ inputSchema: {
276
+ type: "object",
277
+ properties: {
278
+ categoryId: { type: "number", description: "Category ID" },
279
+ name: { type: "object", description: "Category name by locale", properties: { es: { type: "string" }, pt: { type: "string" } } },
280
+ description: { type: "object", description: "Description by locale", properties: { es: { type: "string" }, pt: { type: "string" } } },
281
+ parent: { type: "number", description: "Parent category ID" },
282
+ },
283
+ required: ["categoryId"],
284
+ },
285
+ },
286
+ {
287
+ name: "delete_category",
288
+ description: "Delete a product category by ID",
289
+ inputSchema: {
290
+ type: "object",
291
+ properties: { categoryId: { type: "number", description: "Category ID" } },
292
+ required: ["categoryId"],
293
+ },
294
+ },
295
+ {
296
+ name: "list_webhooks",
297
+ description: "List configured webhooks",
298
+ inputSchema: {
299
+ type: "object",
300
+ properties: {
301
+ page: { type: "number", description: "Page number" },
302
+ per_page: { type: "number", description: "Results per page" },
303
+ event: { type: "string", description: "Filter by event name" },
304
+ },
305
+ },
306
+ },
307
+ {
308
+ name: "create_webhook",
309
+ description: "Subscribe to a webhook event",
310
+ inputSchema: {
311
+ type: "object",
312
+ properties: {
313
+ event: { type: "string", description: "Event name (e.g. order/created, product/updated)" },
314
+ url: { type: "string", description: "Callback URL (HTTPS)" },
315
+ },
316
+ required: ["event", "url"],
317
+ },
318
+ },
319
+ {
320
+ name: "delete_webhook",
321
+ description: "Delete a webhook by ID",
322
+ inputSchema: {
323
+ type: "object",
324
+ properties: { webhookId: { type: "number", description: "Webhook ID" } },
325
+ required: ["webhookId"],
326
+ },
327
+ },
328
+ {
329
+ name: "list_discount_coupons",
330
+ description: "List discount coupons",
331
+ inputSchema: {
332
+ type: "object",
333
+ properties: {
334
+ page: { type: "number", description: "Page number" },
335
+ per_page: { type: "number", description: "Results per page" },
336
+ code: { type: "string", description: "Filter by exact coupon code" },
337
+ },
338
+ },
339
+ },
340
+ {
341
+ name: "create_discount_coupon",
342
+ description: "Create a discount coupon",
343
+ inputSchema: {
344
+ type: "object",
345
+ properties: {
346
+ code: { type: "string", description: "Coupon code" },
347
+ type: { type: "string", description: "Type: percentage, absolute, or shipping" },
348
+ value: { type: "string", description: "Discount value (numeric string)" },
349
+ valid: { type: "boolean", description: "Whether the coupon is valid" },
350
+ start_date: { type: "string", description: "Start date (YYYY-MM-DD)" },
351
+ end_date: { type: "string", description: "End date (YYYY-MM-DD)" },
352
+ max_uses: { type: "number", description: "Maximum number of uses" },
353
+ min_price: { type: "string", description: "Minimum cart price for coupon to apply" },
354
+ first_consumer_purchase: { type: "boolean", description: "Restrict to first-time customers" },
355
+ },
356
+ required: ["code", "type", "value"],
357
+ },
358
+ },
359
+ {
360
+ name: "list_abandoned_carts",
361
+ description: "List abandoned checkouts",
362
+ inputSchema: {
363
+ type: "object",
364
+ properties: {
365
+ page: { type: "number", description: "Page number" },
366
+ per_page: { type: "number", description: "Results per page" },
367
+ since_id: { type: "number", description: "Filter checkouts after this ID" },
368
+ created_at_min: { type: "string", description: "Min creation date (ISO 8601)" },
369
+ created_at_max: { type: "string", description: "Max creation date (ISO 8601)" },
370
+ },
371
+ },
372
+ },
187
373
  ],
188
374
  }));
189
375
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -276,6 +462,115 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
276
462
  payload.shipping_carrier = args.shipping_carrier;
277
463
  return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("PUT", `/orders/${args?.orderId}`, payload), null, 2) }] };
278
464
  }
465
+ case "delete_product":
466
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("DELETE", `/products/${args?.productId}`), null, 2) }] };
467
+ case "list_product_variants":
468
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/products/${args?.productId}/variants`), null, 2) }] };
469
+ case "update_product_variant": {
470
+ const payload = {};
471
+ if (args?.price !== undefined)
472
+ payload.price = args.price;
473
+ if (args?.promotional_price !== undefined)
474
+ payload.promotional_price = args.promotional_price;
475
+ if (args?.stock !== undefined)
476
+ payload.stock = args.stock;
477
+ if (args?.sku !== undefined)
478
+ payload.sku = args.sku;
479
+ if (args?.weight !== undefined)
480
+ payload.weight = args.weight;
481
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("PUT", `/products/${args?.productId}/variants/${args?.variantId}`, payload), null, 2) }] };
482
+ }
483
+ case "close_order":
484
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("POST", `/orders/${args?.orderId}/close`), null, 2) }] };
485
+ case "cancel_order": {
486
+ const payload = {};
487
+ if (args?.reason)
488
+ payload.reason = args.reason;
489
+ if (args?.email !== undefined)
490
+ payload.email = args.email;
491
+ if (args?.restock !== undefined)
492
+ payload.restock = args.restock;
493
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("POST", `/orders/${args?.orderId}/cancel`, payload), null, 2) }] };
494
+ }
495
+ case "create_category":
496
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("POST", "/categories", {
497
+ name: args?.name,
498
+ description: args?.description,
499
+ parent: args?.parent,
500
+ }), null, 2) }] };
501
+ case "update_category": {
502
+ const payload = {};
503
+ if (args?.name)
504
+ payload.name = args.name;
505
+ if (args?.description)
506
+ payload.description = args.description;
507
+ if (args?.parent !== undefined)
508
+ payload.parent = args.parent;
509
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("PUT", `/categories/${args?.categoryId}`, payload), null, 2) }] };
510
+ }
511
+ case "delete_category":
512
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("DELETE", `/categories/${args?.categoryId}`), null, 2) }] };
513
+ case "list_webhooks": {
514
+ const params = new URLSearchParams();
515
+ if (args?.page)
516
+ params.set("page", String(args.page));
517
+ if (args?.per_page)
518
+ params.set("per_page", String(args.per_page));
519
+ if (args?.event)
520
+ params.set("event", args.event);
521
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/webhooks?${params}`), null, 2) }] };
522
+ }
523
+ case "create_webhook":
524
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("POST", "/webhooks", {
525
+ event: args?.event,
526
+ url: args?.url,
527
+ }), null, 2) }] };
528
+ case "delete_webhook":
529
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("DELETE", `/webhooks/${args?.webhookId}`), null, 2) }] };
530
+ case "list_discount_coupons": {
531
+ const params = new URLSearchParams();
532
+ if (args?.page)
533
+ params.set("page", String(args.page));
534
+ if (args?.per_page)
535
+ params.set("per_page", String(args.per_page));
536
+ if (args?.code)
537
+ params.set("code", args.code);
538
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/coupons?${params}`), null, 2) }] };
539
+ }
540
+ case "create_discount_coupon": {
541
+ const payload = {
542
+ code: args?.code,
543
+ type: args?.type,
544
+ value: args?.value,
545
+ };
546
+ if (args?.valid !== undefined)
547
+ payload.valid = args.valid;
548
+ if (args?.start_date)
549
+ payload.start_date = args.start_date;
550
+ if (args?.end_date)
551
+ payload.end_date = args.end_date;
552
+ if (args?.max_uses !== undefined)
553
+ payload.max_uses = args.max_uses;
554
+ if (args?.min_price !== undefined)
555
+ payload.min_price = args.min_price;
556
+ if (args?.first_consumer_purchase !== undefined)
557
+ payload.first_consumer_purchase = args.first_consumer_purchase;
558
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("POST", "/coupons", payload), null, 2) }] };
559
+ }
560
+ case "list_abandoned_carts": {
561
+ const params = new URLSearchParams();
562
+ if (args?.page)
563
+ params.set("page", String(args.page));
564
+ if (args?.per_page)
565
+ params.set("per_page", String(args.per_page));
566
+ if (args?.since_id)
567
+ params.set("since_id", String(args.since_id));
568
+ if (args?.created_at_min)
569
+ params.set("created_at_min", args.created_at_min);
570
+ if (args?.created_at_max)
571
+ params.set("created_at_max", args.created_at_max);
572
+ return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/checkouts?${params}`), null, 2) }] };
573
+ }
279
574
  default:
280
575
  return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
281
576
  }
@@ -302,7 +597,7 @@ async function main() {
302
597
  const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
303
598
  t.onclose = () => { if (t.sessionId)
304
599
  transports.delete(t.sessionId); };
305
- const s = new Server({ name: "mcp-tienda-nube", version: "0.1.0" }, { capabilities: { tools: {} } });
600
+ const s = new Server({ name: "mcp-tienda-nube", version: "0.2.0" }, { capabilities: { tools: {} } });
306
601
  server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v));
307
602
  server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v));
308
603
  await s.connect(t);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codespar/mcp-tienda-nube",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server for Tienda Nube — LATAM e-commerce platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",