update_product
Modify key product details—title, description, vendor, type, tags, or status—by supplying only the fields to change. Archive products to hide from storefront while preserving order history.
Instructions
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).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Product GID or numeric ID | |
| title | No | ||
| description | No | ||
| vendor | No | ||
| product_type | No | ||
| tags | No | ||
| status | No |
Implementation Reference
- src/tools/products.ts:84-96 (schema)GraphQL mutation definition for updating a product in Shopify.
const UPDATE_PRODUCT_MUTATION = /* GraphQL */ ` mutation UpdateProduct($input: ProductInput!) { productUpdate(input: $input) { product { id title handle status } userErrors { field message } } } `; - src/tools/products.ts:142-150 (schema)Zod schema defining the input parameters for the update_product tool.
const updateProductSchema = { id: z.string().describe("Product GID or numeric ID"), title: z.string().optional(), description: z.string().optional(), vendor: z.string().optional(), product_type: z.string().optional(), tags: z.array(z.string()).optional(), status: z.enum(["ACTIVE", "DRAFT", "ARCHIVED"]).optional(), }; - src/tools/products.ts:254-287 (registration)Registration of the update_product MCP tool with its handler, schema, and description.
server.tool( "update_product", "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).", updateProductSchema, async (args) => { const input: Record<string, unknown> = { id: toGid(args.id, "Product") }; if (args.title !== undefined) input.title = args.title; if (args.description !== undefined) input.descriptionHtml = args.description; if (args.vendor !== undefined) input.vendor = args.vendor; if (args.product_type !== undefined) input.productType = args.product_type; if (args.tags !== undefined) input.tags = args.tags; if (args.status !== undefined) input.status = args.status; const data = await client.graphql<{ productUpdate: { product: Product | null; userErrors: ShopifyUserError[]; }; }>(UPDATE_PRODUCT_MUTATION, { input }); throwIfUserErrors(data.productUpdate.userErrors, "productUpdate"); const product = data.productUpdate.product; if (!product) throw new Error("productUpdate returned no product"); return { content: [ { type: "text" as const, text: `Updated product: ${product.title} (${product.id})`, }, ], }; }, ); - src/tools/products.ts:258-287 (handler)Handler function for update_product: builds a partial input object from the provided args (title, description, vendor, product_type, tags, status), calls the Shopify productUpdate GraphQL mutation, and returns a confirmation message.
async (args) => { const input: Record<string, unknown> = { id: toGid(args.id, "Product") }; if (args.title !== undefined) input.title = args.title; if (args.description !== undefined) input.descriptionHtml = args.description; if (args.vendor !== undefined) input.vendor = args.vendor; if (args.product_type !== undefined) input.productType = args.product_type; if (args.tags !== undefined) input.tags = args.tags; if (args.status !== undefined) input.status = args.status; const data = await client.graphql<{ productUpdate: { product: Product | null; userErrors: ShopifyUserError[]; }; }>(UPDATE_PRODUCT_MUTATION, { input }); throwIfUserErrors(data.productUpdate.userErrors, "productUpdate"); const product = data.productUpdate.product; if (!product) throw new Error("productUpdate returned no product"); return { content: [ { type: "text" as const, text: `Updated product: ${product.title} (${product.id})`, }, ], }; }, ); - src/tools/products.ts:333-336 (helper)Helper function that converts a numeric ID or bare ID to a Shopify GID (e.g., gid://shopify/Product/123). Used by the update_product handler to ensure the product ID is in the correct format.
export function toGid(id: string, type: string): string { if (id.startsWith("gid://")) return id; return `gid://shopify/${type}/${id}`; }