Repository navigation
Releases
2.0.3
Security update for hosted and local installations.
- Upgrade MCP server/client SDK to 2.3.1.
- Activate hosted tool-input validation limits (10,000 elements) and a 1 MiB HTTP body limit on Node and Cloudflare Workers.
- Update Wrangler to 4.152.0; the release dependency audit reports zero known findings.
- Replace the EOL Node 20 container stages with patched Node 22.23.4 images.
All 226 tests passed with no skips, strict TypeScript and GitHub CI/CodeQL passed, and the hosted Worker was verified at version 2.0.3 with an authenticated read and input-limit rejection. Docker image execution was not tested locally.
2.0.2
- Hosted: Claude Code signs in. Loopback redirect URIs now match a registered loopback URI on any port (RFC 8252), so Claude Code's ephemeral-port callback is accepted. The token endpoint still requires the exact redirect_uri.
- Hosted: Claude connects again after its first approval. The consent screen now shows on every OAuth sign-in.
install-shopify-skillsinstalls the Shopify AI Toolkit's currentshopifyskill, and exits 1 with the list of available skills when the requested one is missing.
2.0.1
- Hosted: ChatGPT connects with its default OAuth settings (Client ID Metadata Documents that list none in token_endpoint_auth_methods_supported are accepted).
- Hosted: Reconnect all picks up stores missing a newly added scope, such as read_all_orders.
- Docs match the Sign in with Shopify page and the current ChatGPT steps.
- Release workflow waits for npm before publishing to the MCP Registry.
2.0.0
Breaking: hosted mode is now per-user Shopify sign-in only. Google sign-in, the
policy file, roles and personal access tokens were removed.
Live deployment fixes
- Form posts no longer fail with "This form was submitted from another site"
when Chromium sendsOrigin: nullunderReferrer-Policy: no-referrer;
Sec-Fetch-Sitedecides when present. - The connect pages allow the redirect through
admin.shopify.comand
accounts.shopify.comin CSPform-action, so sign-in buttons work. SHOPIFY_CLIENT_ID_<ALIAS>pairs withSHOPIFY_CLIENT_SECRET_<ALIAS>, so a
store in another Shopify organization can use its own app.- The public sign-in page no longer lists store names: one "Sign in with
Shopify" button plus a field for another store's name or .myshopify.com
address. /redirects to/stores, so opening the app from the Shopify admin loads.
Cloudflare Workers review fixes
- Guided tools (prices, metafields, redirects, tags, orders, customers,
fulfillment, and the pinnedshopify_search/shopify_getreads) now run on
the default API version, 2026-07, the one schema a Worker bundles. Before,
they pinned 2026-04, so on Cloudflare the first guided call downloaded a
second 6 MB schema from shopify.dev and held two parsed schemas in a 128 MB
isolate. Only the legacy smart-collectionruleSetwrite stays on 2026-04;
a Worker refuses it and points toshopify_run_action. - A Worker never downloads a schema at run time: an unbundled API version fails
at once with an error naming the bundled one, instead of a 30 second fetch. - Guided writes failed on Workers with "Expected String to be a GraphQL
nullable type":graphql/execution/values.jspulled a second copy of
graphqlinto the bundle. Every import now uses the package root. ACTIONS_DENYLISTandACTIONS_DENYLIST_REPLACEare read from the Worker's
env (runtimeEnv()), notprocess.env, so an operator's denylist applies on
Cloudflare whatever the compatibility date.- Dynamically registered OAuth clients expire after 30 days without use
(OAUTH_CLIENT_IDLE_TTL_SECONDS; each use pushes it back, at most one write a
day). Registration is limited per source address per hour
(OAUTH_MAX_REGISTRATIONS_PER_SOURCE_PER_HOUR, default 30,0for no
limit; the TCP peer on Node,CF-Connecting-IPon Workers). The Durable
Object keeps the client count in a counter key instead of listing every
client on each registration. - Cloudflare CLI setup now creates the D1 audit database explicitly
(npx wrangler d1 create shopify-multi-store-audit, then itsdatabase_idin
wrangler.jsonc). Automatic creation duringwrangler deploydepends on
wrangler's hidden experimental provisioning.package.jsongains
cloudflare.bindingsdescriptions for the Deploy to Cloudflare flow. - Hosted: a store's Shopify token is decrypted only when a tool call uses that
store. Before, every MCP request (includinginitializeandtools/list)
read and decrypted the caller's token for every configured store. - Hosted: the Shopify OAuth HMAC check uses the shared
src/shopify-hmac.ts
instead of a second copy. - The
/storespage names the server it belongs to (issuer and MCP URL), so a
person with more than one deployment knows which connections they are
looking at. - README: the npm badge reads the live version; "up to ten stores" is now the
real limit (one hundred); a "Connect your first store" section walks a new
merchant through a Dev Dashboard app (client credentials or authorization
code) or an admin-created custom app token;preparebuilds the server so
npm install github:...works; thecodex-shopify-multi-storeconfig and
credential name is explained as a legacy name kept for existing installs.
Breaking changes for shopify-multi-store serve (local stdio mode is unchanged):
Review 3: fixes and a smaller tool surface
Breaking: the server now exposes 29 tools instead of 85. Removed tools and their
replacements are listed below. Guided write tools take dryRun (default true)
instead of confirm.
Fixes:
- Write results are never dropped for size. Above 150,000 characters a write
tool's result is trimmed (per-itemmutationResponseandverifiedStateto
the changed fields, then one summary line per applied item), always keeping
status, counts, and every item that did not apply, withresponseTrimmed
explaining what was cut. Before,shopify_update_priceswith about 190 or more
SKUs applied and verified every price and then reported failure. Variants are
also read back 50 at a time, so long product titles cannot push the
verification read over the 50,000 character response cap. shopify_update_product,shopify_update_orderandshopify_update_customer
no longer taketags(a silent full replace).replaceTagssays it replaces
all tags and the preview lists the tags it would remove;addTagsand
removeTagsusetagsAddandtagsRemoveand leave other tags alone.- Every guided write tool defaults to
dryRun: trueand returns a before/after
(or would-create) preview;dryRun: falseapplies and reads back. - Local
shopify_graphql_mutationnow applies the action denylist and the
destructive confirm (confirm set to the mutation name), as hosted mode did. - Destructive classification covers argument-driven destruction:
productUpdateorproductChangeStatuswith statusARCHIVEDorDRAFT,
productVariantsBulkCreatewithREMOVE_STANDALONE_VARIANT, and any mutation
withnotifyCustomer: true(one table,DESTRUCTIVE_ARGUMENT_RULES), plus
always-destructivepublishablePublish,productPublish,collectionPublish,
discount activation, invoice and notification emails,giftCardCreate,
giftCardCreditandstoreCreditAccountCredit. scripts/oauth-connect.mjsverifies Shopify's OAuth HMAC with Shopify's
escaping and array rules and a timestamp check, from the shared
src/shopify-hmac.ts.- Redirect writes report a per-item
outcomeofapplied,rejectedor
unknownand a storestatus(ok,partial,failed,unknown), like
shopify_update_prices; an unknown outcome is no longer flattened to
ok: false. - Pinned Admin API versions live in
src/api-versions.ts, and a test fails 60
days before any pinned version's end of support (12 months after release).
Collection writes without a rule set now use the 2026-07
CollectionCreateInput/CollectionUpdateInput(products are added with
collectionAddProducts); writes with a legacyruleSetstay on 2026-04,
because 2026-07 replaced rule sets with typed collection sources.
Removed features: new-store previews, sample products, the MCP Apps UI
(ui:// resource and _meta.ui), the Shopify CLI bridge and shopify_cli
store auth, and the unused GraphQL code generation (src/generated,
scripts/codegen.mjs). The build is plain tsc.
Removed or folded tools, with what to use instead:
| Removed tool | Use instead |
|---|---|
shopify_create_preview_store, shopify_get_preview_store, shopify_get_new_store_previews, shopify_get_new_store_preview_status, shopify_find_sample_product |
Removed with the feature. |
shopify_switch_shop |
Pass store on every call. |
shopify_get_store_capabilities |
shopify_check_access (shop identity and granted scopes). |
16 report tools (shopify_portfolio_snapshot, shopify_order_summary, shopify_customer_growth, shopify_get_product_everywhere, shopify_compare_inventory, shopify_low_stock_report, shopify_compare_prices, shopify_duplicate_sku_report, shopify_list_unfulfilled_orders, shopify_fulfillment_sla_report, shopify_compare_catalog, shopify_catalog_gap_report, shopify_catalog_health, shopify_recent_product_changes, shopify_compare_collections, shopify_store_locations) |
shopify_report with report set to the old name without shopify_, same arguments. |
shopify_run_analytics_query |
shopify_report with report: "analytics", stores and query. |
shopify_search_products, shopify_search_collections, shopify_list_orders, shopify_list_customers, shopify_list_publications, shopify_list_redirects, shopify_list_pages, shopify_list_files, shopify_list_metaobjects, shopify_list_markets, shopify_list_themes, shopify_list_delivery_profiles |
shopify_search with resource (products, collections, orders, customers, publications, redirects, pages, files, metaobjects with type, markets, themes, delivery_profiles). |
shopify_search_products_many |
shopify_search with resource: "products" and stores. |
shopify_get_product, shopify_get_collection, shopify_get_order, shopify_get_inventory_levels, shopify_get_metafields, shopify_get_theme_files, shopify_list_blog_articles, shopify_get_uploaded_image, shopify_bulk_export_status |
shopify_get with resource (product, collection, order, inventory, metafields, theme_files, blog_articles, uploaded_image, bulk_operation) and id. |
shopify_update_prices_many |
shopify_update_prices with stores instead of store. |
shopify_set_metafields, shopify_delete_metafields |
shopify_metafields with set and/or delete. |
shopify_create_redirects, shopify_delete_redirects |
shopify_redirects with create and/or delete. |
shopify_add_to_collection |
shopify_update_collection with addProductIds. |
shopify_publish_resource |
shopify_run_action with mutation: "publishablePublish", variables: { id, input: [{ publicationId }] }, confirm: "publishablePublish". |
shopify_bulk_update_product_status |
shopify_run_action with a document that aliases one productUpdate(product: { id, status }) per product (or mutation: "productChangeStatus" per product); ARCHIVED and DRAFT need confirm. |
shopify_bulk_export_start |
shopify_run_action with `mutat... |
Shopify Multi Store 1.6.0
Shopify Multi Store 1.6.0
This release expands the server from 22 to 55 tools. It keeps explicit store selection and separate credentials for each store.
New features
- Guided workflows for products, variants, collections, inventory, discounts, images, publication, ShopifyQL, and bulk exports.
- Interactive product cards, tables, charts, and preview status in compatible MCP Apps hosts.
- Temporary storefronts with custom Dawn designs, demo products, and Shopify claim links.
- Category-specific sample catalogs and agent-generated product concepts.
- Shopify Admin client, schema code generation, and documentation search integrations.
Reliability fixes
- Detect GraphQL payload errors through aliases and fragments.
- Prevent automatic retries after partial mutations.
- Bound response-body timeouts and reject repeated pagination cursors.
- Add the required inventory idempotency directive.
- Prevent duplicate preview requests and partial reads of preview receipts.
- Launch Shopify CLI on Windows without a shell.
Acceptance
The release passes 48 automated tests, full TypeScript checks, and package checks. Live acceptance covered 11 existing stores through read-only operations. Three isolated temporary stores covered Admin writes, storefront designs, product seeding, and claim links.
Requirements and limits
Node.js 20 or later is required. Preview creation also needs Shopify CLI, Git, and GitHub access. ShopifyQL needs reports access. Customer data needs the corresponding Shopify permissions. Interactive UI support depends on the MCP host. Existing clients need a restart to load the updated server.
The app uses public Shopify APIs and CLI features. It does not reproduce Shopify's proprietary image-generation service.
v1.5.1
Fixed
-
Keychain-safe account name for OAuth client secrets.
clientSecretAccountbuilt<alias>:client-secret. The macOS backend incross-keychainallows only alphanumerics, dots, underscores,@and hyphens, so the colon made every store usingclient_credentialsauth fail on macOS withaccount contains invalid characters, on both read and write. In practice the secret could never be stored, so the wholeclient_credentialspath was dead on macOS. The account is now<alias>-client-secret.No migration is needed, since nothing could have been written under the old name on macOS. Affected stores should re-run
shopify-multi-store oauthto store the secret. -
Reject Shopify retry delays longer than 60 seconds instead of leaving an MCP request stalled.
-
Keep successful-store counts accurate when a large result must be omitted.
-
Fail explicitly when error payloads alone exceed the combined response limit.
-
Include both the OAuth error code and description when authorization-code exchange fails.
Changed
- Multi-store response fitting now serializes each store result once.
- Store health checks now run in parallel and use the shared default Shopify API version.
- Refreshed the README badge URLs to clear GitHub's cached broken downloads badge.
Full Changelog: v1.5.0...v1.5.1
Shopify Multi-Store MCP v1.5.0: Reliable Results
Reliable results across every store
Version 1.5.0 focuses on trust: complete results are labeled clearly, failed stores can no longer appear complete, and one oversized store response no longer erases successful results from the other stores.
Reliability
- Report failures now return
complete: falseconsistently. - Shopify throttling uses
Retry-Afterand fails clearly after the final retry. - Concurrent OAuth requests share one token exchange.
- OAuth exchanges now have timeouts and readable non-JSON errors.
- Interrupted secret entry is rejected instead of saving a partial credential.
- Legacy imports restore earlier credentials if a later import fails.
- Pagination uses linear size accounting and rejects repeated cursors.
- Missing items are distinguished from matching items in comparison reports.
Operations and debugging
- GraphQL results include Shopify request IDs, elapsed time, and retry counts.
doctornow tests every credential and live store connection.- Price comparison uses a smaller dedicated query.
- Order summaries identify partial currency totals.
Publication and discovery
- Releases now publish through npm trusted publishing with build provenance.
- Added an official MCP Registry manifest.
- Added a terminal demo, comparison with Shopify Dev MCP, changelog, contribution guide, directory guide, and expanded security policy.
Verification
- TypeScript build passed.
- All 11 automated tests passed.
- All 10 configured stores passed live identity checks.
- All 17 ready-made reports passed live read-only smoke tests.
- npm audit found zero known vulnerabilities.
- Official MCP Registry validation passed.
No store mutations were run during release verification.
See CHANGELOG.md for the full change list.
v1.4.0: Find products and operational gaps across every store
v1.4.0 adds four read-only tools and expands the low-stock report.
New tools
- Find one exact SKU or handle across selected stores.
- Search products across multiple stores with one query.
- Report fulfillment age buckets and SLA breaches.
- Find products with missing or different store statuses.
Better inventory operations
- Show SKUs that are out of stock in one store but available in another.
- Exclude same-store inventory from transfer opportunities.
- Keep transfer analysis bounded and report incomplete results.
Reliability and safety
- Read the MCP server version from package.json.
- Label bounded catalog scans as potential gaps.
- Keep all new tools read-only.
- Preserve per-store failures and existing mutation controls.
The release passed automated tests, package validation, and live read-only checks across ten connected stores.
v1.3.0: Portfolio reports and production hardening
v1.3.0 turns the server into a practical operating dashboard for a Shopify portfolio. It adds nine read-only reports and hardens production behavior.
Nine new portfolio reports
| Report | What it shows |
|---|---|
| Order summary | Order values, discounts, shipping, tax, cancellations, and statuses |
| Stock alerts | Low, zero, and negative inventory |
| Price comparison | Exact SKU price and compare-at-price differences |
| SKU integrity | Duplicate SKUs inside stores and shared SKUs across stores |
| Catalog health | Missing merchandising, SEO, media, alt text, and inventory data |
| Recent changes | Products updated during a selected period |
| Customer growth | New-customer counts across equal periods |
| Collection comparison | Collection content and configuration by handle |
| Store locations | Location, fulfillment, inventory, and address coverage |
The server now includes 18 MCP tools and 13 ready-made reports. Every report keeps store errors visible and separates currency totals.
Production hardening
- Retry Shopify HTTP 429 and GraphQL throttling responses.
- Read fresh credentials during long server sessions.
- Tie OAuth tokens to the store and credential fingerprint.
- Show useful errors for non-JSON Shopify responses.
- Examine access tokens before the setup command saves a store.
- Import legacy Hermes store maps with shared app credentials.
- Stop incomplete variant pagination from producing false comparisons.
- Ignore store-specific Shopify resource IDs during cross-store comparisons.
- Label bounded and incomplete reports.
Release confidence
- CI passed on macOS, Ubuntu, and Windows.
- All 13 ready-made reports passed live read-only tests.
- All ten configured stores passed identity tests.
npm auditfound zero known vulnerabilities.- The Codex plugin and Agent Skill passed their checks.
- No Shopify mutations ran during release tests.
Shopify Multi-Store MCP v1.2.1
Reliable comparisons. Safer credential cleanup. A sharper public face.
v1.2.1 completes every inventory and catalog page before it compares stores. Large catalogs no longer return a false consistency result after variant 100.
Credential removal now reports real Keychain and credential backend failures. It ignores only a confirmed missing credential.
The GitHub page now leads with the project's key advantage: one MCP server for every Shopify store. New badges, an architecture diagram, and a concise value summary make the project easier to understand and find.
Included
- Complete inventory pagination across matching Shopify variants.
- Complete catalog pagination across products and nested variants.
- Invalid cursor and incomplete response protection.
- Precise credential deletion error handling.
- Regression tests for multi-page reports and credential cleanup.
- New GitHub description, topics, badges, diagram, and README introduction.
Compatibility
The server supports Claude, Codex, Cursor, VS Code, and other local stdio MCP clients.
No configuration migration is necessary.