@anton.andrusenko/shopify-mcp-admin 1.0.1 → 1.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 +2 -2
- package/dist/index.js +64 -9
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ Tokens are automatically refreshed every 24 hours.
|
|
|
108
108
|
| `PORT` | No | `3000` | HTTP server port (when `TRANSPORT=http`) |
|
|
109
109
|
| `DEBUG` | No | — | Enable debug logging (`1` or `true`) |
|
|
110
110
|
| `LOG_LEVEL` | No | `info` | Log level: `debug`, `info`, `warn`, `error` |
|
|
111
|
-
| `SHOPIFY_MCP_LAZY_LOADING` | No | `
|
|
111
|
+
| `SHOPIFY_MCP_LAZY_LOADING` | No | `false` | Enable modular lazy loading (set to `true` for on-demand module loading) |
|
|
112
112
|
| `SHOPIFY_MCP_ROLE` | No | — | Role preset for automatic module loading (see [Role Presets](#-role-presets)) |
|
|
113
113
|
|
|
114
114
|
**⚡ Authentication:** Provide EITHER `SHOPIFY_ACCESS_TOKEN` (legacy) OR both `SHOPIFY_CLIENT_ID` and `SHOPIFY_CLIENT_SECRET` (Dev Dashboard).
|
|
@@ -832,7 +832,7 @@ export SHOPIFY_MCP_LAZY_LOADING=false
|
|
|
832
832
|
|-------|----------|
|
|
833
833
|
| Tool not found after upgrade | Load the appropriate module: `load-module(module: "collections")` |
|
|
834
834
|
| "Module not found" error | Use `list-modules` to see valid module names |
|
|
835
|
-
| Want
|
|
835
|
+
| Want modular lazy loading | Set `SHOPIFY_MCP_LAZY_LOADING=true` (requires MCP client that supports tool list refresh) |
|
|
836
836
|
| AI agent loading too many modules | Use a role preset instead of on-demand loading |
|
|
837
837
|
|
|
838
838
|
---
|
package/dist/index.js
CHANGED
|
@@ -27,9 +27,11 @@ var configSchema = z.object({
|
|
|
27
27
|
// Default: 5 minutes (300000ms) - configurable for performance tuning
|
|
28
28
|
STORE_INFO_CACHE_TTL_MS: z.string().optional().default("300000").transform(Number).describe("Cache TTL for store info in milliseconds (default: 5 minutes)"),
|
|
29
29
|
// Lazy loading configuration (Epic 12)
|
|
30
|
-
// Default:
|
|
31
|
-
//
|
|
32
|
-
|
|
30
|
+
// Default: false - loads all tools at startup for maximum compatibility
|
|
31
|
+
// Note: Claude Desktop doesn't support dynamic tool refresh via notifications,
|
|
32
|
+
// so lazy loading is disabled by default. Set to 'true' for clients that
|
|
33
|
+
// properly handle notifications/tools/list_changed.
|
|
34
|
+
SHOPIFY_MCP_LAZY_LOADING: z.string().optional().default("false").transform((val) => val === "true" || val === "1").describe("Enable lazy loading of tools via modules (default: false)"),
|
|
33
35
|
// Role preset configuration (Story 12.3: Progressive Loading)
|
|
34
36
|
// Automatically loads appropriate modules at startup based on role
|
|
35
37
|
// Valid roles: inventory-manager, product-manager, content-manager,
|
|
@@ -3199,20 +3201,42 @@ function getRegisteredTools() {
|
|
|
3199
3201
|
annotations: tool.annotations
|
|
3200
3202
|
}));
|
|
3201
3203
|
}
|
|
3204
|
+
function getAllRegisteredToolNames() {
|
|
3205
|
+
return Array.from(registeredTools.keys());
|
|
3206
|
+
}
|
|
3202
3207
|
function getToolByName(name) {
|
|
3203
3208
|
return registeredTools.get(name);
|
|
3204
3209
|
}
|
|
3205
3210
|
function getToolNames() {
|
|
3206
3211
|
return Array.from(registeredTools.keys());
|
|
3207
3212
|
}
|
|
3213
|
+
var toolListChangedCallback = null;
|
|
3214
|
+
function setToolListChangedCallback(callback) {
|
|
3215
|
+
toolListChangedCallback = callback;
|
|
3216
|
+
log.debug("Tool list changed callback registered");
|
|
3217
|
+
}
|
|
3218
|
+
function notifyToolListChanged() {
|
|
3219
|
+
if (toolListChangedCallback) {
|
|
3220
|
+
log.info("\u{1F514} SENDING tools/list_changed notification to client");
|
|
3221
|
+
toolListChangedCallback();
|
|
3222
|
+
} else {
|
|
3223
|
+
log.warn("\u26A0\uFE0F notifyToolListChanged called but no callback registered!");
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3208
3226
|
function enableTool(name) {
|
|
3209
3227
|
const tool = registeredTools.get(name);
|
|
3210
3228
|
if (!tool) {
|
|
3211
3229
|
log.debug(`Cannot enable tool: ${name} not found`);
|
|
3212
3230
|
return false;
|
|
3213
3231
|
}
|
|
3232
|
+
const previousState = toolEnabledState.get(name);
|
|
3233
|
+
const wasEnabled = previousState ?? true;
|
|
3214
3234
|
toolEnabledState.set(name, true);
|
|
3215
|
-
log.debug(`Tool enabled: ${name}`);
|
|
3235
|
+
log.debug(`Tool enabled: ${name} (was: ${previousState}, wasEnabled: ${wasEnabled})`);
|
|
3236
|
+
if (!wasEnabled) {
|
|
3237
|
+
log.info(`\u{1F4E2} Tool ${name} state changed from disabled to enabled, triggering notification`);
|
|
3238
|
+
notifyToolListChanged();
|
|
3239
|
+
}
|
|
3216
3240
|
return true;
|
|
3217
3241
|
}
|
|
3218
3242
|
function disableTool(name) {
|
|
@@ -3221,8 +3245,12 @@ function disableTool(name) {
|
|
|
3221
3245
|
log.debug(`Cannot disable tool: ${name} not found`);
|
|
3222
3246
|
return false;
|
|
3223
3247
|
}
|
|
3248
|
+
const wasEnabled = toolEnabledState.get(name) ?? true;
|
|
3224
3249
|
toolEnabledState.set(name, false);
|
|
3225
3250
|
log.debug(`Tool disabled: ${name}`);
|
|
3251
|
+
if (wasEnabled) {
|
|
3252
|
+
notifyToolListChanged();
|
|
3253
|
+
}
|
|
3226
3254
|
return true;
|
|
3227
3255
|
}
|
|
3228
3256
|
function isToolEnabled(name) {
|
|
@@ -14185,6 +14213,10 @@ function getSuggestionsForTool(toolName) {
|
|
|
14185
14213
|
|
|
14186
14214
|
// src/tools/index.ts
|
|
14187
14215
|
function setupToolHandlers(server) {
|
|
14216
|
+
setToolListChangedCallback(() => {
|
|
14217
|
+
server.sendToolListChanged();
|
|
14218
|
+
log.debug("Sent tools/list_changed notification to clients");
|
|
14219
|
+
});
|
|
14188
14220
|
server.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
14189
14221
|
const tools = getRegisteredTools();
|
|
14190
14222
|
log.debug(`tools/list returning ${tools.length} tools`);
|
|
@@ -14208,16 +14240,35 @@ function setupToolHandlers(server) {
|
|
|
14208
14240
|
}
|
|
14209
14241
|
const tool = getToolByName(name);
|
|
14210
14242
|
if (!tool) {
|
|
14211
|
-
const
|
|
14212
|
-
const
|
|
14213
|
-
|
|
14243
|
+
const allTools = getAllRegisteredToolNames();
|
|
14244
|
+
const enabledTools = getRegisteredTools();
|
|
14245
|
+
const totalRegistered = allTools.length;
|
|
14246
|
+
const totalEnabled = enabledTools.length;
|
|
14247
|
+
const similarTools = allTools.filter(
|
|
14248
|
+
(t) => t.toLowerCase().includes(name.toLowerCase()) || name.toLowerCase().includes(t.toLowerCase())
|
|
14249
|
+
);
|
|
14250
|
+
let diagnosticInfo = `
|
|
14251
|
+
|
|
14252
|
+
Diagnostics:
|
|
14253
|
+
- Total tools registered: ${totalRegistered}
|
|
14254
|
+
- Tools currently enabled: ${totalEnabled}`;
|
|
14255
|
+
if (similarTools.length > 0) {
|
|
14256
|
+
diagnosticInfo += `
|
|
14257
|
+
- Similar tool names found: ${similarTools.join(", ")}`;
|
|
14258
|
+
}
|
|
14259
|
+
const toolList = enabledTools.length > 0 ? `
|
|
14260
|
+
|
|
14261
|
+
Enabled tools: ${enabledTools.map((t) => t.name).join(", ")}` : "\n\nNo tools are currently enabled. Try restarting your MCP client.";
|
|
14262
|
+
log.warn(
|
|
14263
|
+
`Tool not found: ${name}${name !== rawName ? ` (received as "${rawName}")` : ""}. Registered: ${totalRegistered}, Enabled: ${totalEnabled}`
|
|
14264
|
+
);
|
|
14214
14265
|
return {
|
|
14215
14266
|
content: [
|
|
14216
14267
|
{
|
|
14217
14268
|
type: "text",
|
|
14218
|
-
text: `Error: Tool "${name}" not found${name !== rawName ? ` (received as "${rawName}")` : ""}
|
|
14269
|
+
text: `Error: Tool "${name}" not found${name !== rawName ? ` (received as "${rawName}")` : ""}.${diagnosticInfo}
|
|
14219
14270
|
|
|
14220
|
-
Suggestion: Use tools/list to
|
|
14271
|
+
Suggestion: Use tools/list to refresh available tools. If this tool should exist, try restarting your MCP client (Claude Desktop).${toolList}`
|
|
14221
14272
|
}
|
|
14222
14273
|
],
|
|
14223
14274
|
isError: true
|
|
@@ -14375,8 +14426,12 @@ function registerAllTools(server) {
|
|
|
14375
14426
|
`Lazy loading enabled: ${enabledCount} core tools active, ${totalToolCount - enabledCount} tools available via modules`
|
|
14376
14427
|
);
|
|
14377
14428
|
}
|
|
14429
|
+
log.debug(
|
|
14430
|
+
`Enabled tools: ${getRegisteredTools().map((t) => t.name).join(", ")}`
|
|
14431
|
+
);
|
|
14378
14432
|
} else {
|
|
14379
14433
|
log.info(`Lazy loading disabled (legacy mode): ${totalToolCount} tools registered`);
|
|
14434
|
+
log.debug(`All tools: ${getToolNames().join(", ")}`);
|
|
14380
14435
|
}
|
|
14381
14436
|
}
|
|
14382
14437
|
function applyLazyLoading() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anton.andrusenko/shopify-mcp-admin",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "MCP server for Shopify Admin API - enables AI agents to manage Shopify stores with 71 tools for products, inventory, collections, content, SEO, metafields, markets & translations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
25
25
|
"inspect:dev": "npx @modelcontextprotocol/inspector npx tsx src/index.ts",
|
|
26
26
|
"inspect:config": "npx @modelcontextprotocol/inspector --config mcp-inspector.json",
|
|
27
|
+
"fast-agent": "fast-agent",
|
|
28
|
+
"fast-agent:check": "fast-agent check",
|
|
29
|
+
"fast-agent:chat": "fast-agent go --servers shopify-mcp-admin",
|
|
30
|
+
"fast-agent:dev": "fast-agent go --servers shopify-mcp-admin-dev",
|
|
27
31
|
"ci": "npm run lint && npm run typecheck && npm run test && npm run build",
|
|
28
32
|
"version:patch": "npm version patch --no-git-tag-version",
|
|
29
33
|
"version:minor": "npm version minor --no-git-tag-version",
|