get-product-by-id
Retrieve specific product details from a Shopify store by providing the product ID to access inventory, pricing, and descriptions.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| productId | Yes |
Implementation Reference
- src/tools/getProductById.ts:25-167 (handler)The execute function implements the core tool logic: validates productId input, queries Shopify GraphQL API for product data including variants, images, and collections, formats the response, and returns the product or throws an error if not found.execute: async (input: GetProductByIdInput) => { try { const { productId } = input; const query = gql` query GetProductById($id: ID!) { product(id: $id) { id title description handle status createdAt updatedAt totalInventory priceRangeV2 { minVariantPrice { amount currencyCode } maxVariantPrice { amount currencyCode } } images(first: 5) { edges { node { id url altText width height } } } variants(first: 20) { edges { node { id title price inventoryQuantity sku selectedOptions { name value } } } } collections(first: 5) { edges { node { id title } } } tags vendor } } `; const variables = { id: productId }; const data = (await shopifyClient.request(query, variables)) as { product: any; }; if (!data.product) { throw new Error(`Product with ID ${productId} not found`); } // Format product data const product = data.product; // Format variants const variants = product.variants.edges.map((variantEdge: any) => ({ id: variantEdge.node.id, title: variantEdge.node.title, price: variantEdge.node.price, inventoryQuantity: variantEdge.node.inventoryQuantity, sku: variantEdge.node.sku, options: variantEdge.node.selectedOptions })); // Format images const images = product.images.edges.map((imageEdge: any) => ({ id: imageEdge.node.id, url: imageEdge.node.url, altText: imageEdge.node.altText, width: imageEdge.node.width, height: imageEdge.node.height })); // Format collections const collections = product.collections.edges.map( (collectionEdge: any) => ({ id: collectionEdge.node.id, title: collectionEdge.node.title }) ); const formattedProduct = { id: product.id, title: product.title, description: product.description, handle: product.handle, status: product.status, createdAt: product.createdAt, updatedAt: product.updatedAt, totalInventory: product.totalInventory, priceRange: { minPrice: { amount: product.priceRangeV2.minVariantPrice.amount, currencyCode: product.priceRangeV2.minVariantPrice.currencyCode }, maxPrice: { amount: product.priceRangeV2.maxVariantPrice.amount, currencyCode: product.priceRangeV2.maxVariantPrice.currencyCode } }, images, variants, collections, tags: product.tags, vendor: product.vendor }; return { product: formattedProduct }; } catch (error) { console.error("Error fetching product by ID:", error); throw new Error( `Failed to fetch product: ${ error instanceof Error ? error.message : String(error) }` ); } }
- src/tools/getProductById.ts:6-8 (schema)Input schema definition using Zod that validates the productId parameter must be a non-empty string.const GetProductByIdInputSchema = z.object({ productId: z.string().min(1) });
- src/index.ts:96-107 (registration)Tool registration with MCP server using server.tool() - defines the tool name 'get-product-by-id', input schema (productId as string), and async handler that calls getProductById.execute() and returns formatted JSON content.server.tool( "get-product-by-id", { productId: z.string().min(1) }, async (args) => { const result = await getProductById.execute(args); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } );
- src/tools/getProductById.ts:15-168 (handler)Complete tool object definition containing name, description, schema, initialize method for GraphQL client setup, and execute handler function for fetching product by ID from Shopify.const getProductById = { name: "get-product-by-id", description: "Get a specific product by ID", schema: GetProductByIdInputSchema, // Add initialize method to set up the GraphQL client initialize(client: GraphQLClient) { shopifyClient = client; }, execute: async (input: GetProductByIdInput) => { try { const { productId } = input; const query = gql` query GetProductById($id: ID!) { product(id: $id) { id title description handle status createdAt updatedAt totalInventory priceRangeV2 { minVariantPrice { amount currencyCode } maxVariantPrice { amount currencyCode } } images(first: 5) { edges { node { id url altText width height } } } variants(first: 20) { edges { node { id title price inventoryQuantity sku selectedOptions { name value } } } } collections(first: 5) { edges { node { id title } } } tags vendor } } `; const variables = { id: productId }; const data = (await shopifyClient.request(query, variables)) as { product: any; }; if (!data.product) { throw new Error(`Product with ID ${productId} not found`); } // Format product data const product = data.product; // Format variants const variants = product.variants.edges.map((variantEdge: any) => ({ id: variantEdge.node.id, title: variantEdge.node.title, price: variantEdge.node.price, inventoryQuantity: variantEdge.node.inventoryQuantity, sku: variantEdge.node.sku, options: variantEdge.node.selectedOptions })); // Format images const images = product.images.edges.map((imageEdge: any) => ({ id: imageEdge.node.id, url: imageEdge.node.url, altText: imageEdge.node.altText, width: imageEdge.node.width, height: imageEdge.node.height })); // Format collections const collections = product.collections.edges.map( (collectionEdge: any) => ({ id: collectionEdge.node.id, title: collectionEdge.node.title }) ); const formattedProduct = { id: product.id, title: product.title, description: product.description, handle: product.handle, status: product.status, createdAt: product.createdAt, updatedAt: product.updatedAt, totalInventory: product.totalInventory, priceRange: { minPrice: { amount: product.priceRangeV2.minVariantPrice.amount, currencyCode: product.priceRangeV2.minVariantPrice.currencyCode }, maxPrice: { amount: product.priceRangeV2.maxVariantPrice.amount, currencyCode: product.priceRangeV2.maxVariantPrice.currencyCode } }, images, variants, collections, tags: product.tags, vendor: product.vendor }; return { product: formattedProduct }; } catch (error) { console.error("Error fetching product by ID:", error); throw new Error( `Failed to fetch product: ${ error instanceof Error ? error.message : String(error) }` ); } } };
- src/index.ts:64-64 (registration)Initialization of getProductById tool with the Shopify GraphQL client instance before registering with MCP server.getProductById.initialize(shopifyClient);