@codespar/mcp-tienda-nube 0.1.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 +53 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +330 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# MCP Tienda Nube
|
|
2
|
+
|
|
3
|
+
MCP server for **Tienda Nube** (Nuvemshop) — the leading LATAM e-commerce platform, Argentine-founded, equivalent to Shopify for Latin America.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Set your credentials
|
|
9
|
+
export TIENDANUBE_ACCESS_TOKEN="your-access-token"
|
|
10
|
+
export TIENDANUBE_STORE_ID="your-store-id"
|
|
11
|
+
|
|
12
|
+
# Run via stdio
|
|
13
|
+
npx tsx packages/argentina/tienda-nube/src/index.ts
|
|
14
|
+
|
|
15
|
+
# Run via HTTP
|
|
16
|
+
npx tsx packages/argentina/tienda-nube/src/index.ts --http
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Environment Variables
|
|
20
|
+
|
|
21
|
+
| Variable | Required | Description |
|
|
22
|
+
|----------|----------|-------------|
|
|
23
|
+
| `TIENDANUBE_ACCESS_TOKEN` | Yes | Access token from Tienda Nube |
|
|
24
|
+
| `TIENDANUBE_STORE_ID` | Yes | Store identifier |
|
|
25
|
+
| `MCP_HTTP` | No | Set to `"true"` to enable HTTP transport |
|
|
26
|
+
| `MCP_PORT` | No | HTTP port (default: 3000) |
|
|
27
|
+
|
|
28
|
+
## Tools
|
|
29
|
+
|
|
30
|
+
| Tool | Description |
|
|
31
|
+
|------|-------------|
|
|
32
|
+
| `list_products` | List products from the store |
|
|
33
|
+
| `get_product` | Get product details by ID |
|
|
34
|
+
| `create_product` | Create a new product |
|
|
35
|
+
| `update_product` | Update an existing product |
|
|
36
|
+
| `list_orders` | List orders |
|
|
37
|
+
| `get_order` | Get order details by ID |
|
|
38
|
+
| `list_customers` | List customers |
|
|
39
|
+
| `get_customer` | Get customer details by ID |
|
|
40
|
+
| `list_categories` | List product categories |
|
|
41
|
+
| `update_order_status` | Update order fulfillment/shipping status |
|
|
42
|
+
|
|
43
|
+
## Auth
|
|
44
|
+
|
|
45
|
+
Uses **Bearer token** authentication. Obtain your access token via the Tienda Nube Partners OAuth flow. The store ID is included in the API base URL.
|
|
46
|
+
|
|
47
|
+
## API Reference
|
|
48
|
+
|
|
49
|
+
- [Tienda Nube API Docs](https://tiendanube.github.io/api-documentation/)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
**Enterprise?** Contact us at [codespar.com](https://codespar.com) for dedicated support, custom integrations, and SLAs.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for Tienda Nube — LATAM e-commerce platform (Nuvemshop).
|
|
4
|
+
*
|
|
5
|
+
* Tools:
|
|
6
|
+
* - list_products: List products
|
|
7
|
+
* - get_product: Get product by ID
|
|
8
|
+
* - create_product: Create a product
|
|
9
|
+
* - update_product: Update a product
|
|
10
|
+
* - list_orders: List orders
|
|
11
|
+
* - get_order: Get order by ID
|
|
12
|
+
* - list_customers: List customers
|
|
13
|
+
* - get_customer: Get customer by ID
|
|
14
|
+
* - list_categories: List product categories
|
|
15
|
+
* - update_order_status: Update order fulfillment status
|
|
16
|
+
*
|
|
17
|
+
* Environment:
|
|
18
|
+
* TIENDANUBE_ACCESS_TOKEN — Access token
|
|
19
|
+
* TIENDANUBE_STORE_ID — Store identifier
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for Tienda Nube — LATAM e-commerce platform (Nuvemshop).
|
|
4
|
+
*
|
|
5
|
+
* Tools:
|
|
6
|
+
* - list_products: List products
|
|
7
|
+
* - get_product: Get product by ID
|
|
8
|
+
* - create_product: Create a product
|
|
9
|
+
* - update_product: Update a product
|
|
10
|
+
* - list_orders: List orders
|
|
11
|
+
* - get_order: Get order by ID
|
|
12
|
+
* - list_customers: List customers
|
|
13
|
+
* - get_customer: Get customer by ID
|
|
14
|
+
* - list_categories: List product categories
|
|
15
|
+
* - update_order_status: Update order fulfillment status
|
|
16
|
+
*
|
|
17
|
+
* Environment:
|
|
18
|
+
* TIENDANUBE_ACCESS_TOKEN — Access token
|
|
19
|
+
* TIENDANUBE_STORE_ID — Store identifier
|
|
20
|
+
*/
|
|
21
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
22
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
23
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
24
|
+
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
25
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
26
|
+
const ACCESS_TOKEN = process.env.TIENDANUBE_ACCESS_TOKEN || "";
|
|
27
|
+
const STORE_ID = process.env.TIENDANUBE_STORE_ID || "";
|
|
28
|
+
const BASE_URL = `https://api.tiendanube.com/v1/${STORE_ID}`;
|
|
29
|
+
async function tiendaNubeRequest(method, path, body) {
|
|
30
|
+
const headers = {
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
"Accept": "application/json",
|
|
33
|
+
"Authentication": `bearer ${ACCESS_TOKEN}`,
|
|
34
|
+
"User-Agent": "MCP Tienda Nube Server/0.1.0",
|
|
35
|
+
};
|
|
36
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
37
|
+
method,
|
|
38
|
+
headers,
|
|
39
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
const err = await res.text();
|
|
43
|
+
throw new Error(`Tienda Nube API ${res.status}: ${err}`);
|
|
44
|
+
}
|
|
45
|
+
return res.json();
|
|
46
|
+
}
|
|
47
|
+
const server = new Server({ name: "mcp-tienda-nube", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
48
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
49
|
+
tools: [
|
|
50
|
+
{
|
|
51
|
+
name: "list_products",
|
|
52
|
+
description: "List products from the store",
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: "object",
|
|
55
|
+
properties: {
|
|
56
|
+
page: { type: "number", description: "Page number" },
|
|
57
|
+
per_page: { type: "number", description: "Results per page (max 200)" },
|
|
58
|
+
since_id: { type: "number", description: "Filter products after this ID" },
|
|
59
|
+
created_at_min: { type: "string", description: "Min creation date (ISO 8601)" },
|
|
60
|
+
created_at_max: { type: "string", description: "Max creation date (ISO 8601)" },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "get_product",
|
|
66
|
+
description: "Get product details by ID",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: { productId: { type: "number", description: "Product ID" } },
|
|
70
|
+
required: ["productId"],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "create_product",
|
|
75
|
+
description: "Create a new product",
|
|
76
|
+
inputSchema: {
|
|
77
|
+
type: "object",
|
|
78
|
+
properties: {
|
|
79
|
+
name: { type: "object", description: "Product name by locale, e.g. {\"es\":\"Producto\"}", properties: { es: { type: "string" }, pt: { type: "string" }, en: { type: "string" } } },
|
|
80
|
+
variants: {
|
|
81
|
+
type: "array",
|
|
82
|
+
description: "Product variants",
|
|
83
|
+
items: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
price: { type: "string", description: "Price" },
|
|
87
|
+
stock: { type: "number", description: "Stock quantity" },
|
|
88
|
+
sku: { type: "string", description: "SKU" },
|
|
89
|
+
weight: { type: "string", description: "Weight in kg" },
|
|
90
|
+
},
|
|
91
|
+
required: ["price"],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
description: { type: "object", description: "Description by locale", properties: { es: { type: "string" }, pt: { type: "string" } } },
|
|
95
|
+
published: { type: "boolean", description: "Whether the product is published" },
|
|
96
|
+
categories: { type: "array", description: "Category IDs", items: { type: "number" } },
|
|
97
|
+
},
|
|
98
|
+
required: ["name", "variants"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "update_product",
|
|
103
|
+
description: "Update an existing product",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
productId: { type: "number", description: "Product ID" },
|
|
108
|
+
name: { type: "object", description: "Product name by locale", properties: { es: { type: "string" }, pt: { type: "string" } } },
|
|
109
|
+
description: { type: "object", description: "Description by locale", properties: { es: { type: "string" }, pt: { type: "string" } } },
|
|
110
|
+
published: { type: "boolean", description: "Whether the product is published" },
|
|
111
|
+
},
|
|
112
|
+
required: ["productId"],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "list_orders",
|
|
117
|
+
description: "List orders",
|
|
118
|
+
inputSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: {
|
|
121
|
+
page: { type: "number", description: "Page number" },
|
|
122
|
+
per_page: { type: "number", description: "Results per page" },
|
|
123
|
+
status: { type: "string", description: "Order status (open, closed, cancelled)" },
|
|
124
|
+
payment_status: { type: "string", description: "Payment status (pending, paid, refunded)" },
|
|
125
|
+
shipping_status: { type: "string", description: "Shipping status (unpacked, shipped, delivered)" },
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "get_order",
|
|
131
|
+
description: "Get order details by ID",
|
|
132
|
+
inputSchema: {
|
|
133
|
+
type: "object",
|
|
134
|
+
properties: { orderId: { type: "number", description: "Order ID" } },
|
|
135
|
+
required: ["orderId"],
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "list_customers",
|
|
140
|
+
description: "List customers",
|
|
141
|
+
inputSchema: {
|
|
142
|
+
type: "object",
|
|
143
|
+
properties: {
|
|
144
|
+
page: { type: "number", description: "Page number" },
|
|
145
|
+
per_page: { type: "number", description: "Results per page" },
|
|
146
|
+
since_id: { type: "number", description: "Filter customers after this ID" },
|
|
147
|
+
q: { type: "string", description: "Search query (name, email)" },
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: "get_customer",
|
|
153
|
+
description: "Get customer details by ID",
|
|
154
|
+
inputSchema: {
|
|
155
|
+
type: "object",
|
|
156
|
+
properties: { customerId: { type: "number", description: "Customer ID" } },
|
|
157
|
+
required: ["customerId"],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "list_categories",
|
|
162
|
+
description: "List product categories",
|
|
163
|
+
inputSchema: {
|
|
164
|
+
type: "object",
|
|
165
|
+
properties: {
|
|
166
|
+
page: { type: "number", description: "Page number" },
|
|
167
|
+
per_page: { type: "number", description: "Results per page" },
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "update_order_status",
|
|
173
|
+
description: "Update order fulfillment/shipping status",
|
|
174
|
+
inputSchema: {
|
|
175
|
+
type: "object",
|
|
176
|
+
properties: {
|
|
177
|
+
orderId: { type: "number", description: "Order ID" },
|
|
178
|
+
status: { type: "string", description: "New status (open, closed, cancelled)" },
|
|
179
|
+
shipping_status: { type: "string", description: "Shipping status (unpacked, shipped, delivered)" },
|
|
180
|
+
tracking_number: { type: "string", description: "Tracking number" },
|
|
181
|
+
tracking_url: { type: "string", description: "Tracking URL" },
|
|
182
|
+
shipping_carrier: { type: "string", description: "Shipping carrier name" },
|
|
183
|
+
},
|
|
184
|
+
required: ["orderId"],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
}));
|
|
189
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
190
|
+
const { name, arguments: args } = request.params;
|
|
191
|
+
try {
|
|
192
|
+
switch (name) {
|
|
193
|
+
case "list_products": {
|
|
194
|
+
const params = new URLSearchParams();
|
|
195
|
+
if (args?.page)
|
|
196
|
+
params.set("page", String(args.page));
|
|
197
|
+
if (args?.per_page)
|
|
198
|
+
params.set("per_page", String(args.per_page));
|
|
199
|
+
if (args?.since_id)
|
|
200
|
+
params.set("since_id", String(args.since_id));
|
|
201
|
+
if (args?.created_at_min)
|
|
202
|
+
params.set("created_at_min", args.created_at_min);
|
|
203
|
+
if (args?.created_at_max)
|
|
204
|
+
params.set("created_at_max", args.created_at_max);
|
|
205
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/products?${params}`), null, 2) }] };
|
|
206
|
+
}
|
|
207
|
+
case "get_product":
|
|
208
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/products/${args?.productId}`), null, 2) }] };
|
|
209
|
+
case "create_product":
|
|
210
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("POST", "/products", {
|
|
211
|
+
name: args?.name,
|
|
212
|
+
variants: args?.variants,
|
|
213
|
+
description: args?.description,
|
|
214
|
+
published: args?.published,
|
|
215
|
+
categories: args?.categories,
|
|
216
|
+
}), null, 2) }] };
|
|
217
|
+
case "update_product": {
|
|
218
|
+
const payload = {};
|
|
219
|
+
if (args?.name)
|
|
220
|
+
payload.name = args.name;
|
|
221
|
+
if (args?.description)
|
|
222
|
+
payload.description = args.description;
|
|
223
|
+
if (args?.published !== undefined)
|
|
224
|
+
payload.published = args.published;
|
|
225
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("PUT", `/products/${args?.productId}`, payload), null, 2) }] };
|
|
226
|
+
}
|
|
227
|
+
case "list_orders": {
|
|
228
|
+
const params = new URLSearchParams();
|
|
229
|
+
if (args?.page)
|
|
230
|
+
params.set("page", String(args.page));
|
|
231
|
+
if (args?.per_page)
|
|
232
|
+
params.set("per_page", String(args.per_page));
|
|
233
|
+
if (args?.status)
|
|
234
|
+
params.set("status", args.status);
|
|
235
|
+
if (args?.payment_status)
|
|
236
|
+
params.set("payment_status", args.payment_status);
|
|
237
|
+
if (args?.shipping_status)
|
|
238
|
+
params.set("shipping_status", args.shipping_status);
|
|
239
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/orders?${params}`), null, 2) }] };
|
|
240
|
+
}
|
|
241
|
+
case "get_order":
|
|
242
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/orders/${args?.orderId}`), null, 2) }] };
|
|
243
|
+
case "list_customers": {
|
|
244
|
+
const params = new URLSearchParams();
|
|
245
|
+
if (args?.page)
|
|
246
|
+
params.set("page", String(args.page));
|
|
247
|
+
if (args?.per_page)
|
|
248
|
+
params.set("per_page", String(args.per_page));
|
|
249
|
+
if (args?.since_id)
|
|
250
|
+
params.set("since_id", String(args.since_id));
|
|
251
|
+
if (args?.q)
|
|
252
|
+
params.set("q", args.q);
|
|
253
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/customers?${params}`), null, 2) }] };
|
|
254
|
+
}
|
|
255
|
+
case "get_customer":
|
|
256
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/customers/${args?.customerId}`), null, 2) }] };
|
|
257
|
+
case "list_categories": {
|
|
258
|
+
const params = new URLSearchParams();
|
|
259
|
+
if (args?.page)
|
|
260
|
+
params.set("page", String(args.page));
|
|
261
|
+
if (args?.per_page)
|
|
262
|
+
params.set("per_page", String(args.per_page));
|
|
263
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("GET", `/categories?${params}`), null, 2) }] };
|
|
264
|
+
}
|
|
265
|
+
case "update_order_status": {
|
|
266
|
+
const payload = {};
|
|
267
|
+
if (args?.status)
|
|
268
|
+
payload.status = args.status;
|
|
269
|
+
if (args?.shipping_status)
|
|
270
|
+
payload.shipping_status = args.shipping_status;
|
|
271
|
+
if (args?.tracking_number)
|
|
272
|
+
payload.tracking_number = args.tracking_number;
|
|
273
|
+
if (args?.tracking_url)
|
|
274
|
+
payload.tracking_url = args.tracking_url;
|
|
275
|
+
if (args?.shipping_carrier)
|
|
276
|
+
payload.shipping_carrier = args.shipping_carrier;
|
|
277
|
+
return { content: [{ type: "text", text: JSON.stringify(await tiendaNubeRequest("PUT", `/orders/${args?.orderId}`, payload), null, 2) }] };
|
|
278
|
+
}
|
|
279
|
+
default:
|
|
280
|
+
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
async function main() {
|
|
288
|
+
if (process.argv.includes("--http") || process.env.MCP_HTTP === "true") {
|
|
289
|
+
const { default: express } = await import("express");
|
|
290
|
+
const { randomUUID } = await import("node:crypto");
|
|
291
|
+
const app = express();
|
|
292
|
+
app.use(express.json());
|
|
293
|
+
const transports = new Map();
|
|
294
|
+
app.get("/health", (_req, res) => res.json({ status: "ok", sessions: transports.size }));
|
|
295
|
+
app.post("/mcp", async (req, res) => {
|
|
296
|
+
const sid = req.headers["mcp-session-id"];
|
|
297
|
+
if (sid && transports.has(sid)) {
|
|
298
|
+
await transports.get(sid).handleRequest(req, res, req.body);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (!sid && isInitializeRequest(req.body)) {
|
|
302
|
+
const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
|
|
303
|
+
t.onclose = () => { if (t.sessionId)
|
|
304
|
+
transports.delete(t.sessionId); };
|
|
305
|
+
const s = new Server({ name: "mcp-tienda-nube", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
306
|
+
server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v));
|
|
307
|
+
server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v));
|
|
308
|
+
await s.connect(t);
|
|
309
|
+
await t.handleRequest(req, res, req.body);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null });
|
|
313
|
+
});
|
|
314
|
+
app.get("/mcp", async (req, res) => { const sid = req.headers["mcp-session-id"]; if (sid && transports.has(sid))
|
|
315
|
+
await transports.get(sid).handleRequest(req, res);
|
|
316
|
+
else
|
|
317
|
+
res.status(400).send("Invalid session"); });
|
|
318
|
+
app.delete("/mcp", async (req, res) => { const sid = req.headers["mcp-session-id"]; if (sid && transports.has(sid))
|
|
319
|
+
await transports.get(sid).handleRequest(req, res);
|
|
320
|
+
else
|
|
321
|
+
res.status(400).send("Invalid session"); });
|
|
322
|
+
const port = Number(process.env.MCP_PORT) || 3000;
|
|
323
|
+
app.listen(port, () => { console.error(`MCP HTTP server on http://localhost:${port}/mcp`); });
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
const transport = new StdioServerTransport();
|
|
327
|
+
await server.connect(transport);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codespar/mcp-tienda-nube",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Tienda Nube — LATAM e-commerce platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-tienda-nube": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": ["dist"],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"start": "node dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^22.0.0",
|
|
20
|
+
"typescript": "^5.8.0"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"keywords": ["tienda-nube", "nuvemshop", "ecommerce", "argentina", "latam", "mcp"],
|
|
24
|
+
"mcpName": "io.github.codespar/mcp-tienda-nube"
|
|
25
|
+
}
|