Read-only MCP for the Shopify Admin GraphQL API. 6 tools, full read surface, multi-store.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
A single MCP server exposing 100% of the Shopify Admin GraphQL API read surface (version 2026-04) through 6 universal tools. Read-only is enforced at the query-parser level β mutations are rejected before they ever reach Shopify, not merely discouraged. Multi-store by design: one server instance can serve many shops.
Built and maintained by Scalably. Runs on the Model Context Protocol. License: MIT.
Why read-only at the parser level? Giving an AI agent write access to a live store is how you end up with a deleted product or a wrong-priced variant. This server enforces read-only by parsing every query and rejecting mutations before they leave the process β not by trusting the model to behave, and not by relying on Shopify-side scopes alone. It's the safety boundary an agent in production actually needs. (more on the pattern)
Then point any MCP client at the server. See Authentication below for multi-store and OAuth client-credentials setup.
| Tool | Description |
|---|---|
shopify_list_stores | Lists configured stores. Agent calls first. |
shopify_graphql_query | Arbitrary read-only GraphQL. Mutations rejected by the parser. |
shopify_graphql_introspect | Schema introspection β full catalog or single type. |
shopify_bulk_query | Launch async bulk export (JSONL). |
shopify_bulk_poll | Poll bulk operation status + download URL. |
shopify_shopifyql | ShopifyQL analytics (SQL-like; requires read_reports). |
Every non-list tool takes an optional shop argument (alias or domain). Required when >1 store configured; auto-selected when exactly 1.
100% of Admin GraphQL API read surface β any object, field, or connection accessible with the token's scopes is reachable via shopify_graphql_query. Anything large-scale (>10k records) should use shopify_bulk_query. Analytics goes through shopify_shopifyql.
Set SHOPIFY_STORES to a JSON object mapping alias β store config:
client_id+client_secret (Dev Dashboard OAuth, 24h tokens auto-refreshed per store) OR access_token (legacy shpat_).[a-z0-9][a-z0-9_-]{0,63}. Lowercase-normalized on load.If SHOPIFY_STORES is unset, the MCP falls back to single-store env vars:
SHOPIFY_DOMAIN or SHOPIFY_SHOP_DOMAIN β <shop>.myshopify.comSHOPIFY_CLIENT_ID + SHOPIFY_CLIENT_SECRET (Dev Dashboard)SHOPIFY_ACCESS_TOKEN (legacy shpat_)The single store registers under alias default β callers can omit shop argument on tool calls.
Every query is parsed with graphql-core before transmission. The parser rejects:
subscription operations (not supported by Admin API anyway)mutation EXCEPT bulkOperationCancel (cancels an in-flight bulk job, no shop-data write)bulkOperationRunQuery is NOT in the generic parser allowlist. Legitimate bulk exports go through the dedicated shopify_bulk_query tool, which validates the inner query with _assert_read_only BEFORE wrapping it in the bulk mutation. Single source of truth β no reliance on Shopify-side validation.
Per-store cost-based leaky bucket (Shopify's model). Each response includes extensions.cost.throttleStatus. On THROTTLED errors, the MCP sleeps ceil((requestedQueryCost - currentlyAvailable) / restoreRate) seconds (minimum 1s) and retries up to 3 times. Over limit β surfaced to caller.
Buckets are independent per store β throttle on store A doesn't affect store B.
^[a-z0-9][a-z0-9-]*\.myshopify\.com$ (no arbitrary hostnames β defeats SSRF).^[a-z0-9][a-z0-9_-]{0,63}$.allow_redirects=False on both token exchange and GraphQL calls.X-Shopify-Access-Token, client_secret, and all token prefixes (shpua_, shpat_, shpss_, shpca_) redacted from logs and error messages.shopify
Default pin: 2026-04. Callers can override per-tool via api_version="YYYY-MM". Bump the module constant SHOPIFY_API_VERSION quarterly after smoke-testing new versions.
Minimum viable: read_products read_orders read_customers.
Recommended baseline:
read_products read_orders read_customers read_inventory read_locations read_fulfillments read_discounts read_content read_themes read_files read_markets read_metaobjects read_metaobject_definitions read_reports read_translations read_locales read_shipping.
Add read_all_orders for >60-day order history. Enable Protected customer data access in Dev Dashboard β Configuration if the agent needs customer PII.
This connector runs locally, on your own machine, under your own Shopify credentials. It is a thin read-only bridge between your MCP client and Shopify's Admin API.
*.myshopify.com), enforced by a domain allowlist.The canonical hosted version of this policy: https://scalably.io/connector-privacy.html
We write about building production MCP servers and AI agents at scalably.io/blog:
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/shopify-admin-mcp-server-read-only)<a href="https://allmcps.com/mcp/shopify-admin-mcp-server-read-only"><img src="https://allmcps.com/api/badge/shopify-admin-mcp-server-read-only?style=directory" alt="Shopify Admin MCP Server (Read Only) on AllMCPs" /></a>