Skip to main content
Glama

Shopify MCP

License: MIT MCP Shopify Admin API

A single MCP server exposing the full 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)

Install

Claude Code:

claude mcp add shopify -e SHOPIFY_DOMAIN=my-store.myshopify.com -e SHOPIFY_ACCESS_TOKEN=shpat_... -- uvx scalably-shopify-mcp

Codex:

codex mcp add shopify --env SHOPIFY_DOMAIN=my-store.myshopify.com --env SHOPIFY_ACCESS_TOKEN=shpat_... -- uvx scalably-shopify-mcp

Claude Desktop: download shopify-mcp.mcpb from the latest GitHub release and open it.

Related MCP server: shopify-mcp

Setup

Single store (simplest)

  • SHOPIFY_DOMAIN or SHOPIFY_SHOP_DOMAIN - <shop>.myshopify.com

  • Auth path A: SHOPIFY_ACCESS_TOKEN (legacy shpat_)

  • Auth path B: SHOPIFY_CLIENT_ID + SHOPIFY_CLIENT_SECRET (Dev Dashboard custom app, client-credentials OAuth, 24h tokens auto-refreshed)

The single store registers under alias default; callers can omit the shop argument on tool calls.

Multi-store (agency setups)

Set SHOPIFY_STORES to a JSON object mapping alias to store config:

{
  "main":   {"domain": "my-store.myshopify.com",        "client_id": "...", "client_secret": "..."},
  "outlet": {"domain": "my-store-outlet.myshopify.com", "client_id": "...", "client_secret": "..."},
  "legacy": {"domain": "legacy-store.myshopify.com",    "access_token": "shpat_..."}
}
  • Each store can use either client_id + client_secret (Dev Dashboard OAuth) or access_token (legacy shpat_).

  • Aliases: [a-z0-9][a-z0-9_-]{0,63}, lowercase-normalized on load.

  • Token cache is per-store-domain; one throttled store doesn't block others.

Scopes needed (read-only)

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 order history older than 60 days. Enable Protected customer data access in Dev Dashboard, Configuration, if the agent needs customer PII.

Tools (6)

Tool

What it does

shopify_list_stores

List all Shopify stores configured for this agent. Call first.

shopify_graphql_query

Arbitrary read-only GraphQL. Mutations rejected by the parser.

shopify_graphql_introspect

Schema introspection, full catalog or a single type.

shopify_bulk_query

Launch an async bulk export (JSONL).

shopify_bulk_poll

Poll a bulk operation status and 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 more than one store is configured; auto-selected when exactly one.

Coverage

The full 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 (more than 10k records) should use shopify_bulk_query. Analytics goes through shopify_shopifyql.

Configuration

Variable

Required

Purpose

SHOPIFY_DOMAIN, SHOPIFY_SHOP_DOMAIN

one of these or SHOPIFY_STORES

Single-store admin domain, <shop>.myshopify.com

SHOPIFY_ACCESS_TOKEN

see above

Legacy shpat_ access token (single-store auth path B)

SHOPIFY_CLIENT_ID, SHOPIFY_CLIENT_SECRET

see above

Dev Dashboard custom-app credentials (single-store auth path A)

SHOPIFY_STORES

no

JSON object mapping alias to store config; takes precedence over the single-store variables above

SHOPIFY_STORE_<ALIAS>_DOMAIN, _CLIENT_ID, _CLIENT_SECRET, _ACCESS_TOKEN

no

Prefix-key alternative to SHOPIFY_STORES for multi-store setups; one set of keys per store alias

SHOPIFY_REQUEST_TIMEOUT_SECONDS

no

HTTP request timeout in seconds (default 60)

SHOPIFY_LOG_LEVEL

no

INFO (default) or DEBUG

Read-only enforcement

Every query is parsed with graphql-core before transmission. The parser rejects:

  • subscription operations (not supported by the Admin API anyway)

  • Any top-level mutation except bulkOperationCancel (cancels an in-flight bulk job, no shop-data write)

  • Malformed GraphQL (syntax errors)

  • Queries over 100KB

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 the same read-only check before wrapping it in the bulk mutation. Single source of truth, no reliance on Shopify-side validation.

Rate limiting

