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:

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

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.
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

Products & variants

Collections

Publications (sales channels)

Inventory

Orders & fulfillment

Draft orders

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.

Discounts

Checkouts, shipping & analytics


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.
string
required
string
default:"DRAFT"
ACTIVE (live) or ARCHIVED requires confirm: true; DRAFT is free.
string
string
string
string[]
boolean
Requires confirmation: only when status is ACTIVE or ARCHIVED.

update_product

Update a product’s fields.
string
required
string
string
string
string
string[]
string
boolean
Requires confirmation: only when statusACTIVE or ARCHIVED.

set_product_status

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

create_product_variant

Add variants to an existing product.
string
required
object[]
required
Each: optionValues, price?, compareAtPrice?, sku?, barcode?, taxable?, inventoryPolicy?.
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).
string
required
object[]
required
Each must include id; may set price, compareAtPrice, sku, barcode, etc.
boolean
Requires confirmation: yes if a price changes (price/compareAtPrice); otherwise free.

delete_product_variant

Delete variants from a product.
string
required
string[]
required
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).
string
required
string[]
required
Publication ids from list_publications.
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.
string
required
string[]
required
boolean
required
Must be true to apply.
Requires confirmation: always.

set_inventory_quantity

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

adjust_inventory_quantity

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

Code examples

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.