update_variants
Update existing product variants in bulk, modifying price, SKU, barcode, tax status, inventory policy, and option values. Inventory quantity changes require a separate tool.
Instructions
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.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| productId | Yes | Product GID. | |
| variants | Yes |
Implementation Reference
- src/tools/variants.ts:353-387 (handler)The handler function that executes the 'update_variants' tool logic. It calls the Shopify productVariantsBulkUpdate mutation with the provided productId and variants, throws if there are user errors, and returns a formatted response listing the updated variants.
server.tool( "update_variants", "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.", updateVariantsSchema, async (args) => { const data = await client.graphql<{ productVariantsBulkUpdate: { productVariants: VariantNode[]; userErrors: ShopifyUserError[]; }; }>(VARIANTS_BULK_UPDATE_MUTATION, { productId: args.productId, variants: args.variants, }); throwIfUserErrors( data.productVariantsBulkUpdate.userErrors, "productVariantsBulkUpdate", ); const updated = data.productVariantsBulkUpdate.productVariants; return { content: [ { type: "text" as const, text: [ `Updated ${updated.length} variant(s):`, ...updated.map( (v) => ` ${v.title} ${v.price}${v.compareAtPrice ? ` (cmp ${v.compareAtPrice})` : ""}${v.sku ? ` SKU:${v.sku}` : ""} — ${v.id}`, ), ].join("\n"), }, ], }; }, ); - src/tools/variants.ts:209-212 (schema)The Zod schema for the 'update_variants' tool input. It requires a productId (GID string) and an array of 1-100 variant update objects (each containing an id and optional fields like price, compareAtPrice, sku, barcode, taxable, inventoryPolicy, optionValues).
const updateVariantsSchema = { productId: z.string().describe("Product GID."), variants: z.array(variantUpdateSchema).min(1).max(100), }; - src/tools/variants.ts:84-101 (helper)The VARIANTS_BULK_UPDATE_MUTATION GraphQL mutation used by the 'update_variants' handler to perform the bulk update on Shopify.
const VARIANTS_BULK_UPDATE_MUTATION = /* GraphQL */ ` mutation VariantsBulkUpdate( $productId: ID! $variants: [ProductVariantsBulkInput!]! ) { productVariantsBulkUpdate(productId: $productId, variants: $variants) { productVariants { id title price compareAtPrice sku barcode } userErrors { field message } } } `; - src/tools/variants.ts:182-191 (helper)The variantUpdateSchema Zod schema defining the shape of each variant object in the update array, used by updateVariantsSchema.
const variantUpdateSchema = z.object({ id: z.string().describe("Variant GID to update."), price: z.string().optional(), compareAtPrice: z.string().optional().nullable(), sku: z.string().optional(), barcode: z.string().optional(), taxable: z.boolean().optional(), inventoryPolicy: z.enum(["DENY", "CONTINUE"]).optional(), optionValues: z.array(optionValueInputSchema).optional(), });