Per-store cost-based leaky bucket (Shopify's model). Each response includes extensions.cost.throttleStatus. On THROTTLED errors, the server sleeps ceil((requestedQueryCost - currentlyAvailable) / restoreRate) seconds (minimum 1s) and retries up to 3 times before surfacing the error. Buckets are independent per store: a throttle on one store doesn't affect another.

Reply shape

Tool replies mirror the underlying call rather than a uniform envelope. shopify_list_stores returns a JSON array of {alias, domain, name, currency, auth_mode}; every GraphQL-backed tool (shopify_graphql_query, shopify_graphql_introspect, shopify_bulk_query, shopify_bulk_poll, shopify_shopifyql) returns the raw Shopify Admin API response, {"data": ..., "errors": ..., "extensions": ...}, unwrapped. Tool-level failures (bad input, redacted transport errors) raise a plain error.

Limits

100KB query size ceiling. Bulk exports: exactly one top-level connection per query, max 5 total connections, max depth 2, every nested connection node selects id without an alias; one bulk operation at a time per shop on API versions through 2025-10, up to 5 on 2026-01 and later. API version defaults to 2026-04; override per call with api_version="YYYY-MM".

Verify

Each release lists the package version, the .mcpb sha256 and the production commit it was derived from in CHANGELOG.md. CI runs the tests and a clean install of the built wheel on every push.

Privacy Policy

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.

  • Data collection: The connector collects no personal data and contains no telemetry, analytics, or external reporting. It does not phone home.

  • Data usage: Shopify store data you query is returned to your local MCP client to fulfill your request, and is not used for any other purpose.

  • Data storage: The connector stores nothing persistently. Access tokens are held in memory only for the life of the process and are never written to disk. The only network destination is Shopify's own API (*.myshopify.com), enforced by a domain allowlist.

  • Third-party sharing: None. Data flows only between your machine and Shopify. No third party, including the connector's author, ever receives your data or credentials.

  • Retention: No data is retained by the connector after the process exits.

  • Secret handling: Access tokens, client secrets, and all Shopify token prefixes are redacted from logs and error messages.

  • Contact: hello@scalably.io

The canonical hosted version of this policy: https://scalably.io/connector-privacy.html

License

MIT. Copyright Scalably.

Learn more

We write about building production MCP servers and AI agents at scalably.io/blog:

References

Available Tools

6 tools
shopify_bulk_pollA
Read-onlyIdempotent

Poll a bulk operation's status by ID.

Statuses: CREATED, RUNNING, COMPLETED, CANCELED, EXPIRED, FAILED. On COMPLETED, the url field is a pre-signed JSONL download (valid 7 days). On FAILED, partialDataUrl may hold partial results; errorCode explains why.

Args: operation_id: Global ID of the bulk operation (format: gid://shopify/BulkOperation/<numeric-id>). shop: Store alias or domain the bulk op was launched on. Required when multiple stores are configured. api_version: Override API version (default "2026-04").

ParametersJSON Schema
NameRequiredDescriptionDefault
shopNo
api_versionNo
operation_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations (readOnlyHint, idempotentHint) by explaining the concrete outcomes: statuses (CREATED, RUNNING, COMPLETED, CANCELED, EXPIRED, FAILED), the pre-signed JSONL URL valid for 7 days on COMPLETED, and partialDataUrl/errorCode on FAILED. This adds valuable behavioral context that annotations do not capture, and it does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately concise and well-organized: a one-line purpose, a status list with outcome behavior, and then a clearly labeled Args section. Every sentence adds value—no fluff. It could be slightly more compact (e.g., merging statuses and outcomes), but it is efficient and easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a polling tool with an output schema, the description covers all necessary operational details: the ID format, shop requirement, API version default, and what happens on completion and failure. The output schema handles specific return fields, so the description need not enumerate them. Combined with the annotations (read-only, idempotent), an agent has everything needed to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must (and does) fully explain each parameter. It details the operation_id format (gid://shopify/BulkOperation/<numeric-id>), the shop parameter including when it is required (multiple stores configured), and the api_version override with the default value. This is far more informative than the schema's bare titles and types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Poll a bulk operation's status by ID.' It clearly distinguishes this from siblings like shopify_bulk_query (which presumably creates a bulk operation) and shopify_graphql_query by focusing on status polling. The purpose is unambiguous and leaves no room for misidentification.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states the tool's function and provides context on how to use it (e.g., passing an operation_id in the proper format). It doesn't explicitly say 'use this after starting a bulk operation' or 'when not to use it,' but the description of the operation_id and the existence of shopify_bulk_query as a sibling make the intended workflow clear. No exclusions are stated, but the context is strong enough for an agent to infer the appropriate use case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

shopify_bulk_queryA
Read-only

Launch an async bulk export of a read-only GraphQL query.

Use for exporting datasets too large for paginated queries (>10k records, or anything you'd otherwise paginate hundreds of times). Shopify runs the query in the background and produces a JSONL file with all results.

Restrictions (enforced by Shopify):

  • Exactly one top-level connection per query.

  • Max 5 total connections, max depth 2.

  • Every nested connection node must select id without an alias.

  • API ≤ 2025-10: one bulk op at a time per shop. API ≥ 2026-01: up to 5.

Returns the BulkOperation ID - poll with shopify_bulk_poll.

Args: query: Read-only GraphQL document with a single root connection. shop: Store alias or domain. Required when multiple stores are configured. api_version: Override API version (default "2026-04").

ParametersJSON Schema
NameRequiredDescriptionDefault
shopNo
queryYes
api_versionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=true and openWorldHint=true, but the description significantly expands on behavioral details: async execution, background processing, JSONL output, restrictions (connection limits, depth limits, id requirement), and API version-specific concurrency limits. This goes well beyond the annotations, giving agents a full picture of what to expect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, front-loading the core purpose and usage context. The restrictions are clearly bullet-listed, and the Args section is logically placed. No redundant sentences; every sentence adds value. Minor deduction for not being even more streamlined, but it's appropriately sized given the complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (async, multiple restrictions, API version nuances), the description covers all critical aspects: purpose, usage, restrictions, return type (BulkOperation ID), and how to proceed (poll). The output schema likely describes the return structure, so not detailing the response format is acceptable. Sibling tools are distinct and the description clearly differentiates them.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 3 parameters with 0% description coverage; however, the description's 'Args' section provides meaningful context for each: 'query' is described as a read-only GraphQL document with a single root connection, 'shop' is clarified as a store alias or domain required when multiple stores are configured, and 'api_version' is noted as an override with a default. This adds value beyond the schema's type-only information, but could be even more explicit (e.g., format for query).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: launching an async bulk export of a read-only GraphQL query. It distinguishes itself from siblings by specifying it is for large datasets where paginated queries become impractical and explicitly mentions polling with shopify_bulk_poll for results. The verb 'launch' and resource 'async bulk export of a read-only GraphQL query' are specific and non-ambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit usage guidance: use when exporting datasets too large for paginated queries (>10k records or hundreds of pages). It also contrasts with 'normal' queries implicitly by referencing pagination alternatives. While it doesn't explicitly name shopify_graphql_query for smaller queries, the mention of 'paginated queries' serves as a clear alternative. Restrictions are thoroughly listed, aiding correct invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

shopify_graphql_introspectA
Read-only

Introspect a Shopify store's Admin GraphQL schema.

Pass type_name to fetch a single type's fields (cheap, ~50 cost points). Omit it for the full schema type catalog (expensive, ~800 cost points - use sparingly).

Args: type_name: GraphQL type name (e.g. "Order", "Product", "Customer"). Must match [A-Za-z_][A-Za-z0-9_]*. Omit for full schema. shop: Store alias or domain (see shopify_list_stores). Required when multiple stores are configured. api_version: Override API version (default "2026-04").

ParametersJSON Schema
NameRequiredDescriptionDefault
shopNo
type_nameNo
api_versionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is established. The description adds valuable behavioral context: precise cost points for each mode, a caution to use the full schema sparingly, and clarifications on parameter defaults and requirements. No contradiction with annotations, and it goes beyond what annotations alone tell the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tightly structured: the purpose is front-loaded in the first sentence, followed by a compact cost/usage paragraph, then a clean 'Args:' block. Every sentence adds essential information—no filler, no repetition. The layout makes scanning effortless.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only introspection tool, the description covers everything needed to call it correctly: mode selection, cost implications, parameter semantics, and references to the shop resolution tool. An output schema exists to handle return shapes. Combined with the annotations, nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, leaving the description to carry the full burden. It does this excellently: type_name is explained with a regex and examples, shop is tied to shopify_list_stores with a condition, and api_version is given a default and override instruction. Every parameter is fully documented beyond the raw schema, exceeding the baseline expected for low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('introspect') and resource ('Shopify store's Admin GraphQL schema'), and clearly distinguishes two modes: fetching a single type vs the full catalog. This unambiguously separates it from siblings like shopify_graphql_query, which performs actual queries. No ambiguity remains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance on when to pass type_name (cheap, ~50 points) vs omit it (expensive, ~800 points, 'use sparingly'). It also tells when shop is required and references shopify_list_stores. However, it doesn't explicitly name sibling tools as alternatives for other operations, so the when-not-to-use guidance is slightly implicit. Still, the cost/size guidance is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

shopify_graphql_queryA
Read-only

Execute a read-only GraphQL query against a Shopify store's Admin API.

Universal entry point for reading any data the token's scopes permit: products, variants, orders, customers, inventory, fulfillments, discounts, locations, markets, metafields, metaobjects, segments, shop settings, etc.

Full GraphQL reference: https://shopify.dev/docs/api/admin-graphql

Write mutations are rejected by design. The query string is parsed and validated as read-only before transmission.

Idiomatic patterns:

  • Pagination: first: <=250, after: <cursor>, read pageInfo { hasNextPage endCursor }.

  • Search: pass a Shopify search string to the query: arg on connections, e.g. orders(first: 100, query: "created_at:>=2026-04-01 financial_status:paid").

  • Money: totalPriceSet { shopMoney { amount currencyCode } }.

  • For datasets >10k records, use shopify_bulk_query instead.

Args: query: GraphQL document. Must be a query or a fragment. Subscription and mutation operations are rejected - with one narrow exception, bulkOperationCancel. For bulk exports, use shopify_bulk_query. variables: Optional variables dict passed as GraphQL variables. shop: Store alias (from shopify_list_stores) or domain. Required when multiple stores are configured; optional (auto-selected) when there's only one store. api_version: Override API version (default "2026-04"). Format "YYYY-MM".

ParametersJSON Schema
NameRequiredDescriptionDefault
shopNo
queryYes
variablesNo
api_versionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description adds real behavioral detail: 'The query string is parsed and validated as read-only before transmission,' and mutation/subscription operations are rejected except for the narrow `bulkOperationCancel` exception. This meaningfully expands on what the annotations already declare without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and structured into idiomatic patterns and per-argument details. It is somewhat long and repeats the bulk-query alternative twice, but the length earns its place because most content is call-critical rather than decorative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description does not need to explain returns. It covers the required query format, variables, shop selection, api versioning, pagination patterns, search usage, and the bulk export boundary. No essential call context appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates by explaining each parameter: the GraphQL document shape and restrictions, the `variables` dict, the `shop` alias/domain requirements, and `api_version` default plus 'YYYY-MM' format. This turns a bare schema into usable guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Execute a read-only GraphQL query against a Shopify store's Admin API,' naming a specific verb, resource, and constraint. It then clarifies this is the 'Universal entry point for reading any data the token's scopes permit' and lists resource types, which distinguishes it from mutation and bulk siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly says to use the tool for reading any data the token permits and explicitly warns that write mutations are rejected. It also provides an alternative: 'For datasets >10k records, use shopify_bulk_query instead,' so an agent knows when to switch tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

shopify_list_storesA
Read-only

List all Shopify stores configured for this agent.

Returns a JSON array of {alias, domain, name, currency, auth_mode}. The name field is the merchant's own shop name from Shopify (fetched once per process, cached). Use this list to match user intent - e.g., a user saying "check the outlet" maps to the store whose name or domain contains "outlet".

If only one store is configured, shop can be omitted on tool calls.

Args: refresh: If True, bypass the shop-name cache and re-fetch from Shopify. Use after a merchant renames a shop in the Shopify admin.

ParametersJSON Schema
NameRequiredDescriptionDefault
refreshNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=true and openWorldHint=true, so the description's extra detail about the cached `name` field and the `refresh` bypass behavior adds meaningful transparency. The description also discloses that data is fetched once per process and cached, which helps the agent understand freshness semantics beyond what annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded: it states the core purpose in the first sentence, then the return shape, usage guidance, and a single clearly documented parameter. Every sentence earns its place, and the Args section is minimal and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only listing tool with one optional parameter, the description is complete: it specifies the return fields, the caching behavior, the refresh condition, and the mapping use case. The output schema also exists, so the description does not need to over-explain return types, and no critical invocation detail is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema description coverage is 0%, the description fully documents the single `refresh` parameter: 'If True, bypass the shop-name cache and re-fetch from Shopify' and explains when to use it. This compensates for the missing schema description and gives the agent actionable semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List all Shopify stores configured for this agent.' It clearly explains the return shape and also gives a concrete use case, distinguishing this tool from the GraphQL and bulk-query siblings by emphasizing it returns the agent's configured store list, not API queries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: to match user intent to a configured store, including a concrete example. It also provides the conditional guidance that if only one store is configured, `shop` can be omitted. It does not explicitly exclude alternatives, but the usage context is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

shopify_shopifyqlA
Read-only

Run a ShopifyQL analytics query against a Shopify store.

ShopifyQL is Shopify's SQL-like reporting language. Requires read_reports scope. Consumes the same cost bucket as GraphQL.

Syntax: FROM SHOW [, ...] [BY ] [GROUP BY ] [WHERE ] [SINCE -Nd UNTIL today] [ORDER BY [ASC|DESC]] [LIMIT N]

Datasets: sales, orders, products, customers, inventory, sessions. Time tokens: -Nd / -Nw / -Nm / -Nq / -Ny, or named (today, yesterday, this_week, last_week, this_month, last_month, last_year).

Examples:

  • FROM sales SHOW total_sales GROUP BY day SINCE -7d UNTIL today ORDER BY day ASC

  • FROM sales SHOW total_sales BY product_title ORDER BY total_sales DESC LIMIT 10 SINCE -30d

  • FROM sales SHOW returning_customer_rate GROUP BY month SINCE -6m

  • FROM sales SHOW net_sales SINCE -1q UNTIL today

  • FROM sessions SHOW sessions, conversion_rate GROUP BY referrer_source SINCE -14d

Returns tableData.columns, tableData.rows, and parseErrors. When parsing fails, tableData is null and parseErrors contains a list of human-readable error strings (e.g. "Column 'total_sale' not found").

Args: query: ShopifyQL query string. shop: Store alias or domain. Required when multiple stores are configured. api_version: Override API version (default "2026-04").

ParametersJSON Schema
NameRequiredDescriptionDefault
shopNo
queryYes
api_versionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint, but the description adds substantial behavioral context: it specifies the cost bucket shared with GraphQL, returns `tableData.columns`, `tableData.rows`, and `parseErrors`, and explains the error behavior when parsing fails. This goes well beyond what the annotations declare, providing concrete operational expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but tightly organized: a one-line purpose, a syntax block, dataset/token listings, several examples, and a return-format note. Each section earns its place, and the most critical information is front-loaded. No fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with a complex query language, the description is remarkably complete. It covers the syntax, allowed datasets, time tokens, example usages, return structure, and error handling. It even notes the API version default. There is no obvious missing information an agent would need to call it correctly, and the presence of an output schema further reduces the need for return-type detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate. It does: it explains the `query` syntax in detail, clarifies `shop` as 'store alias or domain. Required when multiple stores are configured', and notes `api_version` overrides the default '2026-04'. This adds meaning far beyond the bare schema types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb ('Run'), resource ('ShopifyQL analytics query'), and target ('against a Shopify store'). The description also distinguishes it from siblings by positioning it as a reporting-language query, separate from GraphQL and bulk tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly explains the tool's domain ('analytics query', SQL-like reporting) and notes the required scope ('read_reports') and that it consumes the same cost bucket as GraphQL. However, it does not explicitly contrast with sibling tools (e.g., 'use this for analytics, use GraphQL for other queries'). The guidance is strong but not fully explicit about when to choose this over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv1.1.0
    • First observedshopify_bulk_poll
    • First observedshopify_bulk_query
    • First observedshopify_graphql_introspect
    • First observedshopify_graphql_query
    • First observedshopify_list_stores
    • First observedshopify_shopifyql

TDQS

A4.7/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a distinct role: store discovery, direct GraphQL reads, schema introspection, async bulk exports, bulk status polling, and ShopifyQL analytics. The potential overlap between graphql_query and bulk_query is clearly resolved by scale and execution model guidance.

Naming Consistency4/5

All tools share a consistent shopify_ prefix and snake_case style, with clear verb/noun combinations like list_stores, bulk_query, and bulk_poll. The name shopify_shopifyql is slightly redundant and breaks the verb-led pattern, but the overall convention remains predictable.

Tool Count5/5

Six tools is well-scoped for a Shopify read/analytics MCP server. Each tool addresses a distinct need without redundancy, and the count is comfortably within the ideal range.

Completeness5/5

The universal GraphQL query tool provides read access to virtually any Shopify resource, while bulk_query and bulk_poll cover large exports and ShopifyQL covers analytics. Store discovery and schema introspection complete the read-only surface, leaving no significant operational dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Production-grade MCP server for the Shopify Admin GraphQL API, exposing typed tools for AI agents to manage products, orders, customers, and more.
    10 npm
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    An MCP server providing six scoped tools for Shopify's Admin API, enabling natural-language querying of chargebacks, orders, refunds, customers, and revenue.
    -
  • A
    license
    A
    quality
    C
    maintenance
    A read-only MCP server that lets AI assistants answer Shopify store operations questions via tools like get_shop, list_products, get_product, and list_orders.
    4
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Security-focused MCP server for Shopify Admin GraphQL with read-only queries by default and mutations requiring preview and one-time confirmation. It manages short-lived tokens internally and enforces strict scope and approval controls.
    4
    6 npm
    -