Skip to main content
Shopify is a read + guardrailed write connector, called via tools/call over POST /shopify/mcp. The connector talks only to Shopify’s Admin GraphQL API (version 2026-04) and is connected through OAuth on your own store (see Forbind Shopify).
Endpoint: https://mcp.consile.ai/shopify/mcp. Shopify is its own named connector with only its own tools. Tool names are namespaced shopify__<tool> in Claude/ChatGPT; the bare names are used here for readability.
Public Shopify apps created on/after 2026-04-01 must use an expiring offline token, which Shopify issues only when the code exchange opts in with expiring=1. A connection that holds an old permanent token gets a blanket HTTP 403 (“GraphQL Client: Forbidden”) on every call and must reconnect once. A missing scope / Protected Customer Data shortfall is different — it comes back as HTTP 200 with a body error, not a 403. An expired token surfaces as AccessTokenExpiredError. See Errors & limits.

Write safety: guardrail model

The ten write tools share a connector-local guardrail (the same model the Meta Ads connector established). The platform’s readOnly flag is a hint only; the safety lives in the tool handlers.
  1. New products are created DRAFT (CREATE_DEFAULT_STATUS = "DRAFT"). A draft product is not visible in any sales channel until explicitly published/activated.
  2. confirm: true is required for any write that makes something LIVE (publish/unpublish, or status → ACTIVE), is ARCHIVED, changes a PRICE (variant price/compareAtPrice), changes INVENTORY (set/adjust stock), or is DESTRUCTIVE (delete variants).
  3. Without confirmation you get a WritePreview dry-run and no Shopify call is made. Re-run the identical call with confirm: true to apply.
  4. Failed mutations never look like success — a mutation that returns non-empty userErrors raises ShopifyUserError.
Orders, draft orders, customers, and discounts are structurally read-only: there are no write tools and no write scopes for them. The graphql_query escape hatch rejects any mutation/subscription document. This is a designed-in safety default (connector-local logic), not an unbreakable platform gate. See Handlinger & guardrails for the full cross-connector policy.

WritePreview shape

When a write requires confirmation but confirm is omitted or false, the tool returns this instead of calling Shopify:
{
  "preview": {
    "action": "publish_product",
    "summary": "Publish product 123 to 1 channel(s).",
    "request": {
      "method": "GRAPHQL",
      "mutation": "mutation Publish(...) {...}",
      "variables": { "id": "gid://shopify/Product/123", "input": [ ... ] }
    },
    "confirmHint": "Re-run the same call with confirm: true to apply this change."
  }
}

Shared parameters

Ids

