Building a Shopify MCP Server with Claude: Complete Tutorial
Model Context Protocol (MCP) servers let you extend Claude's capabilities with custom tools and data sources. A Shopify MCP server is a bridge between Claude and your Shopify store—giving Claude real-time access to orders, products, inventory, and customers. You can then automate customer service, product recommendations, bulk operations, and strategic analysis without touching the Shopify admin dashboard.
This guide walks you through building, testing, and deploying a Shopify MCP server that Claude can call.
What Is MCP and Why Shopify?
MCP is Anthropic's open standard for connecting Claude to external tools and data. Think of it as a standardized API layer. You build an MCP server; Claude discovers its capabilities; Claude calls them when needed.
The use cases for a Shopify MCP are straightforward:
- Customer service automation — Claude reads an order, reviews order history, and drafts a personalized refund response
- Product recommendations — Claude analyzes purchase history and current inventory to recommend the next product
- Bulk operations — Tag 500 customers by purchase behavior; update 1000 product descriptions with SEO keywords
- Strategic analysis — "Which products have inventory over-stock?" "What's our customer LTV by cohort?"
Traditional APIs require you to write code in Python or Node.js and deploy it somewhere. MCP servers can run locally (on your laptop or server) or deployed as Lambda functions. Claude calls them in real time.
Architecture: How Claude Talks to Your Shopify Store
Claude (Claude Code or API)
↓
MCP Client (Claude's local tool runner)
↓
Your MCP Server (Python/Node.js)
↓
Shopify Admin API / Storefront API
↓
Your Shopify Store Data (orders, products, customers, inventory)
The MCP server acts as a translator: Claude sends a request ("Get orders from the last 7 days"); the MCP server converts that into a Shopify GraphQL query; Shopify returns data; the MCP server formats it for Claude.
Step 1: Set Up Your Shopify Admin API Credentials
You need a Shopify Admin API key to authenticate. Here's how:
- Log into your Shopify admin
- Go to Settings → Apps and integrations → Develop apps
- Click Create an app
- Name it "Claude MCP Server"
- Select Admin API permissions. Request these scopes:
read_ordersread_productsread_customerswrite_orders(if you want to update orders)write_products(if you want to update products)write_inventory(if you want to manage inventory)
- Copy your API Access Token and Store URL (e.g.,
mystore.myshopify.com)
Store these in a .env file:
SHOPIFY_STORE_URL=mystore.myshopify.com
SHOPIFY_API_KEY=shpat_xxxxxxxxxxxxx
SHOPIFY_API_VERSION=2026-01
Step 2: Build Your MCP Server
Here's a minimal Python MCP server using the mcp library:
import os
import json
import httpx
from typing import Any
from mcp.server import Server, RequestContext
from mcp.types import Tool, TextContent, ToolResponse
# Initialize MCP server
server = Server("shopify-mcp")
# Load credentials from .env
SHOPIFY_STORE_URL = os.getenv("SHOPIFY_STORE_URL")
SHOPIFY_API_KEY = os.getenv("SHOPIFY_API_KEY")
SHOPIFY_API_VERSION = os.getenv("SHOPIFY_API_VERSION", "2026-01")
SHOPIFY_URL = f"https://{SHOPIFY_STORE_URL}/admin/api/{SHOPIFY_API_VERSION}/graphql.json"
def run_shopify_query(query: str, variables: dict = None) -> dict:
"""Execute a GraphQL query against Shopify Admin API."""
headers = {
"X-Shopify-Access-Token": SHOPIFY_API_KEY,
"Content-Type": "application/json",
}
payload = {
"query": query,
"variables": variables or {}
}
response = httpx.post(SHOPIFY_URL, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
if "errors" in data:
raise Exception(f"Shopify GraphQL error: {data['errors']}")
return data["data"]
@server.call_tool()
def get_recent_orders(days: int = 7) -> str:
"""Fetch orders from the last N days."""
query = """
query GetRecentOrders($query: String!) {
orders(first: 50, query: $query) {
edges {
node {
id
name
email
totalPriceSet {
shopMoney {
amount
currencyCode
}
}
createdAt
displayFulfillmentStatus
lineItems(first: 5) {
edges {
node {
title
quantity
}
}
}
}
}
}
}
"""
variables = {
"query": f"created:>={days}d"
}
result = run_shopify_query(query, variables)
return json.dumps(result, indent=2)
@server.call_tool()
def get_product_by_handle(handle: str) -> str:
"""Fetch product details by handle (URL slug)."""
query = """
query GetProduct($handle: String!) {
productByHandle(handle: $handle) {
id
title
description
totalInventory
priceRange {
minVariantPrice {
amount
currencyCode
}
maxVariantPrice {
amount
currencyCode
}
}
variants(first: 10) {
edges {
node {
id
title
sku
inventoryQuantity
price
}
}
}
}
}
"""
variables = {"handle": handle}
result = run_shopify_query(query, variables)
return json.dumps(result, indent=2)
@server.call_tool()
def get_customer(email: str) -> str:
"""Fetch customer by email."""
query = """
query GetCustomer($email: String!) {
customers(first: 1, query: $email) {
edges {
node {
id
email
firstName
lastName
lifetimeValue {
amount
currencyCode
}
ordersCount
createdAt
lastOrder {
createdAt
totalPriceSet {
shopMoney {
amount
}
}
}
}
}
}
}
"""
variables = {"email": email}
result = run_shopify_query(query, variables)
return json.dumps(result, indent=2)
if __name__ == "__main__":
server.run()
Step 3: Register Tools with Claude
Once your MCP server is running, Claude needs to discover its tools. Add this to your Claude Code config (or Claude API settings):
{
"mcpServers": {
"shopify": {
"command": "python",
"args": ["/path/to/shopify_mcp.py"],
"env": {
"SHOPIFY_STORE_URL": "mystore.myshopify.com",
"SHOPIFY_API_KEY": "shpat_xxxxx"
}
}
}
}
Claude will now see three tools:
get_recent_orders— Fetch recent ordersget_product_by_handle— Fetch product detailsget_customer— Fetch customer info
Step 4: Query from Claude
Now you can ask Claude questions and it will use your MCP server:
Claude Code Prompt:
"What's our average order value from the last 7 days? Show me the top 5 products by order count."
Claude's Internal Logic:
1. Calls get_recent_orders(days=7)
2. Parses the order data
3. Calculates average order value
4. Counts product occurrences
5. Returns analysis
Advanced Patterns
Pattern 1: Bulk Customer Tagging by Behavior
Ask Claude: "Tag all customers who spent over $500 in the last 30 days with 'high-value'"
Claude would:
- Call
get_recent_orders(days=30)to fetch all orders - Aggregate by customer email
- Filter customers with total spend > $500
- Call a custom
tag_customer()tool to apply the "high-value" tag
Pattern 2: Inventory Alerts
Ask Claude: "Which products have less than 5 units in stock?"
Claude would:
- Call a custom
list_all_products()tool (you'd need to build this) - Filter by inventory quantity
- Return a formatted list with product names, SKUs, and stock levels
Pattern 3: Customer Service Automation
Ask Claude: "I have a refund request from [email protected] for order #1234. Should we approve it? Draft a response."
Claude would:
- Call
get_customer(email="[email protected]") - Call a custom
get_order(id="1234")tool - Analyze purchase history and order details
- Draft a personalized response
Deployment Options
Option 1: Local Development (Free)
Run the MCP server on your laptop. Works for manual requests but not scalable for production.
Option 2: AWS Lambda (Serverless)
Deploy your MCP server as a Lambda function. Cost: ~$0.20/million requests (negligible for most use cases).
Option 3: Docker Container
Containerize your MCP server and deploy to AWS ECS, Google Cloud Run, or DigitalOcean App Platform. Cost: $5–$30/month depending on traffic.
Common Pitfalls
Pitfall 1: Rate Limiting
Shopify Admin API has rate limits (2 requests/second for most plans). If Claude makes 10 requests in quick succession, you'll hit the limit. Solution: Add exponential backoff retry logic.
Pitfall 2: GraphQL Complexity
Each Shopify GraphQL query has a complexity score. Too many nested fields = error. Solution: Keep queries focused (query only fields you need).
Pitfall 3: API Permissions
If Claude asks for something your API key doesn't have permission for, it fails silently. Solution: Regularly audit your scopes. Only request what you need.
The Tenten Shopify MCP
Tenten has built a production-grade Shopify MCP server used by Shopify Plus partners for:
- Customer service automation (reduce response time by 60%)
- Bulk product updates (update 1000 product descriptions in 5 minutes)
- Inventory analysis (identify over-stock and under-stock patterns)
- Strategic cohort analysis (LTV by acquisition channel, repeat purchase rate by product)
Our MCP server includes authentication, error handling, rate limit management, and caching. We can customize it for your specific use cases.
Ready to Automate Your Shopify Operations with Claude?
Building an MCP server requires understanding both Shopify's API and Claude's tool calling conventions. Tenten specializes in Shopify API architecture, MCP development, and Claude integration for Shopify Plus merchants. We can build a custom MCP server tailored to your operational needs.
Contact Tenten for an MCP development consultation at tenten.co/contact.
Editorial Note
This tutorial draws on Tenten's production deployments of Shopify MCP servers for Shopify Plus partners. Code examples use Python 3.10+ and the mcp library (Anthropic). Shopify API version 2026-01 (current as of April 2026).