A production-oriented Model Context Protocol server that exposes the Shopify Admin GraphQL API to AI assistants. Connect Claude Desktop, Claude Code, or any MCP-compatible client to manage products, customers, orders, inventory, and metafields through a typed tool interface.
- Overview
- Architecture
- Features
- Requirements
- Installation
- Configuration
- Development
- Testing
- Project Structure
- Troubleshooting
- Contributing
- FAQ
- License
This server translates MCP tool calls into Shopify Admin GraphQL operations. It supports static access tokens and OAuth client-credentials (Dev Dashboard apps), optional Redis-backed token persistence, structured JSON logging, and graceful shutdown.
flowchart LR
Client[MCP Client] -->|stdio JSON-RPC| Server[MCP Server]
Server --> Tools[Tool Registry]
Tools --> GraphQL[Shopify Admin GraphQL]
Server --> Auth[OAuth Token Manager]
Auth --> Redis[(Redis Cache)]
Auth --> GraphQL
| Layer | Responsibility |
|---|---|
src/index.ts |
Process entry, error boundary |
src/server/ |
Bootstrap, MCP wiring, shutdown hooks |
src/config/ |
Environment and CLI configuration |
src/lib/ |
Auth, logging, Redis, shared utilities |
src/tools/ |
40 MCP tools (products, orders, customers, …) |
sequenceDiagram
participant C as MCP Client
participant M as McpServer
participant T as Tool
participant S as Shopify API
C->>M: tools/call
M->>T: execute(args)
T->>T: Zod schema validation
T->>S: GraphQL request
S-->>T: Response
T-->>M: Formatted JSON
M-->>C: MCP content block
sequenceDiagram
participant S as Server
participant R as Redis
participant SH as Shopify OAuth
S->>R: Check cached token
alt Valid cache hit
R-->>S: access_token
else Cache miss
S->>SH: client_credentials grant
SH-->>S: access_token + expires_in
S->>R: Store token with TTL
end
Note over S: Auto-refresh 5 min before expiry
| Category | Capabilities |
|---|---|
| Products | CRUD, variants, options, collections |
| Customers | CRUD, merge, address management |
| Orders | Query, cancel, fulfill, refund, draft orders |
| Metafields | Read, write, delete on any resource |
| Inventory | Set quantities, read levels and items |
| Discovery | Shop info, locations, markets, price lists |
| Platform | Redis token cache, structured logging, graceful shutdown, strict TypeScript |
All list tools support cursor pagination, sorting, and Shopify search syntax filtering.
- Node.js 18 or later
- Shopify store with a custom app and Admin API scopes
- Redis (optional) for OAuth token persistence across restarts
read_products, write_products, read_customers, write_customers, read_orders, write_orders (plus scopes for inventory/metafields as needed).
npx shopify-mcp \
--clientId YOUR_CLIENT_ID \
--clientSecret YOUR_CLIENT_SECRET \
--domain your-store.myshopify.comgit clone https://github.com/GeLi2001/shopify-mcp.git
cd shopify-mcp
npm install
npm run build
npm startAdd to claude_desktop_config.json:
{
"mcpServers": {
"shopify": {
"command": "npx",
"args": [
"shopify-mcp",
"--clientId", "<CLIENT_ID>",
"--clientSecret", "<CLIENT_SECRET>",
"--domain", "<store>.myshopify.com"
]
}
}
}Config locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json
Copy .env.example to .env and fill in values:
cp .env.example .env| Variable | Required | Description |
|---|---|---|
MYSHOPIFY_DOMAIN |
Yes | Store domain, e.g. store.myshopify.com |
SHOPIFY_ACCESS_TOKEN |
Option A | Static shpat_ token (legacy apps) |
SHOPIFY_CLIENT_ID |
Option B | Dev Dashboard client ID |
SHOPIFY_CLIENT_SECRET |
Option B | Dev Dashboard client secret |
SHOPIFY_API_VERSION |
No | API version (default: 2026-01) |
LOG_LEVEL |
No | debug, info, warn, error |
REDIS_ENABLED |
No | Enable Redis persistence (true/false) |
REDIS_URL |
If Redis | Connection URL, e.g. redis://127.0.0.1:6379 |
REDIS_KEY_PREFIX |
No | Key namespace prefix (default: shopify-mcp:) |
REDIS_MAX_RETRIES |
No | Max command retries (default: 10) |
REDIS_CONNECT_TIMEOUT_MS |
No | Connect timeout in ms (default: 10000) |
CLI flags (--accessToken, --clientId, --clientSecret, --domain, --apiVersion) override environment variables.
# Install dependencies
npm install
# Run in development (TypeScript directly)
npm run dev
# Full validation pipeline
npm run validate
# GraphQL schema validation
npm run validate:graphql| Script | Purpose |
|---|---|
npm run build |
Compile TypeScript to dist/ |
npm run typecheck |
Type-check source and tests |
npm run lint |
ESLint |
npm test |
Jest unit tests |
npm run validate |
typecheck + lint + test + build |
Tests live in tests/ and cover configuration parsing, logging, error utilities, and Redis token caching.
npm testTests use mocked Redis clients — no running Redis instance required for the test suite.
shopify-mcp/
├── docs/
│ └── AUDIT.md # Internal architecture audit
├── src/
│ ├── config/ # Environment loading (Zod-validated)
│ ├── lib/ # Auth, logging, Redis, tool factory
│ │ └── redis/ # Connection manager + token cache
│ ├── server/ # Bootstrap, MCP server, shutdown
│ ├── tools/ # MCP tool implementations
│ └── index.ts # Entry point
├── tests/ # Unit tests
├── .env.example # Configuration template
├── .github/workflows/ # CI (build, lint, test, typecheck)
└── package.json
Design decisions:
- Tools use a
createTool()factory to eliminate duplicated GraphQL client wiring. - Configuration is centralized in
src/config/env.tswith Zod validation. - OAuth tokens optionally persist in Redis so restarts do not force re-authentication.
- Logs are structured JSON on stderr (safe for stdio MCP transport).
Authentication credentials are required
Provide either SHOPIFY_ACCESS_TOKEN or both SHOPIFY_CLIENT_ID and SHOPIFY_CLIENT_SECRET.
If you see errors referencing a different package name, verify you are running shopify-mcp (this package), not a similarly named alternative.
Check Claude Desktop MCP logs:
# macOS
tail -f ~/Library/Logs/Claude/mcp*.logEnsure the server starts without errors:
SHOPIFY_ACCESS_TOKEN=shpat_xxx MYSHOPIFY_DOMAIN=store.myshopify.com npm startIf REDIS_ENABLED=true but Redis is unreachable, the server exits at startup. Either start Redis locally or set REDIS_ENABLED=false.
docker run -d -p 6379:6379 redis:7-alpineShopify returns field-level errors in mutation responses. The server surfaces these as Failed to <operation>: field: message.
- Fork the repository and create a feature branch.
- Run
npm run validatebefore opening a pull request. - Keep commits focused and write clear commit messages.
- Add tests for new library or configuration behavior.
- Do not commit secrets,
.env, orpackage-lock.json.
Does this replace the Shopify Admin UI?
No. It provides programmatic access for AI assistants via MCP.
Can I use a static access token?
Yes. Set SHOPIFY_ACCESS_TOKEN for legacy custom apps with shpat_ tokens.
Is Redis required?
No. Redis is optional and only caches OAuth tokens for client-credentials auth.
How many tools are available?
40 tools covering products, customers, orders, metafields, inventory, and store discovery.
Which API version is used?
Default 2026-01. Override with SHOPIFY_API_VERSION or --apiVersion.
Why JSON logs on stderr?
MCP uses stdout for the protocol. Logs must go to stderr to avoid corrupting the transport.
MIT — see LICENSE.