@acodera/shopify-admin-mcp 1.0.0 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @acodera/shopify-admin-mcp
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#5](https://github.com/acoderacom/shopify-admin-mcp/pull/5) [`82e29cd`](https://github.com/acoderacom/shopify-admin-mcp/commit/82e29cd0bdd28a01f7f56e84da51b918f01a022f) Thanks [@acoderacom](https://github.com/acoderacom)! - Add a `discounts` toolset: list and get discounts; create amount-off (percentage or fixed, on the order or specific products/collections), free shipping, and buy X get Y discounts as codes or automatic discounts, with dates, minimums, usage limits, combinations, and customer/segment/market eligibility; activate, deactivate, and delete them; and add extra codes in bulk.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#5](https://github.com/acoderacom/shopify-admin-mcp/pull/5) [`921d690`](https://github.com/acoderacom/shopify-admin-mcp/commit/921d690e3f2cf3226e2c45c0ac69077699bdf61d) Thanks [@acoderacom](https://github.com/acoderacom)! - Document every option in the README: a flag-to-environment-variable table with defaults, complete examples using all flags and all environment variables, and which one wins when both are set.
12
+
13
+ ## 1.0.1
14
+
15
+ ### Patch Changes
16
+
17
+ - [#3](https://github.com/acoderacom/shopify-admin-mcp/pull/3) [`8aef080`](https://github.com/acoderacom/shopify-admin-mcp/commit/8aef080c6558da9bf5e672668f738f0386eb5c43) Thanks [@acoderacom](https://github.com/acoderacom)! - Document OAuth client credentials setup for Claude Code (`claude mcp add` and `.mcp.json`) and Claude Desktop, alongside the legacy access token, and show how to pass options such as `--read-only`, `--toolsets`, and `--upload-dir` as flags or environment variables.
18
+
3
19
  ## 1.0.0
4
20
 
5
21
  ### Major Changes
package/README.md CHANGED
@@ -10,7 +10,7 @@ MCP server providing full access to Shopify's Admin GraphQL API. Targets API ver
10
10
 
11
11
  - **Raw GraphQL execution** — run any query or mutation against the Admin API
12
12
  - **Live schema introspection** — search and explore the full GraphQL schema directly from your AI assistant
13
- - **50 convenience tools** — typed, no-GraphQL-needed tools for products and variants, collections, publishing, metafields and metaobjects (including definitions), customers, orders, inventory, file uploads, themes, and markets
13
+ - **59 convenience tools** — typed, no-GraphQL-needed tools for products and variants, collections, publishing, metafields and metaobjects (including definitions), customers, orders, inventory, discounts, file uploads, themes, and markets
14
14
  - **Toolsets** — register only the areas you need to keep the assistant's tool list short
15
15
  - **Read-only mode** — one flag hides every write tool and blocks mutations in raw GraphQL
16
16
  - **Tool annotations** — every tool is marked read-only, write, or destructive so MCP clients can ask before risky calls
@@ -124,6 +124,22 @@ Convenience tools are grouped into toolsets (shown in brackets), which you can s
124
124
  | `shopify_inventory_get_levels` | Get inventory levels across locations |
125
125
  | `shopify_inventory_adjust` | Adjust available quantity at a location, with a compare-and-swap check |
126
126
 
127
+ ### Discounts `[discounts]`
128
+
129
+ | Tool | Description |
130
+ |------|-------------|
131
+ | `shopify_discounts_list` | List/search code and automatic discounts with status and summary |
132
+ | `shopify_discount_get` | Get a discount with its codes and usage |
133
+ | `shopify_discount_amount_off_create` | Percentage or fixed amount off the order or specific products/collections, as a code or automatic |
134
+ | `shopify_discount_free_shipping_create` | Free shipping, optionally limited to countries or a maximum rate, as a code or automatic |
135
+ | `shopify_discount_bxgy_create` | Buy X get Y (e.g. buy 2, get 1 free), as a code or automatic |
136
+ | `shopify_discount_activate` | Start a discount now |
137
+ | `shopify_discount_deactivate` | End a discount now |
138
+ | `shopify_discount_delete` | Delete a discount |
139
+ | `shopify_discount_codes_add` | Add up to 250 extra codes to a code discount |
140
+
141
+ All create tools accept start and end dates, minimum subtotal or quantity, usage limits (codes only), which other discounts they combine with, and eligibility by customer, customer segment, or market. Percentages are given as whole numbers (`20` = 20% off).
142
+
127
143
  ### Files `[files]`
128
144
 
129
145
  | Tool | Description |
@@ -186,7 +202,7 @@ All toolsets are registered by default. To keep the assistant's tool list short,
186
202
  --toolsets products,collections,publishing,files
187
203
  ```
188
204
 
189
- Available toolsets: `products`, `collections`, `publishing`, `metafields`, `metaobjects`, `customers`, `orders`, `inventory`, `files`, `themes`, `markets`. Raw GraphQL and schema search are always available.
205
+ Available toolsets: `products`, `collections`, `publishing`, `metafields`, `metaobjects`, `customers`, `orders`, `inventory`, `discounts`, `files`, `themes`, `markets`. Raw GraphQL and schema search are always available.
190
206
 
191
207
  ## File Uploads
192
208
 
@@ -218,6 +234,7 @@ Configure these scopes on your app to enable all tools:
218
234
  | `read_customers`, `write_customers` | Customers |
219
235
  | `read_orders` | Orders (last 60 days; add `read_all_orders` for older orders) |
220
236
  | `read_inventory`, `write_inventory`, `read_locations` | Inventory |
237
+ | `read_discounts`, `write_discounts` | Discounts |
221
238
  | `read_files`, `write_files` | Files |
222
239
  | `read_themes`, `write_themes` (+ theme-code exemption for writes) | Themes |
223
240
  | `read_markets`, `write_markets` | Markets |
@@ -272,6 +289,18 @@ The store must be a `*.myshopify.com` domain, so credentials are only ever sent
272
289
 
273
290
  ## Usage with Claude Code
274
291
 
292
+ With OAuth client credentials (Dev Dashboard app):
293
+
294
+ ```bash
295
+ claude mcp add shopify \
296
+ -e SHOPIFY_STORE=mystore.myshopify.com \
297
+ -e SHOPIFY_CLIENT_ID=your_client_id \
298
+ -e SHOPIFY_CLIENT_SECRET=your_client_secret \
299
+ -- npx -y @acodera/shopify-admin-mcp
300
+ ```
301
+
302
+ With a legacy access token:
303
+
275
304
  ```bash
276
305
  claude mcp add shopify \
277
306
  -e SHOPIFY_STORE=mystore.myshopify.com \
@@ -279,7 +308,7 @@ claude mcp add shopify \
279
308
  -- npx -y @acodera/shopify-admin-mcp
280
309
  ```
281
310
 
282
- Or add it to your project's `.mcp.json`:
311
+ Or add it to your project's `.mcp.json`. Claude Code expands `${VAR}` from your shell environment, so the file can be committed without secrets. With client credentials:
283
312
 
284
313
  ```json
285
314
  {
@@ -289,18 +318,54 @@ Or add it to your project's `.mcp.json`:
289
318
  "args": ["-y", "@acodera/shopify-admin-mcp"],
290
319
  "env": {
291
320
  "SHOPIFY_STORE": "mystore.myshopify.com",
292
- "SHOPIFY_ACCESS_TOKEN": "shpat_xxxxx"
321
+ "SHOPIFY_CLIENT_ID": "${SHOPIFY_CLIENT_ID}",
322
+ "SHOPIFY_CLIENT_SECRET": "${SHOPIFY_CLIENT_SECRET}"
293
323
  }
294
324
  }
295
325
  }
