vendure-mcp-graphql 1.4.0 → 1.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/dist/index.js +44 -6
- package/dist/src/client.d.ts +11 -4
- package/dist/src/client.js +35 -10
- package/dist/src/tools/graphql-operations.d.ts +6 -6
- package/dist/src/tools/graphql-operations.js +14 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -66,6 +66,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
66
66
|
properties: {
|
|
67
67
|
query: { type: "string", description: "The GraphQL query string" },
|
|
68
68
|
variables: { type: "object", description: "Optional variables" },
|
|
69
|
+
channelToken: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Optional channel token to scope the request to a specific channel. Requires CHANNEL_API_KEY_MAP to be configured with a key for this channel.",
|
|
72
|
+
},
|
|
69
73
|
},
|
|
70
74
|
required: ["query"],
|
|
71
75
|
},
|
|
@@ -81,6 +85,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
81
85
|
description: "The GraphQL mutation string",
|
|
82
86
|
},
|
|
83
87
|
variables: { type: "object", description: "Optional variables" },
|
|
88
|
+
channelToken: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "Optional channel token to scope the request to a specific channel. Requires CHANNEL_API_KEY_MAP to be configured with a key for this channel.",
|
|
91
|
+
},
|
|
84
92
|
},
|
|
85
93
|
required: ["mutation"],
|
|
86
94
|
},
|
|
@@ -114,6 +122,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
114
122
|
type: "number",
|
|
115
123
|
description: "Max number of concurrent mutations. Default: 5.",
|
|
116
124
|
},
|
|
125
|
+
channelToken: {
|
|
126
|
+
type: "string",
|
|
127
|
+
description: "Optional channel token to set channel context (e.g., 'default-channel', 'test-channel')",
|
|
128
|
+
},
|
|
117
129
|
},
|
|
118
130
|
required: ["mutation", "ids"],
|
|
119
131
|
},
|
|
@@ -136,6 +148,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
136
148
|
properties: {
|
|
137
149
|
query: { type: "string", description: "The GraphQL query string" },
|
|
138
150
|
variables: { type: "object", description: "Optional variables" },
|
|
151
|
+
channelToken: {
|
|
152
|
+
type: "string",
|
|
153
|
+
description: "Optional channel token to scope the request to a specific channel. Requires CHANNEL_API_KEY_MAP to be configured with a key for this channel.",
|
|
154
|
+
},
|
|
139
155
|
},
|
|
140
156
|
required: ["query"],
|
|
141
157
|
},
|
|
@@ -151,6 +167,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
151
167
|
description: "The GraphQL mutation string",
|
|
152
168
|
},
|
|
153
169
|
variables: { type: "object", description: "Optional variables" },
|
|
170
|
+
channelToken: {
|
|
171
|
+
type: "string",
|
|
172
|
+
description: "Optional channel token to scope the request to a specific channel. Requires CHANNEL_API_KEY_MAP to be configured with a key for this channel.",
|
|
173
|
+
},
|
|
154
174
|
},
|
|
155
175
|
required: ["mutation"],
|
|
156
176
|
},
|
|
@@ -184,6 +204,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
184
204
|
type: "number",
|
|
185
205
|
description: "Max number of concurrent mutations. Default: 5.",
|
|
186
206
|
},
|
|
207
|
+
channelToken: {
|
|
208
|
+
type: "string",
|
|
209
|
+
description: "Optional channel token to scope the request to a specific channel. Requires CHANNEL_API_KEY_MAP to be configured with a key for this channel.",
|
|
210
|
+
},
|
|
187
211
|
},
|
|
188
212
|
required: ["mutation", "ids"],
|
|
189
213
|
},
|
|
@@ -229,7 +253,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
229
253
|
content: [
|
|
230
254
|
{
|
|
231
255
|
type: "text",
|
|
232
|
-
text: JSON.stringify(await adminQuery(args?.query, args?.variables), null, 2),
|
|
256
|
+
text: JSON.stringify(await adminQuery(args?.query, args?.variables, args?.channelToken), null, 2),
|
|
233
257
|
},
|
|
234
258
|
],
|
|
235
259
|
};
|
|
@@ -238,7 +262,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
238
262
|
content: [
|
|
239
263
|
{
|
|
240
264
|
type: "text",
|
|
241
|
-
text: JSON.stringify(await adminMutation(args?.mutation, args?.variables), null, 2),
|
|
265
|
+
text: JSON.stringify(await adminMutation(args?.mutation, args?.variables, args?.channelToken), null, 2),
|
|
242
266
|
},
|
|
243
267
|
],
|
|
244
268
|
};
|
|
@@ -247,7 +271,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
247
271
|
content: [
|
|
248
272
|
{
|
|
249
273
|
type: "text",
|
|
250
|
-
text: JSON.stringify(await adminBatchMutation(args?.mutation, args?.ids, args?.variableName || "id", args?.extraVariables, args?.concurrency || 5), null, 2),
|
|
274
|
+
text: JSON.stringify(await adminBatchMutation(args?.mutation, args?.ids, args?.variableName || "id", args?.extraVariables, args?.concurrency || 5, args?.channelToken), null, 2),
|
|
251
275
|
},
|
|
252
276
|
],
|
|
253
277
|
};
|
|
@@ -274,7 +298,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
274
298
|
content: [
|
|
275
299
|
{
|
|
276
300
|
type: "text",
|
|
277
|
-
text: JSON.stringify(await shopQuery(args?.query, args?.variables), null, 2),
|
|
301
|
+
text: JSON.stringify(await shopQuery(args?.query, args?.variables, args?.channelToken), null, 2),
|
|
278
302
|
},
|
|
279
303
|
],
|
|
280
304
|
};
|
|
@@ -283,7 +307,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
283
307
|
content: [
|
|
284
308
|
{
|
|
285
309
|
type: "text",
|
|
286
|
-
text: JSON.stringify(await shopMutation(args?.mutation, args?.variables), null, 2),
|
|
310
|
+
text: JSON.stringify(await shopMutation(args?.mutation, args?.variables, args?.channelToken), null, 2),
|
|
287
311
|
},
|
|
288
312
|
],
|
|
289
313
|
};
|
|
@@ -292,7 +316,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
292
316
|
content: [
|
|
293
317
|
{
|
|
294
318
|
type: "text",
|
|
295
|
-
text: JSON.stringify(await shopBatchMutation(args?.mutation, args?.ids, args?.variableName || "id", args?.extraVariables, args?.concurrency || 5), null, 2),
|
|
319
|
+
text: JSON.stringify(await shopBatchMutation(args?.mutation, args?.ids, args?.variableName || "id", args?.extraVariables, args?.concurrency || 5, args?.channelToken), null, 2),
|
|
296
320
|
},
|
|
297
321
|
],
|
|
298
322
|
};
|
|
@@ -346,6 +370,20 @@ async function main() {
|
|
|
346
370
|
console.error(`API Key: ${process.env.VENDURE_API_KEY ? "Present" : "Missing"}`);
|
|
347
371
|
console.error(`Admin URL: ${process.env.ADMIN_API_URL || "default"}`);
|
|
348
372
|
console.error(`Shop URL: ${process.env.SHOP_API_URL || "default"}`);
|
|
373
|
+
// Log available channel API key mappings
|
|
374
|
+
const raw = process.env.CHANNEL_API_KEY_MAP;
|
|
375
|
+
if (raw) {
|
|
376
|
+
try {
|
|
377
|
+
const map = JSON.parse(raw);
|
|
378
|
+
const channels = Object.keys(map);
|
|
379
|
+
if (channels.length > 0) {
|
|
380
|
+
console.error(`Channel API keys configured for: ${channels.join(", ")}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
console.error("Invalid CHANNEL_API_KEY_MAP environment variable");
|
|
385
|
+
}
|
|
386
|
+
}
|
|
349
387
|
}
|
|
350
388
|
main().catch((error) => {
|
|
351
389
|
console.error("Server error:", error);
|
package/dist/src/client.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GraphQL Client for Vendure API
|
|
3
|
-
* Handles authentication via API Key for both Admin and Shop APIs
|
|
3
|
+
* Handles authentication via API Key for both Admin and Shop APIs.
|
|
4
|
+
*
|
|
5
|
+
* Channel switching is done via per-channel API keys (CHANNEL_API_KEY_MAP)
|
|
6
|
+
* combined with the vendure-token header. The per-channel API key provides
|
|
7
|
+
* authentication scoped to the target channel, and the vendure-token header
|
|
8
|
+
* tells Vendure which channel context to use for the request.
|
|
9
|
+
* Both are required for proper channel switching.
|
|
4
10
|
*/
|
|
5
11
|
export interface GraphQLResponse<T = any> {
|
|
6
12
|
data?: T;
|
|
@@ -10,9 +16,10 @@ export interface GraphQLResponse<T = any> {
|
|
|
10
16
|
}>;
|
|
11
17
|
}
|
|
12
18
|
export declare class GraphQLClient {
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
private defaultApiKey;
|
|
20
|
+
private channelApiKeys;
|
|
21
|
+
constructor(defaultApiKey?: string | null, channelApiKeys?: Record<string, string>);
|
|
22
|
+
request<T = any>(url: string, queryString: string, variables?: Record<string, any>, channelToken?: string): Promise<T>;
|
|
16
23
|
}
|
|
17
24
|
export declare function getClient(): GraphQLClient;
|
|
18
25
|
export declare function getAdminUrl(): string;
|
package/dist/src/client.js
CHANGED
|
@@ -1,18 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GraphQL Client for Vendure API
|
|
3
|
-
* Handles authentication via API Key for both Admin and Shop APIs
|
|
3
|
+
* Handles authentication via API Key for both Admin and Shop APIs.
|
|
4
|
+
*
|
|
5
|
+
* Channel switching is done via per-channel API keys (CHANNEL_API_KEY_MAP)
|
|
6
|
+
* combined with the vendure-token header. The per-channel API key provides
|
|
7
|
+
* authentication scoped to the target channel, and the vendure-token header
|
|
8
|
+
* tells Vendure which channel context to use for the request.
|
|
9
|
+
* Both are required for proper channel switching.
|
|
4
10
|
*/
|
|
5
11
|
export class GraphQLClient {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
defaultApiKey;
|
|
13
|
+
channelApiKeys;
|
|
14
|
+
constructor(defaultApiKey = null, channelApiKeys = {}) {
|
|
15
|
+
this.defaultApiKey = defaultApiKey;
|
|
16
|
+
this.channelApiKeys = channelApiKeys;
|
|
9
17
|
}
|
|
10
|
-
async request(url, queryString, variables) {
|
|
18
|
+
async request(url, queryString, variables, channelToken) {
|
|
19
|
+
// Resolve API key: use channel-specific key if available, fall back to default
|
|
20
|
+
const apiKey = (channelToken && this.channelApiKeys[channelToken]) || this.defaultApiKey;
|
|
11
21
|
const headers = {
|
|
12
22
|
"Content-Type": "application/json",
|
|
13
23
|
};
|
|
14
|
-
if (
|
|
15
|
-
headers["vendure-api-key"] =
|
|
24
|
+
if (apiKey) {
|
|
25
|
+
headers["vendure-api-key"] = apiKey;
|
|
26
|
+
}
|
|
27
|
+
// Set vendure-token header when a channel token is provided and we have
|
|
28
|
+
// a mapped API key for it (ensuring the API key has access to this channel).
|
|
29
|
+
// The vendure-token header tells Vendure which channel context to use for the request.
|
|
30
|
+
if (channelToken) {
|
|
31
|
+
headers["vendure-token"] = channelToken;
|
|
16
32
|
}
|
|
17
33
|
const response = await fetch(url, {
|
|
18
34
|
method: "POST",
|
|
@@ -36,11 +52,20 @@ export class GraphQLClient {
|
|
|
36
52
|
// Singleton instance
|
|
37
53
|
let clientInstance = null;
|
|
38
54
|
export function getClient() {
|
|
39
|
-
if (clientInstance)
|
|
55
|
+
if (clientInstance)
|
|
40
56
|
return clientInstance;
|
|
57
|
+
const defaultApiKey = process.env.VENDURE_API_KEY || null;
|
|
58
|
+
let channelApiKeys = {};
|
|
59
|
+
const raw = process.env.CHANNEL_API_KEY_MAP;
|
|
60
|
+
if (raw) {
|
|
61
|
+
try {
|
|
62
|
+
channelApiKeys = JSON.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
console.error("Invalid CHANNEL_API_KEY_MAP JSON:", e);
|
|
66
|
+
}
|
|
41
67
|
}
|
|
42
|
-
|
|
43
|
-
clientInstance = new GraphQLClient(apiKey);
|
|
68
|
+
clientInstance = new GraphQLClient(defaultApiKey, channelApiKeys);
|
|
44
69
|
return clientInstance;
|
|
45
70
|
}
|
|
46
71
|
export function getAdminUrl() {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Execute a GraphQL query on the Admin API
|
|
3
3
|
*/
|
|
4
|
-
export declare function adminQuery(queryString: string, variables?: Record<string, any
|
|
4
|
+
export declare function adminQuery(queryString: string, variables?: Record<string, any>, channelToken?: string): Promise<any>;
|
|
5
5
|
/**
|
|
6
6
|
* Execute a GraphQL mutation on the Admin API
|
|
7
7
|
*/
|
|
8
|
-
export declare function adminMutation(mutationString: string, variables?: Record<string, any
|
|
8
|
+
export declare function adminMutation(mutationString: string, variables?: Record<string, any>, channelToken?: string): Promise<any>;
|
|
9
9
|
/**
|
|
10
10
|
* Execute a GraphQL query on the Shop API
|
|
11
11
|
*/
|
|
12
|
-
export declare function shopQuery(queryString: string, variables?: Record<string, any
|
|
12
|
+
export declare function shopQuery(queryString: string, variables?: Record<string, any>, channelToken?: string): Promise<any>;
|
|
13
13
|
/**
|
|
14
14
|
* Execute a GraphQL mutation on the Shop API
|
|
15
15
|
*/
|
|
16
|
-
export declare function shopMutation(mutationString: string, variables?: Record<string, any
|
|
16
|
+
export declare function shopMutation(mutationString: string, variables?: Record<string, any>, channelToken?: string): Promise<any>;
|
|
17
17
|
/**
|
|
18
18
|
* Fetch the Admin GraphQL schema introspection
|
|
19
19
|
*/
|
|
@@ -63,9 +63,9 @@ export interface BatchResult {
|
|
|
63
63
|
* Execute a GraphQL mutation in batch for multiple IDs on the Admin API.
|
|
64
64
|
* Runs mutations concurrently with configurable concurrency.
|
|
65
65
|
*/
|
|
66
|
-
export declare function adminBatchMutation(mutationString: string, ids: string[], variableName?: string, extraVariables?: Record<string, any>, concurrency?: number): Promise<BatchResult>;
|
|
66
|
+
export declare function adminBatchMutation(mutationString: string, ids: string[], variableName?: string, extraVariables?: Record<string, any>, concurrency?: number, channelToken?: string): Promise<BatchResult>;
|
|
67
67
|
/**
|
|
68
68
|
* Execute a GraphQL mutation in batch for multiple IDs on the Shop API.
|
|
69
69
|
* Runs mutations concurrently with configurable concurrency.
|
|
70
70
|
*/
|
|
71
|
-
export declare function shopBatchMutation(mutationString: string, ids: string[], variableName?: string, extraVariables?: Record<string, any>, concurrency?: number): Promise<BatchResult>;
|
|
71
|
+
export declare function shopBatchMutation(mutationString: string, ids: string[], variableName?: string, extraVariables?: Record<string, any>, concurrency?: number, channelToken?: string): Promise<BatchResult>;
|
|
@@ -2,30 +2,30 @@ import { getClient, getAdminUrl, getShopUrl } from "../client.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Execute a GraphQL query on the Admin API
|
|
4
4
|
*/
|
|
5
|
-
export async function adminQuery(queryString, variables) {
|
|
5
|
+
export async function adminQuery(queryString, variables, channelToken) {
|
|
6
6
|
const client = getClient();
|
|
7
|
-
return client.request(getAdminUrl(), queryString, variables);
|
|
7
|
+
return client.request(getAdminUrl(), queryString, variables, channelToken);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Execute a GraphQL mutation on the Admin API
|
|
11
11
|
*/
|
|
12
|
-
export async function adminMutation(mutationString, variables) {
|
|
12
|
+
export async function adminMutation(mutationString, variables, channelToken) {
|
|
13
13
|
const client = getClient();
|
|
14
|
-
return client.request(getAdminUrl(), mutationString, variables);
|
|
14
|
+
return client.request(getAdminUrl(), mutationString, variables, channelToken);
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Execute a GraphQL query on the Shop API
|
|
18
18
|
*/
|
|
19
|
-
export async function shopQuery(queryString, variables) {
|
|
19
|
+
export async function shopQuery(queryString, variables, channelToken) {
|
|
20
20
|
const client = getClient();
|
|
21
|
-
return client.request(getShopUrl(), queryString, variables);
|
|
21
|
+
return client.request(getShopUrl(), queryString, variables, channelToken);
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Execute a GraphQL mutation on the Shop API
|
|
25
25
|
*/
|
|
26
|
-
export async function shopMutation(mutationString, variables) {
|
|
26
|
+
export async function shopMutation(mutationString, variables, channelToken) {
|
|
27
27
|
const client = getClient();
|
|
28
|
-
return client.request(getShopUrl(), mutationString, variables);
|
|
28
|
+
return client.request(getShopUrl(), mutationString, variables, channelToken);
|
|
29
29
|
}
|
|
30
30
|
const introspectionQuery = `
|
|
31
31
|
query IntrospectionQuery {
|
|
@@ -497,17 +497,17 @@ export async function describeOperation(operationName, api) {
|
|
|
497
497
|
* Execute a GraphQL mutation in batch for multiple IDs on the Admin API.
|
|
498
498
|
* Runs mutations concurrently with configurable concurrency.
|
|
499
499
|
*/
|
|
500
|
-
export async function adminBatchMutation(mutationString, ids, variableName = "id", extraVariables, concurrency = 5) {
|
|
501
|
-
return executeBatch(getAdminUrl(), mutationString, ids, variableName, extraVariables, concurrency);
|
|
500
|
+
export async function adminBatchMutation(mutationString, ids, variableName = "id", extraVariables, concurrency = 5, channelToken) {
|
|
501
|
+
return executeBatch(getAdminUrl(), mutationString, ids, variableName, extraVariables, concurrency, channelToken);
|
|
502
502
|
}
|
|
503
503
|
/**
|
|
504
504
|
* Execute a GraphQL mutation in batch for multiple IDs on the Shop API.
|
|
505
505
|
* Runs mutations concurrently with configurable concurrency.
|
|
506
506
|
*/
|
|
507
|
-
export async function shopBatchMutation(mutationString, ids, variableName = "id", extraVariables, concurrency = 5) {
|
|
508
|
-
return executeBatch(getShopUrl(), mutationString, ids, variableName, extraVariables, concurrency);
|
|
507
|
+
export async function shopBatchMutation(mutationString, ids, variableName = "id", extraVariables, concurrency = 5, channelToken) {
|
|
508
|
+
return executeBatch(getShopUrl(), mutationString, ids, variableName, extraVariables, concurrency, channelToken);
|
|
509
509
|
}
|
|
510
|
-
async function executeBatch(url, mutationString, ids, variableName, extraVariables, concurrency) {
|
|
510
|
+
async function executeBatch(url, mutationString, ids, variableName, extraVariables, concurrency, channelToken) {
|
|
511
511
|
const client = getClient();
|
|
512
512
|
const results = [];
|
|
513
513
|
const queue = [...ids];
|
|
@@ -518,7 +518,7 @@ async function executeBatch(url, mutationString, ids, variableName, extraVariabl
|
|
|
518
518
|
const id = queue.shift();
|
|
519
519
|
const variables = { ...extraVariables, [variableName]: id };
|
|
520
520
|
try {
|
|
521
|
-
const data = await client.request(url, mutationString, variables);
|
|
521
|
+
const data = await client.request(url, mutationString, variables, channelToken);
|
|
522
522
|
succeeded++;
|
|
523
523
|
results.push({ id, success: true, data });
|
|
524
524
|
}
|