All id arguments accept either a bare numeric id or a full GID (gid://shopify/<Type>/<n>). The connector normalises before calling the API.

Money

Money is Shopify MoneyV2 ({ amount, currencyCode }); amounts are decimal strings in the shop currency.

Pagination

limit
integer
default:"50"
Maximum rows to return (max 250). The client cursor-paginates a single page at 100 and follows cursors up to 25 pages / 250 rows.
query
string
Shopify search-query syntax, e.g. status:active, vendor:Acme, sku:ABC-1, financial_status:paid, email:a@b.com, country:DK.

Read tools (40)

All read tools are readOnly: true.

Shop & policies

ToolDescriptionKey inputsReturns
get_shopConnected store profilename, email, domains, currency, timezone, weight unit, plan
get_shop_policiesStore legal policiesrefund / privacy / TOS / shipping policy (type, title, url, body)

Products & variants

ToolDescriptionKey inputsReturns
list_productsList/search productslimit?, query?id, title, handle, status, vendor, type, tags, totalInventory + pageInfo
get_productOne product in detailid+ descriptionHtml, options, first 10 images, up to 50 variants
get_product_by_handleLook up product by URL handlehandlesingle product node (or null)
list_product_variantsList/search variantslimit?, query?id, title, sku, price, compareAtPrice, inventoryQuantity, product
get_product_variantOne variant in detailidprice, sku, barcode, options, inventoryQuantity, inventoryItem
list_product_mediaA product’s mediaid, limit?media nodes (type, alt, image url/width/height) + pageInfo

Collections

ToolDescriptionKey inputsReturns
list_collectionsList smart + manual collectionslimit?, query?id, title, handle, updatedAt, sortOrder
get_collectionOne collection + rule setid+ descriptionHtml, ruleSet (smart-collection rules)
get_collection_productsProducts in a collectionid, limit?product nodes + pageInfo

Publications (sales channels)

ToolDescriptionKey inputsReturns
list_publicationsSales-channel publicationslimit?id, name (use ids for publish/unpublish)
get_product_publicationsWhich channels a product is onid (product)per-publication isPublished + publishDate

Inventory

ToolDescriptionKey inputsReturns
list_locationsInventory locationslimit?id, name, isActive, address
get_locationOne location in detailidname, isActive, shipsInventory, fulfillsOnlineOrders, address
get_inventory_itemInventory item (SKU/cost)id (inventory item)sku, tracked, requiresShipping, unitCost, variant
get_inventory_levelsStock per location for an itemid (inventory item), limit?per-location available / on_hand / committed / incoming
get_variant_inventoryVariant stock across locationsid (variant)inventoryQuantity + per-location available/on_hand
list_inventory_transfersStock transfers between locationslimit?id, name, status, dateCreated · ⚠ version-sensitive
get_inventory_transferOne inventory transferidname, status, origin, destination · ⚠ version-sensitive
get_inventory_shipmentOne inventory shipmentidid, name, status · ⚠ version-sensitive

Orders & fulfillment

ToolDescriptionKey inputsReturns
list_ordersList orders, newest firstlimit?, query?name, dates, financial/fulfillment status, total, customer
get_orderOne order in detailidtotals, customer, shipping address, up to 50 line items
list_order_transactionsPayment transactions on an orderid (order)kind, status, gateway, processedAt, amount
list_order_fulfillmentsAn order’s fulfillmentsid (order)status, createdAt, trackingInfo (company, number, url)
list_fulfillment_ordersFulfillment orders (assignable, incl. 3PL)id (order), limit?status, requestStatus, assignedLocation + pageInfo
get_fulfillment_orderOne fulfillment orderidstatus, requestStatus, assignedLocation, line items

Draft orders

ToolDescriptionKey inputsReturns
list_draft_ordersList draft orderslimit?, query?name, status, total, customer
get_draft_orderOne draft order in detailidstatus, invoiceUrl, total, customer, line items

Customers & B2B companies

Customer and order records can carry personal data (name, email, phone, address). Accessing real-merchant PII requires Shopify’s Protected Customer Data approval for the app; the platform is read-through and never persists it.
ToolDescriptionKey inputsReturns
list_customersList/search customerslimit?, query?displayName, email, phone, numberOfOrders, amountSpent, defaultAddress
get_customerOne customer in detailidcontact, addresses, spend, tags
list_companiesList B2B companieslimit?, query?id, name, dates
get_companyOne B2B companyidmainContact, contacts (≤20), locations (≤20)

Discounts

ToolDescriptionKey inputsReturns
list_discountsAutomatic + code discounts (+ price rules)limit?, query?discount union (title, status, dates by type)
get_discountOne discount in detailid (discount node)discount union detail
list_code_discountsCode discounts + their codeslimit?, query?title, status, codes (first 5)

Checkouts, shipping & analytics

ToolDescriptionKey inputsReturns
list_abandoned_checkoutsAbandoned checkoutslimit?, query?abandonedCheckoutUrl, createdAt, total, customer
list_delivery_profilesShipping (delivery) profileslimit?id, name, default
run_analytics_queryShopifyQL analyticsquery (ShopifyQL string)tableData (columns + rowData) or parseErrors · ⚠ version-sensitive
graphql_queryRead-only Admin GraphQL escape hatchquery (must be a query), variables?raw data; rejects mutation/subscription documents

Write tools (10 guardrailed)

Write tools mutate your store. New products are created DRAFT and never go live until you publish/activate. Any action that makes something live, changes a price, changes inventory, deletes, or archives requires confirm: true. Without it the tool returns a WritePreview and calls no API.

create_product

Create a product. Created DRAFT by default.
title
string
required
status
string
default:"DRAFT"
ACTIVE (live) or ARCHIVED requires confirm: true; DRAFT is free.
descriptionHtml
string
vendor
string
productType
string
tags
string[]
confirm
boolean
Requires confirmation: only when status is ACTIVE or ARCHIVED.

update_product

Update a product’s fields.
id
string
required
title
string
descriptionHtml
string
vendor
string
productType
string
tags
string[]
status
string
confirm
boolean
Requires confirmation: only when statusACTIVE or ARCHIVED.

set_product_status

Set a product’s status.
id
string
required
status
string
required
ACTIVE, DRAFT, or ARCHIVED.
confirm
boolean
Requires confirmation: ACTIVE (live) and ARCHIVED; DRAFT is free.

create_product_variant

Add variants to an existing product.
productId
string
required
variants
object[]
required
Each: optionValues, price?, compareAtPrice?, sku?, barcode?, taxable?, inventoryPolicy?.
confirm
boolean
Requires confirmation: no (adding a variant is not a live/price/destructive action).

update_product_variant

Update existing variants (each entry needs an id).
productId
string
required
variants
object[]
required
Each must include id; may set price, compareAtPrice, sku, barcode, etc.
confirm
boolean
Requires confirmation: yes if a price changes (price/compareAtPrice); otherwise free.

delete_product_variant

Delete variants from a product.
productId
string
required
variantIds
string[]
required
confirm
boolean
required
Must be true to apply.
Requires confirmation: always (destructive).

publish_product

Publish a product to one or more sales channels (makes it live).
productId
string
required
publicationIds
string[]
required
Publication ids from list_publications.
confirm
boolean
required
Must be true to apply.
Requires confirmation: always (makes the product live).

unpublish_product

Remove a product from one or more sales channels.
productId
string
required
publicationIds
string[]
required
confirm
boolean
required
Must be true to apply.
Requires confirmation: always.

set_inventory_quantity

Set an absolute stock quantity at a location.
inventoryItemId
string
required
locationId
string
required
quantity
integer
required
name
string
default:"available"
available or on_hand.
reason
string
default:"correction"
confirm
boolean
required
Must be true to apply.
Requires confirmation: always (inventory change).

adjust_inventory_quantity

Adjust stock by a relative delta at a location.
inventoryItemId
string
required
locationId
string
required
delta
integer
required
Positive or negative.
name
string
default:"available"
reason
string
default:"correction"
confirm
boolean
required
Must be true to apply.
Requires confirmation: always (inventory change).

Code examples

{
  "name": "shopify__list_orders",
  "arguments": { "query": "financial_status:paid", "limit": 10 }
}
Shopify rate limits are cost-based (a leaky bucket). A throttled call returns HTTP 200 with a THROTTLED error; the client retries a bounded number of times, waiting for the bucket to refill. Per-request timeout is 20s. Some tools (list_inventory_transfers, get_inventory_transfer, get_inventory_shipment, run_analytics_query) are best-effort against the 2026-04 schema and may need a field tweak; the graphql_query escape hatch covers any gap. See Errors & limits.