296
326
  }
297
327
  ```
298
328
 
299
- Don't commit real tokens. Claude Code expands `${VAR}` in `.mcp.json`, so you can reference variables from your shell instead.
329
+ With a legacy access token:
330
+
331
+ ```json
332
+ {
333
+ "mcpServers": {
334
+ "shopify": {
335
+ "command": "npx",
336
+ "args": ["-y", "@acodera/shopify-admin-mcp"],
337
+ "env": {
338
+ "SHOPIFY_STORE": "mystore.myshopify.com",
339
+ "SHOPIFY_ACCESS_TOKEN": "${SHOPIFY_ACCESS_TOKEN}"
340
+ }
341
+ }
342
+ }
343
+ }
344
+ ```
345
+
346
+ To add options such as `--read-only` or `--toolsets`, see [Adding Options](#adding-options).
300
347
 
301
348
  ## Usage with Claude Desktop
302
349
 
303
- Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
350
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`). With client credentials:
351
+
352
+ ```json
353
+ {
354
+ "mcpServers": {
355
+ "shopify": {
356
+ "command": "npx",
357
+ "args": ["-y", "@acodera/shopify-admin-mcp"],
358
+ "env": {
359
+ "SHOPIFY_STORE": "mystore.myshopify.com",
360
+ "SHOPIFY_CLIENT_ID": "your_client_id",
361
+ "SHOPIFY_CLIENT_SECRET": "your_client_secret"
362
+ }
363
+ }
364
+ }
365
+ }
366
+ ```
367
+
368
+ With a legacy access token:
304
369
 
