Shopify Store Catalog & Price Intelligence MCP Server
Pricing
Pay per usage
Shopify Store Catalog & Price Intelligence MCP Server
Extract normalized products, variants, SKUs, real-time stock availability, discount percentages, collections, and predictive search results from any public Shopify storefront via Batch JSON API or Standby MCP Server.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Mutualistic Labs
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
MCP Server for AI Agents: Shopify Store Catalog & Search API
An always-on Model Context Protocol (MCP) server and batch Actor that reads any public Shopify store: product catalogs with variant-level price, SKU and availability, collections, single product details and the store's own predictive search. Descriptions are returned as clean Markdown. Built for AI agents (Claude Desktop, Cursor, Windsurf, OpenAI Agents, LangChain), price and assortment monitoring, competitor research, dropshipping research and catalog enrichment.
No proxies, no browser, no logins, no cookies: only the public storefront JSON endpoints (/products.json,
/collections/{handle}/products.json, /products/{handle}.json, /collections.json, /search/suggest.json) are called.
Features
- Products of one or many stores (up to 10), optionally limited to one collection, with filters for availability, price range, vendor, product type, tag and keyword.
- Variant-level data:
variantswith SKU, price, compare-at price, availability, options, grams and tax flags; aggregatedprice_min,price_max,compare_at_price_min,compare_at_price_maxanddiscount_pct_max. - Collections with product counts and URLs.
- Predictive search per store, optionally enriched with the full product record.
- Works with preset stores,
*.myshopify.comsubdomains and custom store domains (https only). - Deterministic de-duplication (
uid), hardmax_itemsandmax_total_charge_usdcaps.
What you get
record_type | Mode | What it is |
|---|---|---|
product | products, search, product_detail | One product (metadata, variants, SKUs, price range, discount, availability, images, Markdown description) |
collection | collections, search | One collection (title, handle, description, product count, URL) |
Endpoints
GET /andGET /health: readiness probe, returns{"status":"ok","actor":"shopify-store-catalog-mcp",...}.POST /mcp: MCP JSON-RPC 2.0 (initialize,ping,tools/list,tools/call).
Standby URL: https://mutualistic-housing--shopify-store-catalog-mcp.apify.actor/mcp (authenticate with your Apify API token).
Input
| Field | Type | Default |
|---|---|---|
mode | products, search, collections, product_detail | products |
stores | string[] (preset keys, myshopify subdomains, *.myshopify.com URLs or custom https domains, 1 to 10) | ["allbirds"] |
collection_handle | string, only for mode products | none |
query | string, max 200 chars (required for search; optional keyword filter in products and collections) | none |
product_urls | string[] of product URLs or store/handle pairs (mode product_detail, 1 to 50) | none |
available_only | boolean | false |
min_price, max_price | number or null, major currency units | none |
vendor, product_type, tag | string, max 100 chars | none |
include_description | boolean | true |
include_full_details | boolean (mode search: fetch the full product record for every match) | true |
max_items | integer 1 to 500 | 25 |
max_total_charge_usd | number or null | no cap |
An empty {} input runs: the 25 first products of allbirds with descriptions. camelCase aliases (collectionHandle, productUrls,
availableOnly, minPrice, maxPrice, productType, includeDescription, includeFullDetails, maxItems, maxTotalChargeUsd) are
accepted. Invalid input is rejected with INVALID_INPUT_ZERO_CHARGE before any network call or charge.
Batch input examples
Available products under 120 from two stores:
{"mode": "products", "stores": ["allbirds", "tentree"], "available_only": true, "max_price": 120, "max_items": 25}
One collection, filtered by tag:
{"mode": "products", "stores": ["kith"], "collection_handle": "mens-footwear", "tag": "new", "include_description": false}
Search a store and enrich every match with variants and SKUs:
{"mode": "search", "stores": ["allbirds"], "query": "shoe", "include_full_details": true, "max_items": 20}
List collections:
{"mode": "collections", "stores": ["https://www.brooklinen.com"], "max_items": 50}
Product details by URL or store/handle:
{"mode": "product_detail", "product_urls": ["https://www.allbirds.com/products/mens-tree-runners", "tentree/some-handle"]}
MCP tools
{"mcpServers": {"shopify": {"url": "https://mutualistic-housing--shopify-store-catalog-mcp.apify.actor/mcp","headers": { "Authorization": "Bearer <APIFY_TOKEN>" }}}}
get_store_products:stores,collection_handle,query,available_only,min_price,max_price,vendor,product_type,tag,include_description(defaultfalsein MCP),max_items(default 10).search_store_catalog:stores,query(required),available_only,min_price,max_price,include_description,max_items.get_store_collections:stores,query,max_items.get_product_details:product_urls(URLs orstore/handlepairs),include_description(defaulttrue).list_preset_stores: no arguments; lists the preset stores (free).
Example calls:
curl -X POST "https://mutualistic-housing--shopify-store-catalog-mcp.apify.actor/mcp" \-H "Authorization: Bearer <APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_store_products","arguments":{"stores":["allbirds"],"available_only":true,"max_price":120,"max_items":5}}}'
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_store_catalog","arguments":{"stores":["tentree"],"query":"shirt","max_items":10}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_store_collections","arguments":{"stores":["kith"],"max_items":20}}}
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_product_details","arguments":{"product_urls":["https://www.allbirds.com/products/mens-tree-runners"]}}}
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"list_preset_stores","arguments":{}}}
Output fields
product:
| Field | Meaning |
|---|---|
record_type, uid | product; deterministic SHA-256 identifier |
store_domain, store_base_url | Store host and base URL |
product_id, handle, title, vendor, product_type, tags | Product identity and classification |
published_at, created_at, updated_at | Timestamps |
product_url, featured_image, images | Page URL (https only) and image URLs |
available, variants_count | true when any variant is in stock; number of variants |
price_min, price_max | Variant price range in major currency units |
compare_at_price_min, compare_at_price_max, discount_pct_max | Compare-at range and largest discount percentage |
currency | Currency code when the store payload exposes one, otherwise null |
skus, options, variants | Distinct SKUs; option names/values; normalized variants |
description_text | Description as Markdown (up to 50000 characters) |
collection_handle, source | Collection listed from; products_json, product_json or search_suggest |
Each entry of variants has variant_id, title, sku, price, compare_at_price, available, option1, option2, option3,
grams, requires_shipping and taxable.
collection:
| Field | Meaning |
|---|---|
record_type, uid | collection; deterministic SHA-256 identifier |
store_domain, store_base_url | Store host and base URL |
collection_id, handle, title | Collection identity |
description_text, products_count | Description as Markdown; number of products |
published_at, updated_at, featured_image, collection_url | Timestamps, image and page URL |
Example product (shortened):
{"record_type": "product", "store_domain": "www.allbirds.com", "store_base_url": "https://www.allbirds.com","product_id": 7654321098, "handle": "mens-tree-runners", "title": "Men's Tree Runners", "vendor": "Allbirds","product_type": "Shoes", "tags": ["mens", "runner"], "product_url": "https://www.allbirds.com/products/mens-tree-runners","available": true, "variants_count": 2, "price_min": 98.0, "price_max": 98.0, "compare_at_price_min": 120.0,"compare_at_price_max": 120.0, "discount_pct_max": 18.33, "currency": null, "skus": ["TR3MBL090"],"variants": [{"variant_id": 1, "title": "9", "sku": "TR3MBL090", "price": 98.0, "compare_at_price": 120.0, "available": true}],"featured_image": "https://cdn.shopify.com/s/files/1/example.jpg", "source": "products_json", "uid": "<sha256>"}
Preset stores
Use the key in stores; any *.myshopify.com subdomain or custom store domain works too (https only).
| Key | Store | Category |
|---|---|---|
allbirds | Allbirds (www.allbirds.com) | footwear, apparel |
tentree | tentree (www.tentree.com) | sustainable apparel |
kith | Kith (kith.com) | streetwear |
cotopaxi | Cotopaxi (www.cotopaxi.com) | outdoor gear |
brooklinen | Brooklinen (www.brooklinen.com) | home, bedding |
deathwishcoffee | Death Wish Coffee (www.deathwishcoffee.com) | coffee |
intelligentsia | Intelligentsia Coffee (www.intelligentsia.com) | coffee |
Security and limits
- https only: bare names become
https://name.myshopify.com;http://,file:and other schemes are rejected. Reserved names such aslocalhost,adminorwwware never accepted as stores. - SSRF protections: credentials in URLs, non-443 ports,
..path traversal, queries and fragments on store URLs are rejected; IP literals,localhost,.localand.internalnames are blocked; DNS results (and the connected peer address, checked before any body is read) that are loopback, private, link-local, CGNAT, NAT64, 6to4, Teredo, multicast or unspecified are refused. Redirects (for example from a myshopify subdomain to a custom domain) must be https and are re-checked per host. - Bounds: at most 500 items per run, 10 stores per call, 50 product URLs in mode
product_detail, a 120 s global batch deadline, a 45 s deadline per MCP tool call, a 15 s per-request timeout (connect, TLS, headers and body) and a 4 MiB response size cap. - MCP server: request bodies above 64 KiB return
413,POST /mcprequiresContent-Type: application/json(415otherwise) and at most 8 concurrent tool calls run (503when busy). - Untrusted content:
description_textis untrusted third-party Markdown written by store owners. Link destinations are percent-encoded and only https and mailto links are emitted, but plain text is passed through verbatim. Sanitize it before rendering it in a browser or UI. - Stores with a password page or disabled JSON endpoints return an error entry for that store; rate limits (
429) and 5xx responses are retried with back-off; per-store and per-product failures are reported inerrorsand never abort other stores.
Pricing
Pay per event: $0.001 per result-item (result-item: one de-duplicated product or collection, as a dataset item or an MCP tool
result row); the actor-start event is free and list_preset_stores is free. max_items and max_total_charge_usd are hard
caps enforced in code, so a run never charges more than you configure. Invalid input and empty results are never charged.