@missionsquad/mcp-shopify
v2.1.1
Published
MCP Server for Shopify API, enabling interaction with store data through GraphQL API
Maintainers
Readme
@missionsquad/mcp-shopify
MCP Server for the Shopify GraphQL Admin API, built on @missionsquad/fastmcp. Provides tools for managing products, customers, and orders through the Model Context Protocol.
Designed for the MissionSquad platform where user-specific Shopify credentials are injected as hidden secrets at tool-call time via mcp-api. Also supports standalone local development with environment variables.
Features
- Product Management: Full CRUD for products, variants, and options
- Customer Management: Query customers and update customer data
- Order Management: Query and update orders
- GraphQL Integration: Direct integration with Shopify's GraphQL Admin API
- Hidden Secret Injection: Credentials are injected per-call via
context.extraArgs— never exposed to the LLM - Multi-Tenant: Supports concurrent users with different Shopify stores and credentials
Prerequisites
- Node.js >= 20
- A Shopify store with a custom app (see authentication below)
Authentication
This server supports two Shopify authentication methods:
Option 1: Client Credentials (Dev Dashboard apps, January 2026+)
New Shopify apps use OAuth client credentials. The server exchanges clientId + clientSecret for an access token on each tool call.
Option 2: Static Access Token (legacy apps)
Existing custom apps with a static shpat_* access token can pass it directly.
Usage
MissionSquad Platform (Hidden Secrets)
When running via mcp-api, credentials are injected as hidden arguments into context.extraArgs. The LLM never sees these values — they are not part of any tool schema.
Secret keys (stored in mcp-api as mcp-shopify.<key>):
| Key | Description | Required |
|---|---|---|
| accessToken | Shopify Admin API access token (shpat_*) | Yes, if no client credentials |
| clientId | Shopify app client ID | Yes, if no static token |
| clientSecret | Shopify app client secret | Yes, if no static token |
| shopDomain | Store domain (e.g., my-store.myshopify.com) | Always required |
| apiVersion | Shopify API version (default: 2026-01) | No |
mcp-api server registration:
{
"name": "mcp-shopify",
"transportType": "stdio",
"command": "node",
"args": ["./path/to/mcp-shopify/dist/index.js"],
"secretNames": ["accessToken", "shopDomain", "apiVersion", "clientId", "clientSecret"],
"enabled": true
}Local Development (Environment Variables)
For standalone use, create a .env file:
Client Credentials:
SHOPIFY_CLIENT_ID=your_client_id
SHOPIFY_CLIENT_SECRET=your_client_secret
MYSHOPIFY_DOMAIN=your-store.myshopify.comStatic Access Token:
SHOPIFY_ACCESS_TOKEN=shpat_your_access_token
MYSHOPIFY_DOMAIN=your-store.myshopify.comOptional:
SHOPIFY_API_VERSION=2026-01
LOG_LEVEL=infoThen run:
node dist/index.jsClaude Desktop
{
"mcpServers": {
"shopify": {
"command": "node",
"args": ["./path/to/mcp-shopify/dist/index.js"],
"env": {
"SHOPIFY_ACCESS_TOKEN": "shpat_your_token",
"MYSHOPIFY_DOMAIN": "your-store.myshopify.com"
}
}
}
}Available Tools
Product Management
shopify_get_products— Get all products or search by titlesearchTitle(string, optional): Filter products by titlelimit(number, default: 10): Maximum products to return
shopify_get_product_by_id— Get a specific product by IDproductId(string, required): Shopify product GID
shopify_create_product— Create a new producttitle(string, required): Product titledescriptionHtml(string, optional): HTML descriptionhandle(string, optional): URL slug (auto-generated if omitted)vendor(string, optional)productType(string, optional)tags(string[], optional)status(string, optional):ACTIVE,DRAFT, orARCHIVED(default:DRAFT)seo(object, optional):{ title, description }metafields(array, optional):{ namespace, key, value, type }productOptions(array, optional): Options to create inline (max 3)collectionsToJoin(string[], optional): Collection GIDs
shopify_update_product— Update an existing productid(string, required): Product GID- All fields from create (optional), plus
collectionsToLeave,redirectNewHandle
shopify_delete_product— Delete a productid(string, required): Product GID
shopify_manage_product_variants— Create or update variants in bulkproductId(string, required): Product GIDvariants(array, required): Variants to create/update (omitidto create, include to update)strategy(string, optional):DEFAULT,REMOVE_STANDALONE_VARIANT, orPRESERVE_STANDALONE_VARIANT
shopify_manage_product_options— Create, update, or delete product optionsproductId(string, required): Product GIDaction(string, required):create,update, ordelete- Action-specific fields (see schema for details)
shopify_delete_product_variants— Delete variants from a productproductId(string, required): Product GIDvariantIds(string[], required): Variant GIDs to delete
Customer Management
shopify_get_customers— Get customers or search by name/emailsearchQuery(string, optional): Search filterlimit(number, default: 10)
shopify_update_customer— Update a customer's informationid(string, required): Numeric customer ID (not GID)firstName,lastName,email,phone,tags,note,taxExempt,metafields(all optional)
shopify_get_customer_orders— Get orders for a specific customercustomerId(string, required): Numeric customer IDlimit(number, default: 10)
Order Management
shopify_get_orders— Get orders with optional status filterstatus(string, optional):any,open,closed, orcancelled(default:any)limit(number, default: 10)
shopify_get_order_by_id— Get a specific order by IDorderId(string, required): Full order GID
shopify_update_order— Update an existing orderid(string, required): Order GIDtags,email,note,customAttributes,metafields,shippingAddress(all optional)
Development
# Install dependencies
yarn install
# Build
yarn build
# Run tests
yarn test
# Run with coverage
yarn test:coverageArchitecture
src/
index.ts # FastMCP entrypoint (stdio transport)
config.ts # Secret resolution (extraArgs -> env fallback)
shopify-client.ts # Per-call GraphQLClient factory + token exchange
tools.ts # All 14 tool definitions + registration
schemas.ts # Zod schemas (functional params only, no secrets)
errors.ts # Custom error classes + toUserError converter
logger.ts # Stderr logger
stdio-safe-console.ts # Redirect console.log to stderr
json.ts # Deterministic JSON serializationKey design decisions:
- Per-call client creation: A new
GraphQLClientis created for each tool invocation with the resolved credentials. This enables multi-tenant operation where different users have different Shopify stores. - Secret isolation: Credentials flow exclusively through
context.extraArgs->config.ts->shopify-client.ts. They never appear in tool schemas (which are sent to the LLM). - Stateless token exchange: For client credentials auth, the OAuth token exchange happens per-call rather than using background refresh. This is simpler and correct for multi-tenant operation.
License
MIT