305
370
  ```json
306
371
  {
@@ -319,6 +384,125 @@ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_
319
384
 
320
385
  If you install the package globally (`npm install -g @acodera/shopify-admin-mcp`), you can use `"command": "shopify-admin-mcp"` with no `args`.
321
386
 
387
+ ## Adding Options
388
+
389
+ Options from the [Configuration](#configuration) table go **after the package name**, either as flags or as environment variables.
390
+
391
+ ### As flags
392
+
393
+ With `claude mcp add`, append them after the package name:
394
+
395
+ ```bash
396
+ claude mcp add shopify \
397
+ -e SHOPIFY_STORE=mystore.myshopify.com \
398
+ -e SHOPIFY_CLIENT_ID=your_client_id \
399
+ -e SHOPIFY_CLIENT_SECRET=your_client_secret \
400
+ -- npx -y @acodera/shopify-admin-mcp --toolsets products,collections,publishing,files --upload-dir /Users/you/shopify-uploads
401
+ ```
402
+
403
+ In `.mcp.json` or the Claude Desktop config, add them to `args`. Each flag and each value is its own string:
404
+
405
+ ```json
406
+ {
407
+ "mcpServers": {
408
+ "shopify": {
409
+ "command": "npx",
410
+ "args": [
411
+ "-y", "@acodera/shopify-admin-mcp",
412
+ "--toolsets", "products,collections,publishing,files",
413
+ "--upload-dir", "/Users/you/shopify-uploads"
414
+ ],
415
+ "env": {
416
+ "SHOPIFY_STORE": "mystore.myshopify.com",
417
+ "SHOPIFY_CLIENT_ID": "${SHOPIFY_CLIENT_ID}",
418
+ "SHOPIFY_CLIENT_SECRET": "${SHOPIFY_CLIENT_SECRET}"
419
+ }
420
+ }
421
+ }
422
+ }
423
+ ```
424
+
425
+ A read-only assistant for reporting:
426
+
427
+ ```json
428
+ "args": ["-y", "@acodera/shopify-admin-mcp", "--read-only", "--toolsets", "products,orders,customers"]
429
+ ```
430
+
431
+ A theme editor that may change the live theme:
432
+
433
+ ```json
434
+ "args": ["-y", "@acodera/shopify-admin-mcp", "--toolsets", "themes,files", "--allow-live-theme-writes"]
435
+ ```
436
+
437
+ Every flag at once, with client credentials:
438
+
439
+ ```json
440
+ "args": [
441
+ "-y", "@acodera/shopify-admin-mcp",
442
+ "--store", "mystore.myshopify.com",
443
+ "--client-id", "your_client_id",
444
+ "--client-secret", "your_client_secret",
445
+ "--api-version", "2026-10",
446
+ "--toolsets", "products,collections,publishing,metafields,metaobjects,customers,orders,inventory,discounts,files,themes,markets",
447
+ "--upload-dir", "/Users/you/shopify-uploads",
448
+ "--allow-live-theme-writes",
449
+ "--read-only"
450
+ ]
451
+ ```
452
+
453
+ `--read-only` hides every write tool, so in practice you wouldn't combine it with `--upload-dir` or `--allow-live-theme-writes`; they're shown together here only for the syntax.
454
+
455
+ For a legacy token, use `"--access-token", "shpat_xxxxx"` instead of `--client-id` and `--client-secret`. Prefer passing credentials through `env` instead: the server warns when secrets are passed as flags, because flags are visible to other processes on the machine.
456
+
457
+ ### As environment variables
458
+
459
+ Every flag has an environment variable, which you can put in `env` instead of `args`:
460
+
461
+ | Flag | Environment variable | Value | Default |
462
+ |------|----------------------|-------|---------|
463
+ | `--store` | `SHOPIFY_STORE` | `mystore` or `mystore.myshopify.com` | required |
464
+ | `--client-id` | `SHOPIFY_CLIENT_ID` | OAuth client ID | none |
465
+ | `--client-secret` | `SHOPIFY_CLIENT_SECRET` | OAuth client secret | none |
466
+ | `--access-token` | `SHOPIFY_ACCESS_TOKEN` | Legacy `shpat_...` token | none |
467
+ | `--api-version` | `SHOPIFY_API_VERSION` | `YYYY-MM` or `unstable` | `2026-10` |
468
+ | `--toolsets` | `SHOPIFY_TOOLSETS` | Comma-separated toolsets | all toolsets |
469
+ | `--upload-dir` | `SHOPIFY_UPLOAD_DIR` | Absolute folder path | local uploads disabled |
470
+ | `--read-only` | `SHOPIFY_READ_ONLY` | `true` or `1` turns it on | off |
471
+ | `--allow-live-theme-writes` | `SHOPIFY_ALLOW_LIVE_THEME_WRITES` | `true` or `1` turns it on | off |
472
+
473
+ Every variable at once, with client credentials:
474
+
475
+ ```json
476
+ {
477
+ "mcpServers": {
478
+ "shopify": {
479
+ "command": "npx",
480
+ "args": ["-y", "@acodera/shopify-admin-mcp"],
481
+ "env": {
482
+ "SHOPIFY_STORE": "mystore.myshopify.com",
483
+ "SHOPIFY_CLIENT_ID": "${SHOPIFY_CLIENT_ID}",
484
+ "SHOPIFY_CLIENT_SECRET": "${SHOPIFY_CLIENT_SECRET}",
485
+ "SHOPIFY_API_VERSION": "2026-10",
486
+ "SHOPIFY_TOOLSETS": "products,collections,publishing,metafields,metaobjects,customers,orders,inventory,discounts,files,themes,markets",
487
+ "SHOPIFY_UPLOAD_DIR": "/Users/you/shopify-uploads",
488
+ "SHOPIFY_READ_ONLY": "false",
489
+ "SHOPIFY_ALLOW_LIVE_THEME_WRITES": "false"
490
+ }
491
+ }
492
+ }
493
+ }
494
+ ```
495
+
496
+ For a legacy token, replace `SHOPIFY_CLIENT_ID` and `SHOPIFY_CLIENT_SECRET` with `"SHOPIFY_ACCESS_TOKEN": "${SHOPIFY_ACCESS_TOKEN}"`. The `${VAR}` references work in Claude Code's `.mcp.json`; in the Claude Desktop config, write the values directly.
497
+
498
+ If you set the same option both ways:
499
+
500
+ - For options that take a value (`--store`, credentials, `--api-version`, `--toolsets`, `--upload-dir`), the flag wins.
501
+ - For on/off options (`--read-only`, `--allow-live-theme-writes`), either one turns it on. Setting the variable to `"false"` doesn't turn off a flag that's present.
502
+ - If both an access token and client credentials are set, the access token is used.
503
+
504
+ Use an absolute path for `--upload-dir`, because MCP clients start the server from their own working directory, not your project's.
505
+
322
506
  ## Schema Exploration
323
507
 
324
508
  The server introspects Shopify's live GraphQL schema on startup, so your AI assistant can discover API capabilities in real time.
@@ -365,7 +549,7 @@ SHOPIFY_ACCESS_TOKEN=shpat_xxxxx \
365
549
  npm test
366
550
  ```
