get-products
Retrieve all products or search by title from a Shopify store using GraphQL API. Specify a search term or limit results for product management.
Instructions
Get all products or search by title
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| searchTitle | No | Search title, if missing, will return all products | |
| limit | Yes | Maximum number of products to return |
Implementation Reference
- src/index.ts:115-131 (handler)The MCP tool handler function for 'get-products'. Instantiates ShopifyClient, fetches products via loadProducts (supporting title search and limit), formats each product using formatProduct helper, joins formatted strings, and returns as text content or error response.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); } }
- src/index.ts:108-114 (schema)Zod input schema for the 'get-products' tool: optional searchTitle (string) for filtering by product title, and limit (number) for pagination.{ searchTitle: z .string() .optional() .describe("Search title, if missing, will return all products"), limit: z.number().describe("Maximum number of products to return"), },
- src/index.ts:105-132 (registration)Full registration of the 'get-products' MCP tool using server.tool(), including name, description, input schema, and inline handler function.server.tool( "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 helper method loadProducts in ShopifyClient class: executes GraphQL query to Shopify Admin API to retrieve products filtered by title (using lucene-style query), limited by count, supports cursor pagination, returns LoadProductsResponse with products, next cursor, and currency.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-49 (helper)Helper function formatProduct: converts a ProductNode object into a human-readable multi-line string, including title, description, handle, and details for each variant (title, id, price, sku, inventoryPolicy). Used by the tool handler.function formatProduct(product: ProductNode): string { return ` Product: ${product.title} 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(", ")} `; }