shopify-mcp
The shopify-mcp server provides comprehensive Shopify Admin API management, enabling full CRUD operations across core Shopify resources, plus optional AI-driven product image generation via ComfyUI.
Products & Variants
List, get, create, update, delete products; upload/attach images
Manage variants: bulk create/update/delete, reorder, add options (Size, Color, etc.)
Orders
List and retrieve orders with line items
Draft Orders
List, get, create, update, complete, and delete draft orders
Customers
List customers with query filters
Inventory & Locations
Set absolute on-hand inventory at a specific location; list store locations
Metafields
Upsert, list, and delete metafields on any supported resource (products, variants, collections, customers, orders, shop)
Collections & Tagging
Full CRUD for collections; add/remove products from manual collections; add/remove tags on any taggable resource
Webhooks
List, get, create, update, and delete webhook subscriptions
Metaobjects
Discover metaobject definitions; list, get, create, update, and delete metaobjects
Fulfillment
List/get fulfillment orders and fulfillment records; create fulfillments (partial supported, with tracking and customer notifications); update tracking; cancel fulfillments
Analytics
Run ShopifyQL queries, returning results as ASCII tables or raw JSON
ComfyUI Bridge (requires COMFYUI_URL configured)
Generate an AI image and create a new Shopify product in one call
Generate an AI image and attach it to an existing product
Refine a product's featured image via img2img
Bulk regenerate images for all products matching a query
Provides comprehensive Shopify Admin API integration with tools for product management, inventory control, order fulfillment, customer management, collections, webhooks, metafields, draft orders, and analytics through ShopifyQL queries.
shopify-mcp
MCP server for Shopify. Full Admin GraphQL API tooling plus an AI-driven product creation bridge via ComfyUI image generation.
The pitch
Every other Shopify MCP is a plain Admin API wrapper. This one pairs with @miller-joe/comfyui-mcp so you can say things like:
"Create a product called 'Nebula Dreamer'. Generate a cosmic abstract image for it, description matching the vibe, tagged astrology, status draft."
Claude then runs ComfyUI, gets an image back, creates the Shopify product, and attaches the image, all in one call.
Related MCP server: comfyui-mcp
Install
# npx, no install
npx @miller-joe/shopify-mcp \
--shopify-store your-store.myshopify.com \
--shopify-access-token shpat_xxx
# Docker
docker run -p 9110:9110 \
-e SHOPIFY_STORE=your-store.myshopify.com \
-e SHOPIFY_ACCESS_TOKEN=shpat_xxx \
-e COMFYUI_URL=http://comfyui:8188 \
ghcr.io/miller-joe/shopify-mcp:latestConnect an MCP client
claude mcp add --transport http shopify http://localhost:9110/mcpOr point your MCP gateway at the Streamable HTTP endpoint.
Configuration
CLI flag | Env var | Default | Notes |
|
| (required) |
|
|
| (required) | Admin API token ( |
|
|
| GraphQL Admin API version |
|
|
| Bind host (HTTP mode only) |
|
|
| Bind port (HTTP mode only) |
|
| (unset) | Speak MCP over stdio instead of HTTP. Use when launched as a subprocess by a stdio-first MCP client (Claude Desktop, mcp-inspector). |
|
| (optional) | Enables bridge tools when set |
|
| same as | External URL used for image references passed to Shopify |
(no flag) |
|
| Default checkpoint for bridge tools |
Transports
The server speaks streamable HTTP by default (great for Claude Code, MetaMCP, raw fetch). Pass --stdio (or set MCP_TRANSPORT=stdio) to switch into stdio mode, which is what stdio-first clients like Claude Desktop and the MCP Inspector expect:
// claude_desktop_config.json
{
"mcpServers": {
"shopify": {
"command": "npx",
"args": ["-y", "@miller-joe/shopify-mcp", "--stdio"],
"env": {
"SHOPIFY_STORE": "my-store.myshopify.com",
"SHOPIFY_ACCESS_TOKEN": "shpat_…"
}
}
}
}Getting a Shopify access token
Easy path, existing dev store: Shopify Admin → Apps → Develop apps → Create custom app → enable relevant Admin API scopes (write_products, read_orders, write_inventory, read_customers) → install → copy the admin API access token (starts with shpat_).
For new apps (post-Jan 2026): legacy custom-app tokens are deprecated for freshly-created apps. Use the Dev Dashboard token-exchange flow once to obtain a working token, then supply it here. Multi-tenant OAuth is on the roadmap.
Tools
Core Admin
Tool | Description |
| Paginated product search with Shopify query syntax |
| Fetch one product with variants, images, media |
| Create a product (default DRAFT); optionally attach images |
| Update title, description, tags, status, etc. |
| Attach a public image URL to an existing product |
| List orders, newest first, with query filters |
| Fetch one order with line items |
| Set absolute on-hand inventory at a location |
| List store locations (for inventory ops) |
| List customers with query filters |
Metafields
Tool | Description |
| Upsert a metafield on any |
| List metafields for a resource, optionally filtered by namespace |
| Delete a metafield by (ownerId, namespace, key) |
Draft orders
Tool | Description |
| List draft orders with Shopify query filters |
| Fetch one draft order with its line items |
| Create a draft order. Line items can be variant refs or custom (title + price). |
| Update customer, line items, tags, note, email |
| Convert a draft order to a real order. |
| Delete a non-completed draft order |
Webhooks
Tool | Description |
| List webhook subscriptions; filter by topic(s) |
| Fetch a single subscription |
| Subscribe an HTTPS callback URL to a topic (e.g. |
| Change callback URL, format, or field/metafield filters |
| Delete a subscription |
Metaobjects
Tool | Description |
| Discover metaobject types (schemas) on the store, including field definitions |
| List metaobjects of a given type |
| Fetch one metaobject with all its fields |
| Create a metaobject (type must already exist as a definition). Supports |
| Upsert fields, change handle, toggle publishable status |
| Delete a metaobject |
Fulfillment
Tool | Description |
| List an order's fulfillment orders (one per shipping location), with remaining quantities per line item |
| Fetch a single fulfillment order |
| Fetch a single fulfillment (shipment record) with tracking info |
| Mark fulfillment orders (or specific quantities) as fulfilled. Optionally attach tracking and notify the customer. |
| Update carrier/number/url on an existing fulfillment |
| Cancel a fulfillment by ID |
Partial fulfillment is supported. Pass specific fulfillmentOrderLineItems with quantity per line, or omit the array to fulfill everything on the fulfillment order.
Variants and product options
Tool | Description |
| List all variants of a product with selected options, price, SKU, inventory |
| Bulk-create variants (up to 100) with option values, price, SKU, compareAtPrice, initial inventory |
| Bulk-update variant price, compareAtPrice, SKU, barcode, taxable, inventoryPolicy, option values |
| Bulk-delete variants from a product |
| Set 1-indexed positions for variants |
| Add options (Size / Color / etc.) with their possible values. Up to 3 options per product. |
For an entirely new product, creating the first real variant requires strategy="REMOVE_STANDALONE_VARIANT" to replace the auto-generated "Default Title" variant.
Collections and tagging
Tool | Description |
| List collections with query filters |
| Fetch one collection with its products |
| Create a manual collection, optionally seeded with products |
| Update title, description, or handle |
| Delete a collection |
| Add products to a manual collection (async job on Shopify's side) |
| Remove products from a manual collection |
| Add tags to any taggable resource (Product, Order, Customer, DraftOrder, Collection) |
| Remove tags from a taggable resource |
Analytics (ShopifyQL)
Tool | Description |
| Run a ShopifyQL query and render the result as an ASCII table. Pass |
Examples:
FROM sales SHOW total_sales BY day SINCE -30d TIMESERIESFROM products SHOW product_title, quantity_sold BY product_id SINCE -7d ORDER BY quantity_sold DESC LIMIT 10
ComfyUI bridge (when COMFYUI_URL is configured)
Tool | Description |
| Generate an image and create a product with it, in one call. Title and description derive from the prompt if not given. |
| Generate an image and attach it to an existing product. |
| Run img2img on a product's featured image (or an explicit URL) and attach the refined result. Tune |
| For all products matching a query, run the generator with a templated prompt and attach fresh images. |
Template placeholders for bulk_regenerate_images: {title}, {handle}.
Example: the whole pitch in one call
Claude, use generate_and_create_product:
prompt: "minimalist sunset mountain silhouette, warm gradient, vector style"
title: "Mountain Sunset Poster"
status: DRAFT
tags: ["posters", "nature", "minimalist"]ComfyUI generates the image, Shopify creates the product with the image attached, and you get the product ID and image URL back. One prompt, one call, real listing.
Architecture
┌────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ MCP client │────▶│ shopify-mcp │────▶│ Shopify Admin │
│ (Claude etc.) │◀────│ (this server) │◀────│ GraphQL API │
└────────────────┘ └────────┬─────────┘ └─────────────────┘
│
│ (bridge tools only)
▼
┌──────────────────┐
│ ComfyUI │
│ (txt2img) │
└──────────────────┘Bridge tools call ComfyUI directly over HTTP, get an image URL, and pass it to Shopify's productCreateMedia mutation. Shopify fetches and hosts the image on its CDN.
Development
git clone https://github.com/miller-joe/shopify-mcp
cd shopify-mcp
npm install
npm run dev # hot reload via tsx watch
npm run build
npm run typecheck
npm testRequires Node 20+.
Roadmap
Shipped:
Core products CRUD plus image attach
Orders read, Inventory set + locations, Customers read
ComfyUI bridge:
generate_and_create_product,generate_product_image,bulk_regenerate_imagesMetafields:
set_metafield,list_metafields,delete_metafieldDraft orders: create / update / complete / delete / list / get
Collections and tagging: CRUD, product add/remove,
add_tags/remove_tagsVariants and product options: bulk create / update / delete / reorder plus
add_product_optionsFulfillment: list/get fulfillment orders, create fulfillment (partial supported), update tracking, cancel
Webhooks: list / get / create / update / delete
Metaobjects: definitions list plus metaobject CRUD
ShopifyQL analytics:
run_shopifyql_querywith ASCII-table renderingImage refinement bridge:
refine_product_image(ComfyUI img2img on product images)
Planned:
OAuth token-exchange flow for new-app auth.
License
MIT © Joe Miller
Support
If this saves you time, consider supporting development:
Available Tools
58 toolsadd_product_optionsA
Add new options (like Size, Color, Material) to an existing product, along with their initial possible values. Shopify caps products at 3 options total — passing more is rejected. Adding an option creates new option-values that existing variants must be assigned to (Shopify auto-assigns the first value if not specified). After adding, use create_variants to add SKUs across the new option-value combinations. Cannot remove options via this tool — that requires re-creating the product.
Inputs: productId (required), options (required).
add_products_to_collectionA
Add one or more products to a manual collection. Runs as an async background job on Shopify's side — the response includes a job ID and done flag, so very large batches may still be queued when the call returns. Smart collections (rule-based) reject manual additions; this tool only works on manual collections. Duplicates are silently ignored.
Inputs: collectionId (required), productIds (required).
add_tagsA
Add tags to any taggable Shopify resource — Product, Order, Customer, DraftOrder, Collection, Article, Blog. Tags are stored as a unique set per resource; adding a tag that already exists is a no-op. Useful for ad-hoc segmentation, marketing campaigns, or driving smart collection membership rules. Pair with remove_tags to fully manage taxonomy.
Inputs: id (required), tags (required).
cancel_fulfillmentA
Cancel an existing fulfillment — use when an item that was marked shipped won't actually ship (lost in warehouse, address bounced, customer cancelled). Restores remaining quantity on the underlying fulfillment order so the items can be re-fulfilled later. Does NOT issue a refund — combine with order-level refund tools if money needs to come back to the customer. Returns the new fulfillment status (typically CANCELLED).
Inputs: id (required).
cancel_orderA
Cancel a Shopify order. Triggers an async job (the response includes a jobId; cancellation finishes shortly after the call returns). Combine with refund: true to issue a full refund of any captured payment, or refund: false if the order is unpaid or you'll handle refunds separately via refund_order. restock: true restores cancelled line items back to inventory; set false if items were physically lost/damaged. notifyCustomer: true sends the cancellation email. Cannot cancel an already-cancelled order or one with active fulfillments still in flight (cancel those fulfillments first via cancel_fulfillment).
Inputs: id (required), reason (required), refund, restock, +2 more.
complete_draft_orderA
Convert an OPEN draft order into a real Shopify order. With paymentPending=false (default), Shopify attempts to capture payment immediately; the call fails if no payment method is on file. With paymentPending=true, the order is created in payment-pending status — useful when collecting payment offline (cash, bank transfer, manual processing). Once completed, the draft transitions to COMPLETED and the new order's GID is returned. The transition is one-way: completed drafts cannot be re-opened or edited via draft tools (use the order tools, or refund/cancel for the resulting order).
Inputs: id (required), paymentPending.
create_collectionA
Create a new manual collection (rule-based 'smart' collections aren't supported here — use the Shopify admin for those). Title is required; description, handle, and an initial product list are optional. Returns the new collection's GID, which you'll need for subsequent add_products_to_collection or update_collection calls. Side effect: collection becomes immediately visible in the storefront unless you've configured publication channels separately.
Inputs: title (required), description, handle, productIds.
create_customerA
Create a new customer record. At minimum, supply email or phone (one is required for the customer to be reachable; both is fine). Email and phone must each be unique across the store — duplicates trigger validation errors. Optionally seed addresses (the first becomes the default shipping address), apply tags for segmentation, and set email-marketing consent. Default consent is NOT_SUBSCRIBED — only set SUBSCRIBED when you have documented opt-in (legal requirement in many jurisdictions). Returns the new customer's GID for use as customerId in create_order, create_draft_order, etc.
Inputs: email, firstName, lastName, phone, +4 more.
create_draft_orderA
Create a new draft order — Shopify's term for an editable cart/quote not yet placed as an order. Each line item is EITHER a variant reference (variantId + quantity) for catalog products, OR a custom item (title + originalUnitPrice + quantity) for one-off charges or services not in the catalog. Optionally attach a customer, email, internal note, tags, and choose whether to copy the customer's default address. Returns the new draft's GID and an invoice URL the customer can use to pay. Drafts stay OPEN until you call complete_draft_order or send the invoice.
Inputs: lineItems (required), customerId, email, note, +2 more.
create_fulfillmentA
Mark items as shipped — creates a fulfillment record covering one or more fulfillment orders. For each fulfillment order in the request, you can either fulfill everything still remaining (omit fulfillmentOrderLineItems) or specify per-line {id, quantity} pairs for partial shipments. Optionally attach tracking info (carrier + number; URL is auto-derived for major carriers like USPS/UPS/FedEx/DHL) and set notifyCustomer=true to send the shipment-confirmation email. The fulfillmentOrderLineItem IDs come from list_fulfillment_orders. Side effects: customer-facing email if notifyCustomer is true; webhook fires; remaining quantities decrement.
Inputs: lineItemsByFulfillmentOrder (required), trackingInfo, notifyCustomer.
create_metaobjectA
Create a new metaobject (instance) of an existing type. The type must match a registered metaobject definition — call list_metaobject_definitions first if you're unsure. fields is an array of {key, value} pairs; values are always strings (JSON/reference fields take a JSON-encoded string, primitives take literal text). handle is optional; Shopify generates one from the displayName field if present. status only applies to types that have the publishable capability — passing it for non-publishable types is silently ignored. Returns the new metaobject's GID for use in subsequent set_metafield calls (e.g. linking the metaobject to a product via a metaobject_reference metafield).
Inputs: type (required), fields (required), handle, status.
create_orderA
Create a real Shopify order directly, bypassing the draft-order flow. Each line item is either a variant reference (variantId + quantity) or a custom item (title + priceSet + quantity). Use when you need to import historical orders, record a phone/in-person sale, or create an order without involving Shopify's checkout pricing engine. For interactive carts where Shopify should compute taxes/shipping/discounts, use create_draft_order then complete_draft_order instead. Defaults: PENDING financial status, customer not notified, inventory decremented respecting each variant's oversell policy.
Inputs: lineItems (required), email, customerId, tags, +4 more.
create_productA
Create a new product. The product is created first, then any image_urls (publicly fetchable) are attached as a follow-up call — Shopify pulls each URL and hosts the image on its CDN. The default status is DRAFT to prevent accidentally publishing half-configured products to the storefront; pass status=ACTIVE only when you're ready to go live. New products start with a single hidden 'Default Title' variant; to add real variants with options, call create_variants with strategy='REMOVE_STANDALONE_VARIANT'. Returns the new product's GID and handle.
Inputs: title (required), description, vendor, product_type, +3 more.
create_variantsA
Create one or more variants on an existing product. Each variant's optionValues must cover EVERY option declared on the product (Size + Color + Material if there are 3 options) — partial coverage is rejected. New products from create_product start with a single hidden 'Default Title' variant; when adding the first real variants, pass strategy='REMOVE_STANDALONE_VARIANT' so Shopify replaces the placeholder rather than leaving it. inventoryQuantities seeds initial stock per location at create time; for ongoing changes use set_inventory_quantity instead.
Inputs: productId (required), variants (required), strategy.
create_webhookA
Subscribe to a Shopify event topic and have payloads POSTed to your HTTPS endpoint. Common topics: ORDERS_CREATE, ORDERS_PAID, ORDERS_FULFILLED, PRODUCTS_CREATE, PRODUCTS_UPDATE, INVENTORY_LEVELS_UPDATE, CUSTOMERS_CREATE, APP_UNINSTALLED. Use includeFields to receive only specific fields in the payload (reduces bandwidth and avoids leaking unrelated data). metafieldNamespaces opts in to including metafields from the listed namespaces. callbackUrl must be HTTPS in production. Returns the new subscription's GID; verify delivery is working with a few real events before relying on it.
Inputs: topic (required), callbackUrl (required), format, includeFields, +1 more.
delete_collectionA
Permanently delete a collection. Products inside it are NOT deleted — only the grouping is removed; products keep all their other associations (other collections, tags, inventory). Irreversible. Confirm the collection ID with get_collection before calling. Returns the deleted collection ID, or a 'nothing deleted' message if the GID didn't match anything.
Inputs: id (required).
delete_draft_orderA
Permanently delete a draft order. Only OPEN/INVOICE_SENT drafts can be deleted — completed drafts are real orders and orders cannot be deleted (cancel them instead). Irreversible. Returns the deleted GID, or a no-op message if the GID didn't match anything.
Inputs: id (required).
delete_metafieldA
Permanently delete a single metafield by (ownerId, namespace, key). Irreversible — the value is gone after this call. Use list_metafields first to confirm the namespace and key, since typos result in a no-op rather than an error. Other metafields on the same resource are unaffected. To delete every metafield on a resource, you'd need a list+loop pattern; this tool only deletes one at a time.
Inputs: ownerId (required), namespace (required), key (required).
delete_metaobjectA
Permanently delete a metaobject by GID. Irreversible. Any metafield references pointing at this metaobject will become broken — Shopify does NOT auto-clean references, you have to find and fix them. Use get_metaobject to confirm the right record before deleting. Returns the deleted GID, or a no-op message if nothing matched.
Inputs: id (required).
delete_variantsA
Permanently delete one or more variants from a product. Irreversible. Each product must keep at least one variant — Shopify rejects requests that would empty the product (delete the whole product via update_product status:ARCHIVED, or use the admin UI for full deletion). Variants in completed orders are kept-but-hidden by Shopify automatically; the historical record on the order is preserved.
Inputs: productId (required), variantIds (required).
delete_webhookA
Permanently unsubscribe from an event topic by deleting the webhook subscription. Stops all future deliveries to that endpoint for that topic — irreversible (you'd have to re-create with create_webhook). Use when retiring an integration or switching topics. Returns the deleted GID, or a no-op message if nothing matched.
Inputs: id (required).
get_collectionA
Fetch a single collection by GID with full details — title, handle, sort order, description, and the first N products inside it. Pass productsFirst=0 for metadata-only when you don't need the products array. Returns a friendly text view; pageInfo flags when more products exist beyond the requested page.
Inputs: id (required), productsFirst.
get_draft_orderA
Fetch a single draft order with full details: status, customer, line items (with quantity, title, and unit price), invoice URL, and the resulting real order if it's already been completed. Use to inspect a draft before calling update_draft_order or complete_draft_order. Returns a friendly text summary.
Inputs: id (required).
get_fulfillmentA
Fetch a single fulfillment (a shipment record produced by create_fulfillment) by GID. Returns its status (SUCCESS/CANCELLED/etc.), tracking entries (carrier, number, URL), the parent order, and timestamps. Use after create_fulfillment to confirm the shipment took, or when a webhook delivers a fulfillment GID and you need the details.
Inputs: id (required).
get_fulfillment_orderA
Fetch a single fulfillment order by GID with its full line-item set and remaining quantities. Use this when you have the FulfillmentOrder ID directly (e.g. from a webhook payload) and want detail without having to look up its parent order first. Returns the same shape as list_fulfillment_orders for one record.
Inputs: id (required).
get_metaobjectA
Fetch a single metaobject by GID and return its display name, handle, type, publishable status, and all of its field values. Field values longer than 120 characters are truncated in the rendered output (full values are still on the underlying record). Use list_metaobjects to discover GIDs first.
Inputs: id (required).
get_orderA
Fetch a single order's full record by GID or numeric ID — includes header fields (email, totals, both status flags, timestamps), full line items (title + quantity), and the customer email if on file. Returned as JSON for downstream tooling. Use list_orders to discover order IDs first. To inspect or act on shipments for this order, follow up with list_fulfillment_orders.
Inputs: id (required).
get_productA
Fetch a single product's full record by GID or numeric ID. Returns header fields (title, handle, status, vendor, productType, description, tags), inventory totals, the first 10 images and 10 media items, and the first 20 variants with their prices, SKUs, inventory quantities, and inventoryItem GIDs. Returned as JSON for downstream tooling. The variant inventoryItem GIDs are needed by set_inventory_quantity. For more than 20 variants, follow up with list_variants.
Inputs: id (required).
get_webhookA
Fetch a single webhook subscription's full configuration by GID — topic, endpoint, format, API version, includeFields filter, metafield namespaces, and timestamps. Use to verify subscription details before update or delete, or when debugging delivery issues.
Inputs: id (required).
list_collectionsA
List collections in the store, most recently updated first. Returns each collection's title, handle, ID, and product count. Supports Shopify's collection query syntax for filtering by title, type, or update time. Cursor-paginated; pass after from the previous response to advance. Use this to find a collection's GID before calling get_collection, update_collection, or add_products_to_collection.
Inputs: first, query, after.
list_customersA
List customers in the store, newest first by creation date. Returns each customer's display name, email, lifetime order count, and total amount spent (in shop currency). Supports Shopify's customer query syntax for filtering by email, tag, order count, spend, marketing-consent, account state, and more. Cursor-paginated; pass after to advance pages. Use this to find customer GIDs before referencing them in draft orders or to segment for marketing.
Inputs: first, query, after.
list_draft_ordersA
List draft orders (carts/quotes that haven't yet been completed into real orders), most recently updated first. Returns each draft's name (e.g. 'D1023'), status (OPEN/COMPLETED/INVOICE_SENT), total price, customer name, and whether it's already been converted to an order. Supports Shopify's draft-order query syntax for filtering by status, customer, tag, or update time. Cursor-paginated.
Inputs: first, query, after.
list_fulfillment_ordersA
List the fulfillment orders attached to a Shopify order. A fulfillment order groups line items by the location that will ship them — a single order can have multiple fulfillment orders if items split across warehouses. Each one tracks per-line remaining quantity (totalQuantity minus what's already shipped/cancelled). Returns the assigned location, destination address, and line-item progress for each. This is the primary read tool you'll call before create_fulfillment to figure out which fulfillmentOrderLineItem IDs and quantities to mark as shipped.
Inputs: orderId (required).
list_locationsA
List the store's locations — physical or virtual places where inventory is stocked or fulfilled from (warehouses, retail stores, drop-ship partners). Returns each location's name, active/inactive flag, city + country, and GID. The location GID is required by set_inventory_quantity and create_fulfillment. Inactive locations still exist but cannot accept new inventory or fulfillments.
Inputs: first.
list_metafieldsA
List metafields attached to a single Shopify resource. Returns each metafield's namespace.key, type, current value, and optional description. Pass a namespace to scope the read to one app/integration's metafields (recommended when the resource has many). Empty result is normal for resources without metafields. Use this to inspect existing custom data before calling set_metafield, or to audit which apps have written what to a record.
Inputs: ownerId (required), namespace, first.
list_metaobject_definitionsA
List the metaobject definitions (custom types/schemas) registered on this Shopify store, with their field definitions. Each definition declares a type handle, a set of typed fields, and which fields are required. Use this tool to discover what custom data shapes the store supports before calling list_metaobjects (which queries instances of one type) or create_metaobject (which creates a new instance). Cursor-paginated.
Inputs: first, after.
list_metaobjectsA
List instances of a single metaobject type — e.g. all 'lookbook' or 'product_feature' entries. Returns each metaobject's display name, handle, GID, and (when the type is publishable) ACTIVE/DRAFT status. The type handle comes from list_metaobject_definitions. Cursor-paginated; pass after to advance pages. To inspect an individual metaobject's full field values, follow up with get_metaobject.
Inputs: type (required), first, after.
list_ordersA
List orders in the store, newest first by creation date. Returns each order's name (e.g. '#1042'), total price (in shop currency), financial status (paid/pending/refunded), fulfillment status (fulfilled/unfulfilled/partial), and timestamp. Supports Shopify's order query syntax for filtering by status, date range, customer, tags, and more. Cursor-paginated; the last line shows the next cursor when more pages exist. Use this to find order GIDs before calling get_order or list_fulfillment_orders.
Inputs: first, query, after.
list_productsA
List products in the store with cursor-based pagination. Returns each product's title, status (ACTIVE/DRAFT/ARCHIVED), GID, and total inventory across all variants/locations. Supports Shopify's product query syntax for filtering by status, vendor, type, tag, title (wildcard), and date ranges. The last line of output shows the next cursor when more pages exist — pass it as after on the next call. Use this to find product GIDs before calling get_product, update_product, list_variants, or any product-scoped tool.
Inputs: first, query, after.
list_variantsA
List all variants of a single product, plus the product's option definitions (Size, Color, etc.) and possible values. For each variant returns: title, GID, price, compareAtPrice, SKU, barcode, current inventory quantity, taxable flag, inventory policy, and the option-value combination that produced it. Use to inspect a product's full SKU matrix before calling create_variants/update_variants/delete_variants.
Inputs: productId (required), first.
list_webhooksA
List webhook subscriptions on the store. Each subscription wires a Shopify event topic (ORDERS_CREATE, PRODUCTS_UPDATE, INVENTORY_LEVELS_UPDATE, etc.) to a delivery target — typically an HTTPS callback URL, but Pub/Sub and EventBridge are also supported. Returns each subscription's topic, delivery format (JSON/XML), endpoint, API version, and any field/metafield filters applied. Filter by topic to scope the result. Use this to audit existing automation hooks before creating new ones.
Inputs: first, topics, after.
refund_orderA
Issue a refund against an order — for specific line items (with quantities and optional restock behaviour), for shipping, or both. Returns the new refund's GID and total amount refunded. To refund a full order use cancel_order with refund=true instead (one-step). Use this tool when refunding partially: just one item, just shipping, an adjustment without item breakdown, or a return that needs explicit restock-to-location handling. The restockType per line item controls inventory behaviour: NO_RESTOCK (default — the items aren't coming back), CANCEL (restock as if cancelled), RETURN (restock with a return record at the given locationId). Pass notify: true to email the customer.
Inputs: id (required), refundLineItems, shipping, currency, +2 more.
remove_products_from_collectionA
Remove one or more products from a manual collection. Like add_products_to_collection, this runs as an async job for larger batches — the response includes job ID and done status. Products not currently in the collection are silently skipped. Removes the membership only; products themselves are not deleted or modified.
Inputs: collectionId (required), productIds (required).
remove_tagsA
Remove tags from any taggable Shopify resource (Product, Order, Customer, DraftOrder, Collection, Article, Blog). Tags not currently on the resource are silently ignored. To replace the full tag set rather than remove specific ones, use update_product/update_customer/etc. with the new tag list.
Inputs: id (required), tags (required).
reorder_variantsA
Set the display order of variants on a product. Positions are 1-indexed and must be unique across all variants in the product (you can't have two variants both at position 2). Affects the order variants appear on the product page and in Shopify admin. Only provide the variants whose positions are changing — others stay where they are.
Inputs: productId (required), positions (required).
run_shopifyql_queryA
Run a ShopifyQL query against the store and return the result as a rendered ASCII table. ShopifyQL is Shopify's SQL-like analytics language. Examples: 'FROM sales SHOW total_sales BY day SINCE -30d TIMESERIES', 'FROM products SHOW product_title, quantity_sold BY product_id SINCE -7d ORDER BY quantity_sold DESC LIMIT 10'.
Inputs: query (required), raw.
set_inventory_quantityA
Set the absolute available inventory for one variant at one location. This is a direct overwrite, not an adjustment — passing 5 sets the count to 5 regardless of what was there before. The pair (inventory_item_id, location_id) uniquely identifies the inventory level: get inventory_item_id from get_product (it's on each variant) and location_id from list_locations. Records a Shopify inventory adjustment with the reason code you provide. Use 'correction' for cycle counts/manual fixes, 'received' when receiving stock, 'cycle_count_available' for systematic counts. Tracks history; the audit log shows who/when via the API user.
Inputs: inventory_item_id (required), location_id (required), quantity (required), reason.
set_metafieldA
Create or update (upsert) a single metafield on any supported Shopify resource — product, variant, collection, customer, order, draft order, shop, or shop policies. The (ownerId, namespace, key) triple is the unique identifier; calling this tool with an existing triple replaces the value, otherwise creates a new metafield. The type must be a Shopify-supported metafield type and the value must serialize per that type — e.g. JSON types take a JSON string, references take a target GID, primitives take literal text. Errors come back as MCP tool errors with the validation messages from Shopify.
Inputs: ownerId (required), namespace (required), key (required), type (required), +1 more.
update_collectionA
Update an existing collection's title, description (HTML), or URL handle. Only provide fields you want to change; omitted fields are left untouched. Changing the handle changes the storefront URL — Shopify does NOT create automatic redirects from the old slug, so existing links break. To change collection membership use add_products_to_collection / remove_products_from_collection instead.
Inputs: id (required), title, description, handle.
update_customerA
Update an existing customer's profile fields — email, name, phone, tags, internal note. Only provide fields you want changed; omitted fields stay as-is. Tags is a full replacement (use add_tags / remove_tags for additive/subtractive changes). Email and phone changes still need to satisfy the per-store uniqueness constraint. To change addresses, use Shopify's address-specific mutations (not yet exposed by this server). To change marketing consent, the dedicated customerEmailMarketingConsentUpdate mutation is preferred.
Inputs: id (required), email, firstName, lastName, +3 more.
update_draft_orderA
Modify an existing OPEN draft order's customer, email, note, tags, or line items. Important: if lineItems is provided, it REPLACES the existing items entirely (not a merge or append) — read the current items first if you need to preserve any. Cannot update completed drafts; those are real orders. To pause and pick up a draft later, leave it OPEN and re-invoke update later; nothing here triggers payment.
Inputs: id (required), lineItems, customerId, email, +2 more.
update_fulfillment_trackingA
Update or add tracking info on an existing fulfillment after the fact. Use this when you've already called create_fulfillment but didn't have the carrier/tracking number yet, or when a tracking number was wrong and needs fixing. company+number is enough; Shopify auto-derives the URL for known carriers (USPS, UPS, FedEx, DHL, etc.). Set notifyCustomer=true to re-send the shipping email with the updated tracking. Omitted fields are left unchanged.
Inputs: fulfillmentId (required), company, number, url, +1 more.
update_metaobjectA
Update an existing metaobject's handle, field values, or publishable status. Fields are upserted by key — pass only the fields you want to change; omitted fields keep their current values. To clear a field, pass an empty string or null-ish value matching the field type. If you change the handle, set redirectNewHandle=true to have Shopify redirect from the old handle on the storefront. The type cannot be changed by this tool — delete and recreate to change type.
Inputs: id (required), handle, fields, status, +1 more.
update_orderA
Update an existing order's metadata: email, tags, internal note, or custom attributes. Most order fields are immutable post-creation in Shopify (line items, totals, customer-of-record can't be changed via the Admin API after the fact) — for those, use refund_order or cancel_order to back out, then create a corrected order. Tags and customAttributes are full replacements: read the current values first if you want to merge rather than replace. Use when fixing a typo'd email, adding a fulfillment-team note, or attaching internal segmentation tags.
Inputs: id (required), email, tags, note, +1 more.
update_productA
Update an existing product's core fields — title, description (HTML), vendor, productType, tags, or status. Only provide fields you want changed; omitted fields are left untouched. Setting status=ARCHIVED hides the product from the storefront but preserves order history. To change variants, prices, or inventory use create_variants/update_variants and set_inventory_quantity. To change images use upload_product_image (or one of the bridge tools to generate new ones).
Inputs: id (required), title, description, vendor, +3 more.
update_variantsA
Update one or more existing variants in a single call. Editable fields: price, compareAtPrice (set to null to clear), SKU, barcode, taxable, inventoryPolicy (DENY blocks oversells, CONTINUE allows backorders), and optionValues (e.g. rename a size). Per-variant only; only the fields you provide are written. For inventory quantity changes use set_inventory_quantity — this tool deliberately doesn't accept quantities to keep that audit trail in one place.
Inputs: productId (required), variants (required).
update_webhookA
Modify an existing webhook subscription's callback URL, payload format, includeFields filter, or metafield-namespace filter. Topic cannot be changed — to switch event types, delete and recreate the subscription. Use when migrating an endpoint to a new domain, switching from JSON to XML, or tightening payload size by adding includeFields. Omitted parameters are left unchanged.
Inputs: id (required), callbackUrl, format, includeFields, +1 more.
upload_product_imageA
Attach an image to an existing product by URL. Shopify fetches the URL server-side and hosts the file on its CDN — the URL must be publicly reachable from Shopify's network. Multiple calls add multiple images; this tool does not replace existing images. Use the bridge tools (generate_product_image, refine_product_image) instead when you want the image generated by ComfyUI rather than provided as a URL.
Inputs: product_id (required), image_url (required), alt_text.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 58 tools
Each tool targets a specific resource or action within Shopify's extensive API. Descriptions clearly distinguish overlapping areas like metaobjects vs metafields, and add/remove tags vs update product tags. No two tools appear to do the same thing.
All tools follow a consistent verb_noun pattern in snake_case (e.g., create_product, list_orders, set_inventory_quantity). The only slight deviation is run_shopifyql_query, but it still fits the pattern.
58 tools cover a very broad Shopify surface (products, orders, customers, collections, metaobjects, webhooks, fulfillments, etc.). While high, each tool serves a distinct purpose; the count is somewhat justified by the platform's complexity, though slightly above the typical well-scoped range.
The tool set covers CRUD for all major resources (products, variants, orders, customers, collections, metaobjects, metafields, webhooks) plus inventory management, fulfillments, and analytics queries. Only minor niche operations (e.g., bulk adjustments, advanced discounting) are absent, which is acceptable for an MCP server.
Maintenance
Related MCP Connectors
Shopify MCP Pack — wraps the Shopify Admin REST API (2024-01)
Hosted Shopify MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Unified MCP server for 70+ eCommerce platforms: products, orders, customers, and more.
AI commerce for Shopify: product search, comparison, recommendations, and checkout via MCP.
Related MCP Servers
- AlicenseDqualityDmaintenancefor shopify api interaction including product, customer, order52,952 npm239MIT
- AlicenseAqualityDmaintenanceMCP server for ComfyUI — text-to-image, variations, img2img refine, upscale, image proxy, and workflow runner.15120 npm2MIT
- AlicenseCqualityDmaintenanceAn MCP server providing AI agents with full access to the Shopify Admin API via 136 tools for managing products, orders, customers, collections, and more.10045 npmMIT
- AlicenseNot gradedqualityCmaintenanceA comprehensive MCP server for Shopify Admin API integration, enabling AI assistants to manage products, orders, customers, inventory, analytics, and more through natural language.25 npm20MIT