367
551
 
368
- Add `SHOPIFY_TEST_WRITES=1` to also run the write tests. They create `[MCP test]` products, variants, collections, files, metafield and metaobject definitions, customers, a duplicate of the live theme, and a draft market, run every write tool against them, and delete them afterwards. The live theme itself is only read. Only run write tests against a development store.
552
+ Add `SHOPIFY_TEST_WRITES=1` to also run the write tests. They create `[MCP test]` products, variants, collections, files, metafield and metaobject definitions, customers, a duplicate of the live theme, a draft market, and discounts scheduled a year ahead (so they never apply to real carts), run every write tool against them, and delete them afterwards. The live theme itself is only read. Only run write tests against a development store.
369
553
 
370
554
  ## Contributing and Releases
371
555
 
package/dist/server.js CHANGED
@@ -12,6 +12,7 @@ import { registerMetafieldTools } from "./tools/metafields.js";
12
12
  import { registerCustomerTools } from "./tools/customers.js";
13
13
  import { registerOrderTools } from "./tools/orders.js";
14
14
  import { registerInventoryTools } from "./tools/inventory.js";
15
+ import { registerDiscountTools } from "./tools/discounts.js";
15
16
  import { registerFileTools } from "./tools/files.js";
16
17
  import { registerThemeTools } from "./tools/themes.js";
17
18
  import { registerMarketTools } from "./tools/markets.js";
