@acodera/shopify-admin-mcp 1.0.1 → 1.1.1
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 +18 -0
- package/README.md +80 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/discounts.d.ts +3 -0
- package/dist/tools/discounts.js +344 -0
- package/dist/tools/discounts.js.map +1 -0
- package/dist/utils/cli.d.ts +1 -1
- package/dist/utils/cli.js +27 -10
- package/dist/utils/cli.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @acodera/shopify-admin-mcp
|
|
2
2
|
|
|
3
|
+
## 1.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#7](https://github.com/acoderacom/shopify-admin-mcp/pull/7) [`04f9a39`](https://github.com/acoderacom/shopify-admin-mcp/commit/04f9a39f77ffc3e207e355f758a5141dfe1f127b) Thanks [@acoderacom](https://github.com/acoderacom)! - Treat blank values and unfilled `${VAR}` / `$VAR` references as not set for every option, so a config can list both an access token and client credentials and use whichever is filled in (previously a literal `${SHOPIFY_ACCESS_TOKEN}` was sent as the token). The startup log now names the authentication method, and incomplete client credentials report which value is missing.
|
|
8
|
+
|
|
9
|
+
- [#7](https://github.com/acoderacom/shopify-admin-mcp/pull/7) [`c062f3a`](https://github.com/acoderacom/shopify-admin-mcp/commit/c062f3a022a7da493b46dee9b9eca8c1835bd980) Thanks [@acoderacom](https://github.com/acoderacom)! - Upgrade `graphql` (used to parse raw GraphQL in read-only mode) from 16 to 17. No behavior change: mutations and subscriptions are still detected and blocked the same way.
|
|
10
|
+
|
|
11
|
+
## 1.1.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [#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.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#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.
|
|
20
|
+
|
|
3
21
|
## 1.0.1
|
|
4
22
|
|
|
5
23
|
### Patch 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
|
-
- **
|
|
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 |
|
|
@@ -417,9 +434,43 @@ A theme editor that may change the live theme:
|
|
|
417
434
|
"args": ["-y", "@acodera/shopify-admin-mcp", "--toolsets", "themes,files", "--allow-live-theme-writes"]
|
|
418
435
|
```
|
|
419
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
|
+
|
|
420
457
|
### As environment variables
|
|
421
458
|
|
|
422
|
-
Every flag
|
|
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:
|
|
423
474
|
|
|
424
475
|
```json
|
|
425
476
|
{
|
|
@@ -431,15 +482,38 @@ Every flag also has an environment variable, which you can put in `env` instead
|
|
|
431
482
|
"SHOPIFY_STORE": "mystore.myshopify.com",
|
|
432
483
|
"SHOPIFY_CLIENT_ID": "${SHOPIFY_CLIENT_ID}",
|
|
433
484
|
"SHOPIFY_CLIENT_SECRET": "${SHOPIFY_CLIENT_SECRET}",
|
|
434
|
-
"
|
|
485
|
+
"SHOPIFY_API_VERSION": "2026-10",
|
|
486
|
+
"SHOPIFY_TOOLSETS": "products,collections,publishing,metafields,metaobjects,customers,orders,inventory,discounts,files,themes,markets",
|
|
435
487
|
"SHOPIFY_UPLOAD_DIR": "/Users/you/shopify-uploads",
|
|
436
|
-
"SHOPIFY_READ_ONLY": "false"
|
|
488
|
+
"SHOPIFY_READ_ONLY": "false",
|
|
489
|
+
"SHOPIFY_ALLOW_LIVE_THEME_WRITES": "false"
|
|
437
490
|
}
|
|
438
491
|
}
|
|
439
492
|
}
|
|
440
493
|
}
|
|
441
494
|
```
|
|
442
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
|
+
Blank values and unfilled variable references (`${VAR}`, `${VAR:-}`, `$VAR`) are treated as not set, for every option. That lets one config list both authentication methods and use whichever has real values, which helps with clients such as Claude Desktop that pass `${VAR}` through literally:
|
|
499
|
+
|
|
500
|
+
```json
|
|
501
|
+
"env": {
|
|
502
|
+
"SHOPIFY_STORE": "mystore.myshopify.com",
|
|
503
|
+
"SHOPIFY_ACCESS_TOKEN": "${SHOPIFY_ACCESS_TOKEN}",
|
|
504
|
+
"SHOPIFY_CLIENT_ID": "${SHOPIFY_CLIENT_ID}",
|
|
505
|
+
"SHOPIFY_CLIENT_SECRET": "${SHOPIFY_CLIENT_SECRET}"
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
The startup log on stderr says which method was used, for example `Connecting to mystore.myshopify.com (API 2026-10, client credentials)...`.
|
|
510
|
+
|
|
511
|
+
If you set the same option both ways:
|
|
512
|
+
|
|
513
|
+
- For options that take a value (`--store`, credentials, `--api-version`, `--toolsets`, `--upload-dir`), the flag wins.
|
|
514
|
+
- 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.
|
|
515
|
+
- If both an access token and client credentials are set, the access token is used.
|
|
516
|
+
|
|
443
517
|
Use an absolute path for `--upload-dir`, because MCP clients start the server from their own working directory, not your project's.
|
|
444
518
|
|
|
445
519
|
## Schema Exploration
|
|
@@ -488,7 +562,7 @@ SHOPIFY_ACCESS_TOKEN=shpat_xxxxx \
|
|
|
488
562
|
npm test
|
|
489
563
|
```
|
|
490
564
|
|
|
491
|
-
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,
|
|
565
|
+
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.
|
|
492
566
|
|
|
493
567
|
## Contributing and Releases
|
|
494
568
|
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { SchemaIndex } from "./graphql/schema-index.js";
|
|
|
8
8
|
import { createServer } from "./server.js";
|
|
9
9
|
async function main() {
|
|
10
10
|
const config = parseArgs(process.argv);
|
|
11
|
-
console.error(`Connecting to ${config.store} (API ${config.apiVersion}${config.readOnly ? ", read-only" : ""})...`);
|
|
11
|
+
console.error(`Connecting to ${config.store} (API ${config.apiVersion}, ${config.auth.mode === "access-token" ? "access token" : "client credentials"}${config.readOnly ? ", read-only" : ""})...`);
|
|
12
12
|
const auth = new AuthProvider(config);
|
|
13
13
|
// Validate credentials early
|
|
14
14
|
try {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,OAAO,CAAC,KAAK,CACX,iBAAiB,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,OAAO,CAAC,KAAK,CACX,iBAAiB,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,oBAAoB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,CACrL,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAEtC,6BAA6B;IAC7B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CACrE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAE/C,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACjD,IAAI,WAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC9C,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,CAAC,KAAK,CACX,kBAAkB,MAAM,CAAC,KAAK,CAAC,MAAM,QAAQ,CAC9C,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,gCAAgC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAC3E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
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,
|
package/dist/server.js.map
CHANGED
|
@@ -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,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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"}
|
package/dist/utils/cli.d.ts
CHANGED
|
@@ -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",
|
|
@@ -16,15 +17,28 @@ export const DEFAULT_API_VERSION = "2026-10";
|
|
|
16
17
|
// Restricting the host to *.myshopify.com keeps credentials from being sent to any other domain
|
|
17
18
|
const STORE_PATTERN = /^[a-z0-9][a-z0-9-]*\.myshopify\.com$/;
|
|
18
19
|
const API_VERSION_PATTERN = /^(\d{4}-(01|04|07|10)|unstable)$/;
|
|
20
|
+
// A whole-value variable reference such as ${SHOPIFY_CLIENT_ID}, ${VAR:-default}, or $VAR
|
|
21
|
+
const UNEXPANDED_VARIABLE = /^\$(\{[^}]*\}|[A-Za-z_][A-Za-z0-9_]*)$/;
|
|
22
|
+
// MCP clients that don't expand variables pass ${VAR} through literally, and unset
|
|
23
|
+
// variables often arrive as empty strings. Treating both as "not provided" lets one
|
|
24
|
+
// config carry both auth methods and use whichever is filled in.
|
|
25
|
+
function provided(value) {
|
|
26
|
+
const trimmed = value?.trim();
|
|
27
|
+
if (!trimmed || UNEXPANDED_VARIABLE.test(trimmed))
|
|
28
|
+
return undefined;
|
|
29
|
+
return trimmed;
|
|
30
|
+
}
|
|
19
31
|
function getArg(args, flag) {
|
|
20
32
|
const idx = args.indexOf(flag);
|
|
21
33
|
if (idx === -1 || idx + 1 >= args.length)
|
|
22
34
|
return undefined;
|
|
23
|
-
return args[idx + 1];
|
|
35
|
+
return provided(args[idx + 1]);
|
|
36
|
+
}
|
|
37
|
+
function getEnv(name) {
|
|
38
|
+
return provided(process.env[name]);
|
|
24
39
|
}
|
|
25
40
|
function getFlag(args, flag, envVar) {
|
|
26
|
-
return
|
|
27
|
-
["1", "true"].includes(process.env[envVar]?.toLowerCase() ?? ""));
|
|
41
|
+
return args.includes(flag) || ["1", "true"].includes(getEnv(envVar)?.toLowerCase() ?? "");
|
|
28
42
|
}
|
|
29
43
|
function fail(message) {
|
|
30
44
|
console.error(`Error: ${message}`);
|
|
@@ -49,18 +63,18 @@ function parseToolsets(value) {
|
|
|
49
63
|
return names;
|
|
50
64
|
}
|
|
51
65
|
export function parseArgs(argv) {
|
|
52
|
-
const store = getArg(argv, "--store") ??
|
|
66
|
+
const store = getArg(argv, "--store") ?? getEnv("SHOPIFY_STORE");
|
|
53
67
|
const accessTokenArg = getArg(argv, "--access-token");
|
|
54
|
-
const accessToken = accessTokenArg ??
|
|
68
|
+
const accessToken = accessTokenArg ?? getEnv("SHOPIFY_ACCESS_TOKEN");
|
|
55
69
|
const clientId = getArg(argv, "--client-id") ??
|
|
56
70
|
getArg(argv, "--clientId") ??
|
|
57
|
-
|
|
71
|
+
getEnv("SHOPIFY_CLIENT_ID");
|
|
58
72
|
const clientSecretArg = getArg(argv, "--client-secret") ?? getArg(argv, "--clientSecret");
|
|
59
|
-
const clientSecret = clientSecretArg ??
|
|
73
|
+
const clientSecret = clientSecretArg ?? getEnv("SHOPIFY_CLIENT_SECRET");
|
|
60
74
|
const apiVersion = getArg(argv, "--api-version") ??
|
|
61
|
-
|
|
75
|
+
getEnv("SHOPIFY_API_VERSION") ??
|
|
62
76
|
DEFAULT_API_VERSION;
|
|
63
|
-
const uploadDir = getArg(argv, "--upload-dir") ??
|
|
77
|
+
const uploadDir = getArg(argv, "--upload-dir") ?? getEnv("SHOPIFY_UPLOAD_DIR");
|
|
64
78
|
if (!store)
|
|
65
79
|
fail("--store is required (e.g. --store mystore.myshopify.com)");
|
|
66
80
|
const normalizedStore = normalizeStore(store);
|
|
@@ -77,7 +91,7 @@ export function parseArgs(argv) {
|
|
|
77
91
|
store: normalizedStore,
|
|
78
92
|
apiVersion,
|
|
79
93
|
readOnly: getFlag(argv, "--read-only", "SHOPIFY_READ_ONLY"),
|
|
80
|
-
toolsets: parseToolsets(getArg(argv, "--toolsets") ??
|
|
94
|
+
toolsets: parseToolsets(getArg(argv, "--toolsets") ?? getEnv("SHOPIFY_TOOLSETS")),
|
|
81
95
|
uploadDir: uploadDir ? path.resolve(uploadDir) : undefined,
|
|
82
96
|
allowLiveThemeWrites: getFlag(argv, "--allow-live-theme-writes", "SHOPIFY_ALLOW_LIVE_THEME_WRITES"),
|
|
83
97
|
};
|
|
@@ -90,6 +104,9 @@ export function parseArgs(argv) {
|
|
|
90
104
|
auth: { mode: "client-credentials", clientId, clientSecret },
|
|
91
105
|
};
|
|
92
106
|
}
|
|
107
|
+
if (clientId || clientSecret) {
|
|
108
|
+
fail(`Client credentials are incomplete: ${clientId ? "SHOPIFY_CLIENT_SECRET (--client-secret)" : "SHOPIFY_CLIENT_ID (--client-id)"} is missing`);
|
|
109
|
+
}
|
|
93
110
|
fail("Provide either --access-token or both --client-id and --client-secret");
|
|
94
111
|
}
|
|
95
112
|
//# sourceMappingURL=cli.js.map
|
package/dist/utils/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/utils/cli.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,UAAU;IACV,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,WAAW;IACX,QAAQ;IACR,WAAW;IACX,OAAO;IACP,QAAQ;IACR,SAAS;CACD,CAAC;AAkBX,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,gGAAgG;AAChG,MAAM,aAAa,GAAG,sCAAsC,CAAC;AAC7D,MAAM,mBAAmB,GAAG,kCAAkC,CAAC;AAE/D,SAAS,MAAM,CAAC,IAAc,EAAE,IAAY;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/utils/cli.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acodera/shopify-admin-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "MCP server providing full access to Shopify's Admin GraphQL API with schema introspection",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
29
|
-
"graphql": "^
|
|
29
|
+
"graphql": "^17.0.2",
|
|
30
30
|
"zod": "^4.6.5"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|