@commercetools/commerce-mcp 1.0.6 → 2.0.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.js +82 -149
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.ACCEPTED_TOOLS = void 0;
|
|
4
|
+
exports.resolveToolsForConfiguration = exports.applyResolvedToolsToConfiguration = exports.ACCEPTED_TOOLS = void 0;
|
|
5
5
|
exports.parseArgs = parseArgs;
|
|
6
6
|
exports.main = main;
|
|
7
7
|
const modelcontextprotocol_1 = require("@commercetools/commerce-agent/modelcontextprotocol");
|
|
8
|
+
const processors_1 = require("@commercetools/processors");
|
|
8
9
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
9
10
|
const colors_1 = require("colors");
|
|
10
11
|
const HIDDEN_ARGS = ['customerId', 'isAdmin', 'storeKey', 'businessUnitKey'];
|
|
@@ -21,121 +22,18 @@ const PUBLIC_ARGS = [
|
|
|
21
22
|
'toolOutputFormat',
|
|
22
23
|
];
|
|
23
24
|
const ACCEPTED_ARGS = [...PUBLIC_ARGS, ...HIDDEN_ARGS];
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'products.read',
|
|
29
|
-
'products.create',
|
|
30
|
-
'products.update',
|
|
31
|
-
'project.read',
|
|
32
|
-
'product-search.read',
|
|
33
|
-
'category.read',
|
|
34
|
-
'category.create',
|
|
35
|
-
'category.update',
|
|
36
|
-
'channel.read',
|
|
37
|
-
'channel.create',
|
|
38
|
-
'channel.update',
|
|
39
|
-
'product-selection.read',
|
|
40
|
-
'product-selection.create',
|
|
41
|
-
'product-selection.update',
|
|
42
|
-
'order.read',
|
|
43
|
-
'order.create',
|
|
44
|
-
'order.update',
|
|
45
|
-
'cart.read',
|
|
46
|
-
'cart.create',
|
|
47
|
-
'cart.update',
|
|
48
|
-
'customer.create',
|
|
49
|
-
'customer.read',
|
|
50
|
-
'customer.update',
|
|
51
|
-
'customer-group.read',
|
|
52
|
-
'customer-group.create',
|
|
53
|
-
'customer-group.update',
|
|
54
|
-
'quote.read',
|
|
55
|
-
'quote.create',
|
|
56
|
-
'quote.update',
|
|
57
|
-
'quote-request.read',
|
|
58
|
-
'quote-request.create',
|
|
59
|
-
'quote-request.update',
|
|
60
|
-
'staged-quote.read',
|
|
61
|
-
'staged-quote.create',
|
|
62
|
-
'staged-quote.update',
|
|
63
|
-
'standalone-price.read',
|
|
64
|
-
'standalone-price.create',
|
|
65
|
-
'standalone-price.update',
|
|
66
|
-
'product-discount.read',
|
|
67
|
-
'product-discount.create',
|
|
68
|
-
'product-discount.update',
|
|
69
|
-
'cart-discount.read',
|
|
70
|
-
'cart-discount.create',
|
|
71
|
-
'cart-discount.update',
|
|
72
|
-
'discount-code.read',
|
|
73
|
-
'discount-code.create',
|
|
74
|
-
'discount-code.update',
|
|
75
|
-
'product-type.read',
|
|
76
|
-
'product-type.create',
|
|
77
|
-
'product-type.update',
|
|
78
|
-
'bulk.create',
|
|
79
|
-
'bulk.update',
|
|
80
|
-
'inventory.read',
|
|
81
|
-
'inventory.create',
|
|
82
|
-
'inventory.update',
|
|
83
|
-
'store.read',
|
|
84
|
-
'store.create',
|
|
85
|
-
'store.update',
|
|
86
|
-
'review.read',
|
|
87
|
-
'review.create',
|
|
88
|
-
'review.update',
|
|
89
|
-
'tax-category.read',
|
|
90
|
-
'tax-category.create',
|
|
91
|
-
'tax-category.update',
|
|
92
|
-
'shipping-methods.read',
|
|
93
|
-
'shipping-methods.create',
|
|
94
|
-
'shipping-methods.update',
|
|
95
|
-
'payments.read',
|
|
96
|
-
'payments.create',
|
|
97
|
-
'payments.update',
|
|
98
|
-
'zone.read',
|
|
99
|
-
'zone.create',
|
|
100
|
-
'zone.update',
|
|
101
|
-
'product-tailoring.read',
|
|
102
|
-
'product-tailoring.create',
|
|
103
|
-
'product-tailoring.update',
|
|
104
|
-
'payment-methods.read',
|
|
105
|
-
'payment-methods.create',
|
|
106
|
-
'payment-methods.update',
|
|
107
|
-
'recurring-orders.read',
|
|
108
|
-
'recurring-orders.create',
|
|
109
|
-
'recurring-orders.update',
|
|
110
|
-
'shopping-lists.read',
|
|
111
|
-
'shopping-lists.create',
|
|
112
|
-
'shopping-lists.update',
|
|
113
|
-
'extensions.read',
|
|
114
|
-
'extensions.create',
|
|
115
|
-
'extensions.update',
|
|
116
|
-
'subscriptions.read',
|
|
117
|
-
'subscriptions.create',
|
|
118
|
-
'subscriptions.update',
|
|
119
|
-
'custom-objects.read',
|
|
120
|
-
'custom-objects.create',
|
|
121
|
-
'custom-objects.update',
|
|
122
|
-
'types.read',
|
|
123
|
-
'types.create',
|
|
124
|
-
'types.update',
|
|
125
|
-
'payment-intents.update',
|
|
126
|
-
'transactions.read',
|
|
127
|
-
'transactions.create',
|
|
128
|
-
];
|
|
129
|
-
// eslint-disable-next-line complexity
|
|
25
|
+
var modelcontextprotocol_2 = require("@commercetools/commerce-agent/modelcontextprotocol");
|
|
26
|
+
Object.defineProperty(exports, "ACCEPTED_TOOLS", { enumerable: true, get: function () { return modelcontextprotocol_2.ACCEPTED_TOOLS; } });
|
|
27
|
+
Object.defineProperty(exports, "applyResolvedToolsToConfiguration", { enumerable: true, get: function () { return modelcontextprotocol_2.applyResolvedToolsToConfiguration; } });
|
|
28
|
+
Object.defineProperty(exports, "resolveToolsForConfiguration", { enumerable: true, get: function () { return modelcontextprotocol_2.resolveToolsForConfiguration; } });
|
|
130
29
|
function parseArgs(args) {
|
|
131
30
|
const options = {};
|
|
132
31
|
const env = {};
|
|
133
|
-
// eslint-disable-next-line complexity
|
|
134
32
|
args.forEach((arg) => {
|
|
135
33
|
if (arg.startsWith('--')) {
|
|
136
34
|
const [key, value] = arg.slice(2).split('=');
|
|
137
35
|
if (key == 'tools') {
|
|
138
|
-
options.tools = value.split(',');
|
|
36
|
+
options.tools = value.replace(/\s+/g, '').split(',');
|
|
139
37
|
}
|
|
140
38
|
else if (key == 'authType') {
|
|
141
39
|
env.authType = value;
|
|
@@ -181,6 +79,9 @@ function parseArgs(args) {
|
|
|
181
79
|
options.toolOutputFormat = value;
|
|
182
80
|
}
|
|
183
81
|
}
|
|
82
|
+
else if (key == 'fieldFiltering') {
|
|
83
|
+
options.fieldFiltering = tryParseFieldFiltering(value);
|
|
84
|
+
}
|
|
184
85
|
else if (key == 'logging') {
|
|
185
86
|
options.logging = value == 'true';
|
|
186
87
|
}
|
|
@@ -210,8 +111,8 @@ function parseArgs(args) {
|
|
|
210
111
|
if (tool == 'all' || tool == 'all.read') {
|
|
211
112
|
return;
|
|
212
113
|
}
|
|
213
|
-
if (!
|
|
214
|
-
throw new Error(`Invalid tool: ${tool}. Accepted tools are: ${
|
|
114
|
+
if (!modelcontextprotocol_1.ACCEPTED_TOOLS.includes(tool.trim())) {
|
|
115
|
+
throw new Error(`Invalid tool: ${tool}. Accepted tools are: ${modelcontextprotocol_1.ACCEPTED_TOOLS.join(', ')}`);
|
|
215
116
|
}
|
|
216
117
|
});
|
|
217
118
|
// Check for commercetools env vars
|
|
@@ -267,6 +168,71 @@ function parseArgs(args) {
|
|
|
267
168
|
}
|
|
268
169
|
return { options, env };
|
|
269
170
|
}
|
|
171
|
+
function tryParseFieldFiltering(fieldFilteringString) {
|
|
172
|
+
let fieldFilteringConfig;
|
|
173
|
+
try {
|
|
174
|
+
fieldFilteringConfig = JSON.parse(fieldFilteringString);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
throw new Error(`Invalid argument: fieldFiltering. Error parsing JSON: ${error}`);
|
|
178
|
+
}
|
|
179
|
+
if (typeof fieldFilteringConfig !== 'object' ||
|
|
180
|
+
fieldFilteringConfig === null ||
|
|
181
|
+
Array.isArray(fieldFilteringConfig)) {
|
|
182
|
+
throw new Error(`Invalid argument: fieldFiltering. Value must be a stringified object of type FieldFilteringManagerConfig.`);
|
|
183
|
+
}
|
|
184
|
+
if (fieldFilteringConfig.paths) {
|
|
185
|
+
if (!isFieldFilteringRuleArray(fieldFilteringConfig.paths)) {
|
|
186
|
+
throw new Error(`Invalid argument: fieldFiltering.paths. Value must be a stringified array of type { type: "filter" | "redact", value: string, value: boolean }`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (fieldFilteringConfig.properties) {
|
|
190
|
+
if (!isFieldFilteringRuleArray(fieldFilteringConfig.properties)) {
|
|
191
|
+
throw new Error(`Invalid argument: fieldFiltering.properties. Value must be a stringified array of type { type: "filter" | "redact", value: string, value: boolean }`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (fieldFilteringConfig.whitelistPaths) {
|
|
195
|
+
if (!isFieldFilteringRuleArray(
|
|
196
|
+
// add value property to whitelistPaths depsite irrelevance to reuse isFieldFilteringRuleArray logic
|
|
197
|
+
fieldFilteringConfig.whitelistPaths.map((path) => ({
|
|
198
|
+
...path,
|
|
199
|
+
value: 'filter',
|
|
200
|
+
})))) {
|
|
201
|
+
throw new Error(`Invalid argument: fieldFiltering.whitelistPaths. Value must be a stringified array of type { value: string, value: boolean }`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (fieldFilteringConfig.includes) {
|
|
205
|
+
if (!isFieldFilteringRuleArray(fieldFilteringConfig.includes)) {
|
|
206
|
+
throw new Error(`Invalid argument: fieldFiltering.includes. Value must be a stringified array of type { type: "filter" | "redact", value: string, value: boolean }`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (fieldFilteringConfig.jsonRedactionText) {
|
|
210
|
+
if (typeof fieldFilteringConfig.jsonRedactionText !== 'string') {
|
|
211
|
+
throw new Error(`Invalid argument: fieldFiltering.jsonRedactionText. Value must be of type string`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (fieldFilteringConfig.urlRedactionText) {
|
|
215
|
+
if (typeof fieldFilteringConfig.urlRedactionText !== 'string') {
|
|
216
|
+
throw new Error(`Invalid argument: fieldFiltering.urlRedactionText. Value must be of type string`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return fieldFilteringConfig;
|
|
220
|
+
}
|
|
221
|
+
function isFieldFilteringRuleArray(possibleRules) {
|
|
222
|
+
if (!Array.isArray(possibleRules)) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
return (possibleRules
|
|
226
|
+
.map((rule) => isFieldFilteringRule(rule))
|
|
227
|
+
.findIndex((bool) => bool === false) === -1);
|
|
228
|
+
}
|
|
229
|
+
function isFieldFilteringRule(possibleRule) {
|
|
230
|
+
const rule = possibleRule;
|
|
231
|
+
return (!!rule.value &&
|
|
232
|
+
typeof rule.value === 'string' &&
|
|
233
|
+
typeof rule.caseSensitive === 'boolean' &&
|
|
234
|
+
(rule.type === 'filter' || rule.type === 'redact'));
|
|
235
|
+
}
|
|
270
236
|
function createAuthConfig(env) {
|
|
271
237
|
const baseConfig = {
|
|
272
238
|
authUrl: env.authUrl,
|
|
@@ -315,46 +281,13 @@ async function main() {
|
|
|
315
281
|
storeKey: options.storeKey,
|
|
316
282
|
businessUnitKey: options.businessUnitKey,
|
|
317
283
|
logging: options.logging,
|
|
284
|
+
fieldFiltering: options.fieldFiltering
|
|
285
|
+
? new processors_1.FieldFilteringHandler(options.fieldFiltering)
|
|
286
|
+
: undefined,
|
|
318
287
|
},
|
|
319
288
|
};
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (!configuration.actions) {
|
|
323
|
-
configuration.actions = {};
|
|
324
|
-
}
|
|
325
|
-
const [namespace, action] = tool.split('.');
|
|
326
|
-
configuration.actions[namespace] = {
|
|
327
|
-
...configuration.actions[namespace],
|
|
328
|
-
[action]: true,
|
|
329
|
-
};
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
else if (selectedTools[0] === 'all.read') {
|
|
333
|
-
exports.ACCEPTED_TOOLS.forEach((tool) => {
|
|
334
|
-
if (!configuration.actions) {
|
|
335
|
-
configuration.actions = {};
|
|
336
|
-
}
|
|
337
|
-
const [namespace, action] = tool.split('.');
|
|
338
|
-
if (action === 'read') {
|
|
339
|
-
configuration.actions[namespace] = {
|
|
340
|
-
...configuration.actions[namespace],
|
|
341
|
-
[action]: true,
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
selectedTools.forEach((tool) => {
|
|
348
|
-
if (!configuration.actions) {
|
|
349
|
-
configuration.actions = {};
|
|
350
|
-
}
|
|
351
|
-
const [namespace, action] = tool.split('.');
|
|
352
|
-
configuration.actions[namespace] = {
|
|
353
|
-
...(configuration.actions[namespace] || {}),
|
|
354
|
-
[action]: true,
|
|
355
|
-
};
|
|
356
|
-
});
|
|
357
|
-
}
|
|
289
|
+
const resolution = (0, modelcontextprotocol_1.resolveToolsForConfiguration)(selectedTools, Boolean(options.isAdmin));
|
|
290
|
+
(0, modelcontextprotocol_1.applyResolvedToolsToConfiguration)(configuration, resolution);
|
|
358
291
|
const authConfig = createAuthConfig(env);
|
|
359
292
|
// eslint-disable-next-line require-await
|
|
360
293
|
async function getServer() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools/commerce-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"mcpName": "io.github.commercetools/commerce-mcp",
|
|
5
5
|
"homepage": "https://github.com/commercetools/commerce-mcp",
|
|
6
6
|
"description": "A command line tool for setting up commercetools MCP server",
|
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
23
23
|
"colors": "^1.4.0",
|
|
24
24
|
"dotenv": "^17.2.1",
|
|
25
25
|
"mcp-remote": "^0.1.18",
|
|
26
|
-
"@commercetools/commerce-agent": "
|
|
26
|
+
"@commercetools/commerce-agent": "2.0.0",
|
|
27
|
+
"@commercetools/processors": "0.0.0"
|
|
27
28
|
},
|
|
28
29
|
"keywords": [
|
|
29
30
|
"mcp",
|
|
@@ -55,7 +56,7 @@
|
|
|
55
56
|
},
|
|
56
57
|
"scripts": {
|
|
57
58
|
"preinstall": "npx only-allow pnpm",
|
|
58
|
-
"prebuild": "pnpm --filter @commercetools/commerce-agent run build",
|
|
59
|
+
"prebuild": "pnpm --filter @commercetools/processors run build && pnpm --filter @commercetools/commerce-agent run build",
|
|
59
60
|
"dev": "concurrently -n BUILD,SERVER -c magenta,cyan \"pnpm dev:build\" \"pnpm dev:run\"",
|
|
60
61
|
"dev:build": "tsup --env.NODE_ENV dev",
|
|
61
62
|
"dev:run": "nodemon dist/index.js --watch",
|