@@ -26,6 +27,7 @@ const toolsetRegistrations = {
26
27
  customers: registerCustomerTools,
27
28
  orders: registerOrderTools,
28
29
  inventory: registerInventoryTools,
30
+ discounts: registerDiscountTools,
29
31
  files: registerFileTools,
30
32
  themes: registerThemeTools,
31
33
  markets: registerMarketTools,
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,QAAQ,EAA6B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAsB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,kFAAkF;AAClF,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAW7F,MAAM,oBAAoB,GAAqC;IAC7D,QAAQ,EAAE,oBAAoB;IAC9B,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE,uBAAuB;IACnC,UAAU,EAAE,sBAAsB;IAClC,WAAW,EAAE,uBAAuB;IACpC,SAAS,EAAE,qBAAqB;IAChC,MAAM,EAAE,kBAAkB;IAC1B,SAAS,EAAE,sBAAsB;IACjC,KAAK,EAAE,iBAAiB;IACxB,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,mBAAmB;CAC7B,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,MAAqB,EACrB,WAAwB,EACxB,OAAsB;IAEtB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,mBAAmB;QACzB,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAExE,qDAAqD;IACrD,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC;QACnD,oBAAoB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,QAAQ,EAA6B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAsB,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,kFAAkF;AAClF,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAW7F,MAAM,oBAAoB,GAAqC;IAC7D,QAAQ,EAAE,oBAAoB;IAC9B,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE,uBAAuB;IACnC,UAAU,EAAE,sBAAsB;IAClC,WAAW,EAAE,uBAAuB;IACpC,SAAS,EAAE,qBAAqB;IAChC,MAAM,EAAE,kBAAkB;IAC1B,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,qBAAqB;IAChC,KAAK,EAAE,iBAAiB;IACxB,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,mBAAmB;CAC7B,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,MAAqB,EACrB,WAAwB,EACxB,OAAsB;IAEtB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,mBAAmB;QACzB,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAExE,qDAAqD;IACrD,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC;QACnD,oBAAoB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { GraphQLClient } from "../graphql/client.js";
2
+ import { type ToolRegistrar } from "./shared.js";
3
+ export declare function registerDiscountTools(server: ToolRegistrar, client: GraphQLClient): void;
@@ -0,0 +1,344 @@
1
+ import { z } from "zod";
2
+ import { DESTRUCTIVE, READ_ONLY, WRITE, pageSize, toolResult, } from "./shared.js";
3
+ const COMMON_FIELDS = "title status startsAt endsAt discountClasses combinesWith { orderDiscounts productDiscounts shippingDiscounts }";
4
+ const CODE_EXTRA = "usageLimit asyncUsageCount appliesOncePerCustomer codesCount { count } codes(first: 5) { nodes { code } }";
5
+ const CODE_FRAGMENTS = `
6
+ ... on DiscountCodeBasic { ${COMMON_FIELDS} summary ${CODE_EXTRA} }
7
+ ... on DiscountCodeBxgy { ${COMMON_FIELDS} summary ${CODE_EXTRA} }
8
+ ... on DiscountCodeFreeShipping { ${COMMON_FIELDS} summary ${CODE_EXTRA} }
9
+ ... on DiscountCodeApp { ${COMMON_FIELDS} ${CODE_EXTRA} }
10
+ `;
11
+ const AUTOMATIC_FRAGMENTS = `
12
+ ... on DiscountAutomaticBasic { ${COMMON_FIELDS} summary }
13
+ ... on DiscountAutomaticBxgy { ${COMMON_FIELDS} summary }
14
+ ... on DiscountAutomaticFreeShipping { ${COMMON_FIELDS} summary }
15
+ ... on DiscountAutomaticApp { ${COMMON_FIELDS} }
16
+ `;
17
+ const CODE_PAYLOAD = `codeDiscountNode { id codeDiscount { __typename ${CODE_FRAGMENTS} } } userErrors { field code message }`;
18
+ const AUTOMATIC_PAYLOAD = `automaticDiscountNode { id automaticDiscount { __typename ${AUTOMATIC_FRAGMENTS} } } userErrors { field code message }`;
19
+ const ids = (what) => z.array(z.string()).min(1).optional().describe(`${what} GIDs`);
20
+ const decimal = (example) => z.string().regex(/^\d+(\.\d+)?$/, "Use a decimal string").describe(`Decimal amount as a string, e.g. "${example}"`);
21
+ const percent = z.number().gt(0).max(100);
22
+ const shared = {
23
+ method: z
24
+ .enum(["code", "automatic"])
25
+ .describe('"code": customers enter a code at checkout. "automatic": applies without a code.'),
26
+ title: z.string().describe("Discount name shown to merchants and customers"),
27
+ code: z.string().optional().describe("The code customers enter (required for method code)"),
28
+ startsAt: z.string().optional().describe("ISO 8601 start time (default: now)"),
29
+ endsAt: z.string().optional().describe("ISO 8601 end time (default: no end date)"),
30
+ usageLimit: z.number().int().positive().optional().describe("Total number of uses allowed (code discounts only)"),
31
+ appliesOncePerCustomer: z.boolean().optional().describe("Each customer can use it once (code discounts only)"),
32
+ combinesWith: z
33
+ .object({
34
+ productDiscounts: z.boolean().optional(),
35
+ orderDiscounts: z.boolean().optional(),
36
+ shippingDiscounts: z.boolean().optional(),
37
+ })
38
+ .optional()
39
+ .describe("Other discount classes this discount can combine with (default: none)"),
40
+ customerIds: ids("Only these customers can use it: customer"),
41
+ customerSegmentIds: ids("Only customers in these segments can use it: segment"),
42
+ marketIds: ids("Only buyers in these markets can use it: market"),
43
+ };
44
+ const minimums = {
45
+ minimumSubtotal: decimal("50000").optional().describe('Minimum order subtotal, e.g. "50000"'),
46
+ minimumQuantity: z.number().int().positive().optional().describe("Minimum number of items"),
47
+ };
48
+ function errorResult(message) {
49
+ return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
50
+ }
51
+ // Returns a message when the method-specific fields don't fit together
52
+ function checkMethod(input) {
53
+ if (input.method === "code" && !input.code)
54
+ return "code is required when method is code";
55
+ if (input.method === "automatic" && (input.code || input.usageLimit || input.appliesOncePerCustomer)) {
56
+ return "automatic discounts don't take code, usageLimit, or appliesOncePerCustomer";
57
+ }
58
+ return null;
59
+ }
60
+ function context({ customerIds, customerSegmentIds, marketIds }) {
61
+ if (!customerIds && !customerSegmentIds && !marketIds)
62
+ return { all: "ALL" };
63
+ return {
64
+ customers: customerIds ? { add: customerIds } : undefined,
65
+ customerSegments: customerSegmentIds ? { add: customerSegmentIds } : undefined,
66
+ markets: marketIds ? { add: marketIds } : undefined,
67
+ };
68
+ }
69
+ function items({ productIds, variantIds, collectionIds }) {
70
+ if (collectionIds)
71
+ return { collections: { add: collectionIds } };
72
+ if (productIds || variantIds) {
73
+ return { products: { productsToAdd: productIds, productVariantsToAdd: variantIds } };
74
+ }
75
+ return null;
76
+ }
77
+ function minimumRequirement(min) {
78
+ if (min.minimumSubtotal)
79
+ return { subtotal: { greaterThanOrEqualToSubtotal: min.minimumSubtotal } };
80
+ if (min.minimumQuantity)
81
+ return { quantity: { greaterThanOrEqualToQuantity: String(min.minimumQuantity) } };
82
+ return undefined;
83
+ }
84
+ // Fields every discount input shares; code-only fields are dropped for automatic discounts
85
+ function baseInput(input) {
86
+ const base = {
87
+ title: input.title,
88
+ startsAt: input.startsAt ?? new Date().toISOString(),
89
+ endsAt: input.endsAt,
90
+ combinesWith: input.combinesWith,
91
+ context: context(input),
92
+ };
93
+ if (input.method === "automatic")
94
+ return base;
95
+ return {
96
+ ...base,
97
+ code: input.code,
98
+ usageLimit: input.usageLimit,
99
+ appliesOncePerCustomer: input.appliesOncePerCustomer,
100
+ };
101
+ }
102
+ function discountKind(id) {
103
+ if (id.startsWith("gid://shopify/DiscountCodeNode/"))
104
+ return "code";
105
+ if (id.startsWith("gid://shopify/DiscountAutomaticNode/"))
106
+ return "automatic";
107
+ return null;
108
+ }
109
+ const discountId = z
110
+ .string()
111
+ .describe("Discount GID from shopify_discounts_list (DiscountCodeNode or DiscountAutomaticNode)");
112
+ export function registerDiscountTools(server, client) {
113
+ server.registerTool("shopify_discounts_list", {
114
+ description: "List code and automatic discounts with their status, dates, and a summary of what they do",
115
+ inputSchema: {
116
+ query: z
117
+ .string()
118
+ .optional()
119
+ .describe('Search filter, e.g. "status:active", "method:code", "type:free_shipping", "title:summer*"'),
120
+ first: pageSize.optional().describe("Number of discounts to return (default 20)"),
121
+ after: z.string().optional().describe("Cursor for pagination"),
122
+ },
123
+ annotations: READ_ONLY,
124
+ }, async ({ query, first, after }) => {
125
+ const result = await client.execute(`query ($first: Int!, $query: String, $after: String) {
126
+ discountNodes(first: $first, query: $query, after: $after, sortKey: CREATED_AT, reverse: true) {
127
+ nodes { id discount { __typename ${CODE_FRAGMENTS} ${AUTOMATIC_FRAGMENTS} } }
128
+ pageInfo { hasNextPage endCursor }
129
+ }
130
+ }`, { first: first ?? 20, query, after });
131
+ return toolResult(result);
132
+ });
133
+ server.registerTool("shopify_discount_get", {
134
+ description: "Get a discount by ID, including its codes and usage",
135
+ inputSchema: { id: discountId },
136
+ annotations: READ_ONLY,
137
+ }, async ({ id }) => {
138
+ const result = await client.execute(`query ($id: ID!) {
139
+ discountNode(id: $id) { id discount { __typename ${CODE_FRAGMENTS} ${AUTOMATIC_FRAGMENTS} } }
140
+ }`, { id });
141
+ return toolResult(result);
142
+ });
143
+ server.registerTool("shopify_discount_amount_off_create", {
144
+ description: "Create a percentage or fixed-amount discount on the whole order, or on specific products, variants, or collections, as a code or an automatic discount",
145
+ inputSchema: {
146
+ ...shared,
147
+ percentOff: percent.optional().describe("Percentage off, e.g. 20 for 20% off"),
148
+ amountOff: decimal("10000").optional().describe('Fixed amount off, e.g. "10000"'),
149
+ amountOffEachItem: z
150
+ .boolean()
151
+ .optional()
152
+ .describe("Apply amountOff to each eligible item instead of once across them"),
153
+ productIds: ids("Discount only these products: product"),
154
+ variantIds: ids("Discount only these variants: variant"),
155
+ collectionIds: ids("Discount only products in these collections: collection"),
156
+ ...minimums,
157
+ },
158
+ annotations: WRITE,
159
+ }, async (input) => {
160
+ const invalid = checkMethod(input) ??
161
+ ((input.percentOff === undefined) === (input.amountOff === undefined)
162
+ ? "provide exactly one of percentOff or amountOff"
163
+ : null) ??
164
+ (input.minimumSubtotal && input.minimumQuantity
165
+ ? "provide at most one of minimumSubtotal or minimumQuantity"
166
+ : null);
167
+ if (invalid)
168
+ return errorResult(invalid);
169
+ const value = input.percentOff !== undefined
170
+ ? { percentage: input.percentOff / 100 }
171
+ : { discountAmount: { amount: input.amountOff, appliesOnEachItem: input.amountOffEachItem ?? false } };
172
+ const discount = {
173
+ ...baseInput(input),
174
+ minimumRequirement: minimumRequirement(input),
175
+ // No product selection means the discount applies to the whole order
176
+ customerGets: { value, items: items(input) ?? { all: true } },
177
+ };
178
+ const result = input.method === "code"
179
+ ? await client.execute(`mutation ($discount: DiscountCodeBasicInput!) {
180
+ discountCodeBasicCreate(basicCodeDiscount: $discount) { ${CODE_PAYLOAD} }
181
+ }`, { discount })
182
+ : await client.execute(`mutation ($discount: DiscountAutomaticBasicInput!) {
183
+ discountAutomaticBasicCreate(automaticBasicDiscount: $discount) { ${AUTOMATIC_PAYLOAD} }
184
+ }`, { discount });
185
+ return toolResult(result);
186
+ });
187
+ server.registerTool("shopify_discount_free_shipping_create", {
188
+ description: "Create a free shipping discount, as a code or an automatic discount",
189
+ inputSchema: {
190
+ ...shared,
191
+ countryCodes: z
192
+ .array(z.string().regex(/^[A-Z]{2}$/, "Use ISO 3166-1 alpha-2 codes, e.g. ID"))
193
+ .min(1)
194
+ .optional()
195
+ .describe("Destination countries that qualify (default: all countries)"),
196
+ maximumShippingPrice: decimal("20000")
197
+ .optional()
198
+ .describe("Only shipping rates up to this price become free"),
199
+ ...minimums,
200
+ },
201
+ annotations: WRITE,
202
+ }, async (input) => {
203
+ const invalid = checkMethod(input) ??
204
+ (input.minimumSubtotal && input.minimumQuantity
205
+ ? "provide at most one of minimumSubtotal or minimumQuantity"
206
+ : null);
207
+ if (invalid)
208
+ return errorResult(invalid);
209
+ const discount = {
210
+ ...baseInput(input),
211
+ minimumRequirement: minimumRequirement(input),
212
+ destination: input.countryCodes ? { countries: { add: input.countryCodes } } : { all: true },
213
+ maximumShippingPrice: input.maximumShippingPrice,
214
+ };
215
+ const result = input.method === "code"
216
+ ? await client.execute(`mutation ($discount: DiscountCodeFreeShippingInput!) {
217
+ discountCodeFreeShippingCreate(freeShippingCodeDiscount: $discount) { ${CODE_PAYLOAD} }
218
+ }`, { discount })
219
+ : await client.execute(`mutation ($discount: DiscountAutomaticFreeShippingInput!) {
220
+ discountAutomaticFreeShippingCreate(freeShippingAutomaticDiscount: $discount) { ${AUTOMATIC_PAYLOAD} }
221
+ }`, { discount });
222
+ return toolResult(result);
223
+ });
224
+ const selection = (role) => z
225
+ .object({
226
+ productIds: ids(`${role} products: product`),
227
+ variantIds: ids(`${role} variants: variant`),
228
+ collectionIds: ids(`${role} products in collections: collection`),
229
+ })
230
+ .describe(`Which items ${role.toLowerCase()} (give products, variants, or collections)`);
231
+ server.registerTool("shopify_discount_bxgy_create", {
232
+ description: "Create a buy X get Y discount (e.g. buy 2 shirts, get 1 hat free), as a code or an automatic discount",
233
+ inputSchema: {
234
+ ...shared,
235
+ buys: selection("The customer buys").extend({
236
+ quantity: z.number().int().positive().optional().describe("Number of items the customer must buy"),
237
+ amount: decimal("100000").optional().describe("Or: amount the customer must spend on them"),
238
+ }),
239
+ gets: selection("The customer gets").extend({
240
+ quantity: z.number().int().positive().describe("Number of items the customer gets discounted"),
241
+ percentOff: percent.optional().describe("Percentage off the items they get (default 100: free)"),
242
+ amountOff: decimal("10000").optional().describe("Or: fixed amount off the items they get"),
243
+ }),
244
+ usesPerOrderLimit: z.number().int().positive().optional().describe("Times the offer can apply in one order"),
245
+ },
246
+ annotations: WRITE,
247
+ }, async (input) => {
248
+ const buysItems = items(input.buys);
249
+ const getsItems = items(input.gets);
250
+ const invalid = checkMethod(input) ??
251
+ ((input.buys.quantity === undefined) === (input.buys.amount === undefined)
252
+ ? "buys needs exactly one of quantity or amount"
253
+ : null) ??
254
+ (input.gets.percentOff !== undefined && input.gets.amountOff !== undefined
255
+ ? "gets takes at most one of percentOff or amountOff"
256
+ : null) ??
257
+ (!buysItems || !getsItems
258
+ ? "buys and gets each need productIds, variantIds, or collectionIds"
259
+ : null);
260
+ if (invalid)
261
+ return errorResult(invalid);
262
+ const effect = input.gets.amountOff !== undefined
263
+ ? { amount: input.gets.amountOff }
264
+ : { percentage: (input.gets.percentOff ?? 100) / 100 };
265
+ const discount = {
266
+ ...baseInput(input),
267
+ customerBuys: {
268
+ value: input.buys.quantity !== undefined
269
+ ? { quantity: String(input.buys.quantity) }
270
+ : { amount: input.buys.amount },
271
+ items: buysItems,
272
+ },
273
+ customerGets: {
274
+ value: { discountOnQuantity: { quantity: String(input.gets.quantity), effect } },
275
+ items: getsItems,
276
+ },
277
+ };
278
+ const result = input.method === "code"
279
+ ? await client.execute(`mutation ($discount: DiscountCodeBxgyInput!) {
280
+ discountCodeBxgyCreate(bxgyCodeDiscount: $discount) { ${CODE_PAYLOAD} }
281
+ }`, { discount: { ...discount, usesPerOrderLimit: input.usesPerOrderLimit } })
282
+ : // The automatic input types usesPerOrderLimit as UnsignedInt64, which is sent as a string
283
+ await client.execute(`mutation ($discount: DiscountAutomaticBxgyInput!) {
284
+ discountAutomaticBxgyCreate(automaticBxgyDiscount: $discount) { ${AUTOMATIC_PAYLOAD} }
285
+ }`, {
286
+ discount: {
287
+ ...discount,
288
+ usesPerOrderLimit: input.usesPerOrderLimit === undefined ? undefined : String(input.usesPerOrderLimit),
289
+ },
290
+ });
291
+ return toolResult(result);
292
+ });
293
+ const statusTool = (action) => server.registerTool(`shopify_discount_${action}`, {
294
+ description: action === "activate"
295
+ ? "Activate a discount now (sets its start time to now)"
296
+ : "Deactivate a discount now (sets its end time to now)",
297
+ inputSchema: { id: discountId },
298
+ annotations: { ...WRITE, idempotentHint: true },
299
+ }, async ({ id }) => {
300
+ const kind = discountKind(id);
301
+ if (!kind)
302
+ return errorResult("Expected a DiscountCodeNode or DiscountAutomaticNode ID");
303
+ const verb = action === "activate" ? "Activate" : "Deactivate";
304
+ const result = kind === "code"
305
+ ? await client.execute(`mutation ($id: ID!) { discountCode${verb}(id: $id) { ${CODE_PAYLOAD} } }`, { id })
306
+ : await client.execute(`mutation ($id: ID!) { discountAutomatic${verb}(id: $id) { ${AUTOMATIC_PAYLOAD} } }`, { id });
307
+ return toolResult(result);
308
+ });
309
+ statusTool("activate");
310
+ statusTool("deactivate");
311
+ server.registerTool("shopify_discount_delete", {
312
+ description: "Permanently delete a discount and its codes",
313
+ inputSchema: { id: discountId },
314
+ annotations: DESTRUCTIVE,
315
+ }, async ({ id }) => {
316
+ const kind = discountKind(id);
317
+ if (!kind)
318
+ return errorResult("Expected a DiscountCodeNode or DiscountAutomaticNode ID");
319
+ const result = kind === "code"
320
+ ? await client.execute(`mutation ($id: ID!) { discountCodeDelete(id: $id) { deletedCodeDiscountId userErrors { field code message } } }`, { id })
321
+ : await client.execute(`mutation ($id: ID!) { discountAutomaticDelete(id: $id) { deletedAutomaticDiscountId userErrors { field code message } } }`, { id });
322
+ return toolResult(result);
323
+ });
324
+ server.registerTool("shopify_discount_codes_add", {
325
+ description: "Add up to 250 extra codes to an existing code discount (e.g. unique codes for a campaign). Codes are created in the background; check progress with shopify_discount_get.",
326
+ inputSchema: {
327
+ discountId: z.string().describe("DiscountCodeNode GID"),
328
+ codes: z.array(z.string().min(1)).min(1).max(250).describe("Codes to add"),
329
+ },
330
+ annotations: WRITE,
331
+ }, async ({ discountId, codes }) => {
332
+ if (discountKind(discountId) !== "code") {
333
+ return errorResult("Codes can only be added to code discounts (DiscountCodeNode IDs)");
334
+ }
335
+ const result = await client.execute(`mutation ($discountId: ID!, $codes: [DiscountRedeemCodeInput!]!) {
336
+ discountRedeemCodeBulkAdd(discountId: $discountId, codes: $codes) {
337
+ bulkCreation { id done codesCount importedCount failedCount }
338
+ userErrors { field code message }
339
+ }
340
+ }`, { discountId, codes: codes.map((code) => ({ code })) });
341
+ return toolResult(result);
342
+ });
343
+ }
344
+ //# sourceMappingURL=discounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discounts.js","sourceRoot":"","sources":["../../src/tools/discounts.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const TOOLSETS: readonly ["products", "collections", "publishing", "metafields", "metaobjects", "customers", "orders", "inventory", "files", "themes", "markets"];
1
+ export declare const TOOLSETS: readonly ["products", "collections", "publishing", "metafields", "metaobjects", "customers", "orders", "inventory", "discounts", "files", "themes", "markets"];
2
2
  export type Toolset = (typeof TOOLSETS)[number];
3
3
  export interface Config {
4
4
  store: string;
package/dist/utils/cli.js CHANGED
@@ -8,6 +8,7 @@ export const TOOLSETS = [
8
8
  "customers",
9
9
  "orders",
10
10
  "inventory",
11
+ "discounts",
11
12
  "files",
12
13
  "themes",
13
14
  "markets",
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/utils/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/utils/cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@acodera/shopify-admin-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "MCP server providing full access to Shopify's Admin GraphQL API with schema introspection",
5
5
  "type": "module",
6
6
  "bin": {
7
- "shopify-admin-mcp": "./dist/index.js"
7
+ "shopify-admin-mcp": "dist/index.js"
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "files": [