get-products
Retrieve products from Shopify Update MCP Server by title or fetch all products within a specified limit. Simplify product management and querying.
Instructions
Get all products or search by title
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | Yes | Maximum number of products to return | |
| searchTitle | No | Search title, if missing, will return all products |
Implementation Reference
- src/index.ts:107-133 (registration)MCP tool registration for 'get-products', including Zod input schema and handler function that delegates to ShopifyClient.loadProducts, formats output using formatProduct, and handles errors."get-products", "Get all products or search by title", { searchTitle: z .string() .optional() .describe("Search title, if missing, will return all products"), limit: z.number().describe("Maximum number of products to return"), }, async ({ searchTitle, limit }) => { const client = new ShopifyClient(); try { const products = await client.loadProducts( SHOPIFY_ACCESS_TOKEN, MYSHOPIFY_DOMAIN, searchTitle ?? null, limit ); const formattedProducts = products.products.map(formatProduct); return { content: [{ type: "text", text: formattedProducts.join("\n") }], }; } catch (error) { return handleError("Failed to retrieve products data", error); } } );
- Core handler logic for loading products from Shopify using GraphQL query with optional title filter, pagination support, and returns formatted LoadProductsResponse.async loadProducts( accessToken: string, myshopifyDomain: string, searchTitle: string | null, limit: number = 10, afterCursor?: string ): Promise<LoadProductsResponse> { const titleFilter = searchTitle ? `title:*${searchTitle}*` : ""; const graphqlQuery = gql` { shop { currencyCode } products(first: ${limit}, query: "${titleFilter}"${ afterCursor ? `, after: "${afterCursor}"` : "" }) { edges { node { ${productFragment} } } pageInfo { hasNextPage endCursor } } } `; const res = await this.shopifyGraphqlRequest<{ data: { shop: { currencyCode: string; }; products: { edges: Array<{ node: ProductNode; }>; pageInfo: { hasNextPage: boolean; endCursor: string; }; }; }; }>({ url: `https://${myshopifyDomain}/admin/api/${this.SHOPIFY_API_VERSION}/graphql.json`, accessToken, query: graphqlQuery, }); const data = res.data.data; const edges = data.products.edges; const products = edges.map((edge) => edge.node); const pageInfo = data.products.pageInfo; const next = pageInfo.hasNextPage ? pageInfo.endCursor : undefined; const currencyCode = data.shop.currencyCode; return { products, next, currencyCode }; }
- src/index.ts:33-50 (helper)Helper function to format a ProductNode into a readable string for the tool output.function formatProduct(product: ProductNode): string { return ` Product: ${product.title} id: ${product.id} description: ${product.description} handle: ${product.handle} variants: ${product.variants.edges .map( (variant) => `variant.title: ${variant.node.title} variant.id: ${variant.node.id} variant.price: ${variant.node.price} variant.sku: ${variant.node.sku} variant.inventoryPolicy: ${variant.node.inventoryPolicy} ` ) .join(", ")} `; }
- src/index.ts:109-115 (schema)Zod schema defining input parameters for the 'get-products' tool: optional searchTitle (string) and required limit (number).{ searchTitle: z .string() .optional() .describe("Search title, if missing, will return all products"), limit: z.number().describe("Maximum number of products to return"), },
- GraphQL fragment defining the structure of ProductNode queried in loadProducts, including variants and images.const productFragment = gql` id handle title description publishedAt updatedAt options { id name values } images(first: 20) { edges { node { ${productImagesFragment} } } } variants(first: 250) { edges { node { ${productVariantsFragment} } } } `;