
Shopify MCP Server
Enables interaction with Shopify store data through GraphQL API, providing tools for managing products, customers, orders, blogs, and articles.
README
Shopify MCP Server
(please leave a star if you like!)
MCP Server for Shopify API, enabling interaction with store data through GraphQL API. This server provides tools for managing products, customers, orders, and more.
📦 Package Name: shopify-mcp
🚀 Command: shopify-mcp
(NOT shopify-mcp-server
)
<a href="https://glama.ai/mcp/servers/@GeLi2001/shopify-mcp"> <img width="380" height="200" src="https://glama.ai/mcp/servers/@GeLi2001/shopify-mcp/badge" alt="Shopify MCP server" /> </a>
Features
- Product Management: Search, retrieve, and update product information, including SEO-optimized content
- Customer Management: Load customer data and manage customer tags
- Order Management: Advanced order querying and filtering
- Blog Management: Create, retrieve, and update blogs with custom templates and comment policies
- Article Management: Create and manage blog articles with rich content, author information, and SEO metadata
- Store Search: Unified search across products, articles, blogs, and pages
- GraphQL Integration: Direct integration with Shopify's GraphQL Admin API
- Comprehensive Error Handling: Clear error messages for API and authentication issues
- LLM-Optimized: Designed for seamless use with AI language models
Prerequisites
- Node.js (version 16 or higher)
- Shopify Custom App Access Token (see setup instructions below)
Setup
Shopify Access Token
To use this MCP server, you'll need to create a custom app in your Shopify store:
- From your Shopify admin, go to Settings > Apps and sales channels
- Click Develop apps (you may need to enable developer preview first)
- Click Create an app
- Set a name for your app (e.g., "Shopify MCP Server")
- Click Configure Admin API scopes
- Select the following scopes:
read_products
,write_products
read_customers
,write_customers
read_orders
,write_orders
read_content
,write_content
(for blogs and articles)
- Click Save
- Click Install app
- Click Install to give the app access to your store data
- After installation, you'll see your Admin API access token
- Copy this token - you'll need it for configuration
Usage with Claude Desktop
Add this to your claude_desktop_config.json
:
{
"mcpServers": {
"shopify": {
"command": "npx",
"args": [
"shopify-mcp",
"--accessToken",
"<YOUR_ACCESS_TOKEN>",
"--domain",
"<YOUR_SHOP>.myshopify.com"
]
}
}
}
Locations for the Claude Desktop config file:
- MacOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%/Claude/claude_desktop_config.json
Alternative: Run Locally with Environment Variables
If you prefer to use environment variables instead of command-line arguments:
-
Create a
.env
file with your Shopify credentials:SHOPIFY_ACCESS_TOKEN=your_access_token MYSHOPIFY_DOMAIN=your-store.myshopify.com
-
Run the server with npx:
npx shopify-mcp
Direct Installation (Optional)
If you want to install the package globally:
npm install -g shopify-mcp
Then run it:
shopify-mcp --accessToken=<YOUR_ACCESS_TOKEN> --domain=<YOUR_SHOP>.myshopify.com
⚠️ Important: If you see errors about "SHOPIFY_ACCESS_TOKEN environment variable is required" when using command-line arguments, you might have a different package installed. Make sure you're using shopify-mcp
, not shopify-mcp-server
.
Available Tools
Product Management
-
get-products
- Get products or search by title with cursor-based navigation
- Inputs:
searchTitle
(optional string): Filter products by titlelimit
(optional number, default: 10): Maximum number of products to returnafter
(optional string): Cursor for pagination - get items after this cursorbefore
(optional string): Cursor for pagination - get items before this cursorreverse
(optional boolean, default: false): Reverse the order of the returned products
- Returns:
- Object containing:
products
: Array of products, each containing:title
: Product title (SEO-optimized)description
: Plain text product descriptiondescriptionHtml
: HTML-formatted product description- Additional fields: id, handle, status, inventory, pricing, etc.
cursor
: Cursor for pagination
pageInfo
: Pagination information containing:hasNextPage
: Whether there are more items after the current pagehasPreviousPage
: Whether there are more items before the current pagestartCursor
: Cursor for the first item in the current pageendCursor
: Cursor for the last item in the current page
- Object containing:
🌟 Navigation Examples:
- Basic Pagination:
// Get first page of products { "limit": 10 } // Get next page using the endCursor from previous response { "limit": 10, "after": "endCursor_from_previous_response" } // Get previous page using the startCursor from current response { "limit": 10, "before": "startCursor_from_current_response" }
- Search with Pagination:
// Search products with pagination { "searchTitle": "t-shirt", "limit": 5, "after": "cursor_from_previous_response" }
- Reverse Order:
// Get products in reverse order { "limit": 10, "reverse": true }
💡 Pagination Tips:
- Store both
startCursor
andendCursor
from each response - Use
hasNextPage
andhasPreviousPage
to show/hide navigation controls - Keep the same
limit
value for consistent page sizes - Use
reverse
when you need newest/oldest items first - Combine with
searchTitle
for paginated search results
-
get-product-by-id
- Get a specific product by ID with all its details
- Inputs:
productId
(string): The GID of the product to fetch (e.g., "gid://shopify/Product/1234567890")
- Returns:
- Single product object containing:
title
: Product title (SEO-optimized)description
: Plain text product descriptiondescriptionHtml
: HTML-formatted product description- Additional fields: id, handle, status, inventory, pricing, variants, collections, etc.
- Single product object containing:
-
update-product
- Update any aspect of a product including basic details, SEO, and variants
- Inputs:
productId
(required string): The product's ID (e.g., "gid://shopify/Product/1234567890")title
(optional string): New product titledescriptionHtml
(optional string): Product description in HTML formatseo
(optional object): SEO settingstitle
(optional string): SEO-optimized titledescription
(optional string): Meta description for search engines
status
(optional string): Product status - "ACTIVE", "ARCHIVED", or "DRAFT"vendor
(optional string): Product manufacturer or brandproductType
(optional string): Category or type of producttags
(optional array of strings): Product tags for categorizationvariants
(optional array of objects): Product variants to updateid
(string): Variant ID to updateprice
(optional string): New pricecompareAtPrice
(optional string): Original/compare-at pricesku
(optional string): Stock Keeping Unitbarcode
(optional string): Product barcodeinventoryPolicy
(optional string): "DENY" or "CONTINUE" for out-of-stock behavior
🌟 Beginner's Guide to Updating Products
- Basic Product Update:
// Update product title and status { "productId": "gid://shopify/Product/1234567890", "title": "Awesome T-Shirt", "status": "ACTIVE" }
- Update SEO Information:
// Make your product more visible in search results { "productId": "gid://shopify/Product/1234567890", "seo": { "title": "Awesome T-Shirt | 100% Cotton | Available in 5 Colors", "description": "High-quality cotton t-shirt perfect for everyday wear. Available in multiple colors and sizes." } }
- Update Product Variants:
// Change prices and inventory settings { "productId": "gid://shopify/Product/1234567890", "variants": [ { "id": "gid://shopify/ProductVariant/1234567", "price": "29.99", "compareAtPrice": "39.99", "inventoryPolicy": "DENY" } ] }
- Complete Product Update:
// Update multiple aspects at once { "productId": "gid://shopify/Product/1234567890", "title": "Premium Cotton T-Shirt", "vendor": "Fashion Basics", "productType": "Apparel", "tags": ["cotton", "t-shirt", "basics", "summer"], "seo": { "title": "Premium Cotton T-Shirt | Fashion Basics | Multiple Colors", "description": "Experience comfort with our premium cotton t-shirt. Perfect for any occasion." }, "variants": [ { "id": "gid://shopify/ProductVariant/1234567", "price": "29.99", "compareAtPrice": "39.99" } ] }
💡 Tips for New Users:
- Start Small: Begin with simple updates (like title or price) before trying complex changes
- Test First: Always test updates on a draft product before modifying live products
- Check IDs: Make sure you have the correct product and variant IDs
- SEO Best Practices:
- Keep SEO titles under 60 characters
- Write descriptive meta descriptions (150-160 characters)
- Include relevant keywords naturally
- Pricing Strategy:
- Use
compareAtPrice
to show savings - Keep prices consistent across variants unless size/material differs
- Use
- Inventory Management:
- Use "DENY" for limited stock items
- Use "CONTINUE" for made-to-order items
⚠️ Common Mistakes to Avoid:
- Forgetting to include the product ID
- Using wrong ID formats (always use the full GID format)
- Setting invalid prices (must be strings, not numbers)
- Mixing up variant IDs
- Using HTML in regular text fields
🔍 How to Find IDs:
- Product ID: Available in the product URL or using
get-products
- Variant ID: Use
get-product-by-id
to see all variants - Always use the full GID format: "gid://shopify/Product/1234567890"
-
update-product-image-alt-text
- Update the alt text for a specific product image
- Inputs:
productId
(string): The GID of the product to which the image belongs (e.g., "gid://shopify/Product/1234567890")imageId
(string): The GID of the product image/media to update (e.g., "gid://shopify/MediaImage/123")altText
(string | null): The new descriptive alt text for the image. Set to null to remove. Best practice is to keep it under 125 characters, max 512.
- Returns:
- Updated media object containing:
id
: The media IDaltText
: The updated alt text
- Updated media object containing:
Collection Management
get-collections
- Get collections or search by title
- Inputs:
searchTitle
(optional string): Filter collections by titlelimit
(optional number, default: 10): Maximum number of collections to return
Blog Management
-
get-blogs
- Get all blogs or search by title
- Inputs:
searchTitle
(optional string): Filter blogs by titlelimit
(optional number, default: 10): Maximum number of blogs to return
- Returns:
- Array of blogs containing:
id
: Blog IDtitle
: Blog titlehandle
: URL-friendly handletemplateSuffix
: Template suffix for custom themescommentPolicy
: Comment moderation policycreatedAt
: Creation timestampupdatedAt
: Last update timestamp
- Array of blogs containing:
-
update-blog
- Update an existing blog's details
- Inputs:
blogId
(string, required): The GID of the blog to update (e.g., "gid://shopify/Blog/1234567890")title
(optional string): New blog titlehandle
(optional string): New URL-friendly handletemplateSuffix
(optional string): New template suffix for custom themescommentPolicy
(optional string): New comment policy ("MODERATED" or "CLOSED")
- Returns:
- Updated blog object with the modified fields
-
get-blog-by-id
- Get a specific blog by ID with all its details
- Inputs:
blogId
(string, required): The GID of the blog to fetch
- Returns:
- Blog object containing:
id
: Blog IDtitle
: Blog titlehandle
: URL-friendly handletemplateSuffix
: Template suffixcommentPolicy
: Comment policyarticles
: Recent articles (first 5)
- Blog object containing:
Article Management
-
get-articles
- Get articles from a specific blog
- Inputs:
blogId
(string, required): The GID of the blog to get articles fromsearchTitle
(optional string): Filter articles by titlelimit
(optional number, default: 10): Maximum number of articles to return
- Returns:
- Array of articles containing:
id
: Article IDtitle
: Article titlehandle
: URL-friendly handleauthor
: Author informationpublishedAt
: Publication datetags
: Associated tagsimage
: Featured image (if any)
- Array of articles containing:
-
create-article
- Create a new article in a specified blog
- Inputs:
blogId
(string, required): The GID of the blog to create the article intitle
(string, required): The title of the articlecontent
(string, required): The content of the article in HTML formatauthor
(object, required):name
(string, required): The name of the article's author
published
(optional boolean): Whether to publish immediately (default: false)tags
(optional array of strings): Tags to categorize the article
- Returns:
- Created article object containing:
id
: Article IDtitle
: Article titlehandle
: URL-friendly handle (auto-generated from title)body
: Article contentsummary
: Article summary (if provided)author
: Author informationtags
: Associated tagsimage
: Featured image details (if provided)
- Created article object containing:
- Example Usage:
// Create a published article with formatted content { "blogId": "gid://shopify/Blog/123456789", "title": "My New Article", "content": "<p>Article content with <strong>HTML formatting</strong>.</p>", "author": { "name": "John Doe" }, "published": true, "tags": ["news", "updates"] } // Create a draft article with future publication { "blogId": "gid://shopify/Blog/123456789", "title": "Upcoming Article", "content": "<p>Draft content...</p>", "author": { "name": "Jane Smith" }, "published": false, "tags": ["draft"] }
-
update-article
- Update an existing article's details
- Inputs:
articleId
(string, required): The GID of the article to updatetitle
(optional string): New article titlebody
(optional string): New article contentsummary
(optional string): New article summarytags
(optional array of strings): New article tagsauthor
(optional object): Author informationname
(string): Author's name
- Returns:
- Updated article object with the modified fields
-
get-article-by-id
- Get a specific article by ID with all its details
- Inputs:
articleId
(string, required): The GID of the article to fetch
- Returns:
- Article object containing:
id
: Article IDtitle
: Article titlehandle
: URL-friendly handleauthor
: Author informationbody
: Article contentblog
: Parent blog informationtags
: Associated tags
- Article object containing:
Important Notes for Blog and Article Management
-
Working with Blog Content
- Always use
get-blogs
first to obtain valid blog IDs - Use
get-blog-by-id
to fetch detailed information about a specific blog - When updating blogs, only include the fields you want to modify
- The
commentPolicy
can only be set to "MODERATED" or "CLOSED"
- Always use
-
Working with Articles
- Articles must be associated with an existing blog
- Use
get-articles
to list articles within a specific blog - When creating or updating articles, the
body
field supports HTML content - Author information should always include at least the name
- Tags are case-sensitive and should be consistent across articles
- Image URLs must be publicly accessible
- Handle creation is optional - Shopify will generate one from the title if not provided
-
Best Practices for Article Creation
- Use semantic HTML for article content (e.g.,
<p>
,<h2>
,<ul>
, etc.) - Keep article summaries concise (recommended: 150-160 characters)
- Use consistent tag naming conventions
- Always verify blog IDs before creating articles
- Consider SEO implications when writing titles and content
- Test HTML formatting in a staging environment first
- For drafts, set
published: false
to save without publishing - When using tags, maintain a consistent taxonomy
- Provide descriptive alt text for any images
- Schedule articles strategically using publishDate
- Keep HTML content clean and well-structured
- Use meaningful handles for better SEO
- Consider mobile readability when formatting content
- Use semantic HTML for article content (e.g.,
-
Article Creation Tips
- HTML Content: The content field accepts HTML markup for rich formatting:
<p>First paragraph with <strong>bold text</strong>.</p> <h2>Section Heading</h2> <ul> <li>List item one</li> <li>List item two</li> </ul>
- Tags: Use descriptive, consistent tags for better organization:
"tags": ["product-updates", "how-to", "tips"]
- Draft Mode: Create unpublished drafts by setting published to false:
{ "published": false, // other fields... }
- Author Information: Always provide complete author details:
"author": { "name": "Full Author Name" }
- HTML Content: The content field accepts HTML markup for rich formatting:
Store Search
search-shopify
- Perform a unified search across products, articles, blogs, and pages
- Inputs:
query
(string, required): The search query to find content across the storetypes
(optional array of strings): Types of resources to search for. Available types:- "ARTICLE"
- "BLOG"
- "PAGE"
- "PRODUCT"
first
(optional number, default: 10, max: 50): Number of results to return
- Returns:
- Array of search results, each containing:
id
: Resource IDtitle
: Resource titletype
: Resource typeurl
: Resource URL- Additional fields based on resource type
- Array of search results, each containing:
- Example Usage:
// Search for articles and blogs about "kawaii" { "query": "kawaii", "types": ["ARTICLE", "BLOG"], "first": 5 } // Search across all content types { "query": "new collection", "first": 10 }
Page Management
-
get-pages
- Get all pages or search by title
- Inputs:
searchTitle
(optional string): Filter pages by titlelimit
(optional number, default: 10): Maximum number of pages to return
- Returns:
- Array of pages containing:
id
: Page IDtitle
: Page titlehandle
: URL-friendly handlebody
: Page contentbodySummary
: Content summarycreatedAt
: Creation timestampupdatedAt
: Last update timestamp
- Array of pages containing:
-
update-page
- Update an existing page's details
- Inputs:
pageId
(string, required): The GID of the page to update (e.g., "gid://shopify/Page/1234567890")title
(optional string): New page titlebody
(optional string): New page contentbodyHtml
(optional string): New HTML contentseo
(optional object): SEO settingstitle
(optional string): SEO titledescription
(optional string): SEO description
published
(optional boolean): Whether the page is published
- Returns:
- Updated page object with modified fields
- Example Usage:
// Update page content and SEO { "pageId": "gid://shopify/Page/123456789", "title": "About Our Store", "bodyHtml": "<h1>Welcome!</h1><p>Learn about our story...</p>", "seo": { "title": "About Us - Kawaii Store", "description": "Discover our journey in bringing kawaii culture to you" } }
Collection Management
-
get-collections
- Get all collections or search by title
- Inputs:
searchTitle
(optional string): Filter collections by titlelimit
(optional number, default: 10): Maximum number of collections to return
- Returns:
- Array of collections containing:
id
: Collection IDtitle
: Collection titlehandle
: URL-friendly handledescription
: Collection descriptiondescriptionHtml
: HTML-formatted descriptionupdatedAt
: Last update timestampproductsCount
: Number of products in collection
- Array of collections containing:
-
update-collection
- Update an existing collection's details
- Inputs:
collectionId
(string, required): The GID of the collection to updatetitle
(optional string): New collection titledescription
(optional string): New collection descriptiondescriptionHtml
(optional string): New HTML descriptionseo
(optional object): SEO settingstitle
(optional string): SEO titledescription
(optional string): SEO description
- Returns:
- Updated collection object with modified fields
- Example Usage:
// Update collection with SEO optimization { "collectionId": "gid://shopify/Collection/123456789", "title": "Summer Kawaii Collection", "descriptionHtml": "<p>Discover our cutest summer items!</p>", "seo": { "title": "Summer Kawaii Collection 2025", "description": "Explore our adorable summer collection featuring..." } }
Product Management
-
get-products
- Get all products or search by title
- Inputs:
searchTitle
(optional string): Filter products by titlelimit
(optional number, default: 10): Maximum number of products to return
- Returns:
- Array of products containing:
id
: Product IDtitle
: Product titlehandle
: URL-friendly handledescription
: Product descriptiondescriptionHtml
: HTML-formatted descriptionstatus
: Product statustotalInventory
: Total inventory countpriceRange
: Product price rangeimages
: Product images
- Array of products containing:
-
get-product-by-id
- Get detailed information about a specific product
- Inputs:
productId
(string, required): The GID of the product to fetch
- Returns:
- Product object containing:
id
: Product IDtitle
: Product titlehandle
: URL-friendly handledescription
: Product descriptiondescriptionHtml
: HTML-formatted descriptionstatus
: Product statustotalInventory
: Total inventory countvariants
: Product variantsimages
: Product imagescollections
: Associated collections
- Product object containing:
-
update-product
- Update a product's details
- Inputs:
productId
(string, required): The GID of the product to updatetitle
(optional string): New product titledescriptionHtml
(optional string): New HTML description
- Returns:
- Updated product object containing:
id
: Product IDtitle
: Updated titledescriptionHtml
: Updated descriptionupdatedAt
: Update timestamp
- Updated product object containing:
Best Practices for Content Management
-
SEO Optimization
- Use descriptive titles and handles
- Provide meta descriptions for all content
- Include relevant keywords naturally
- Keep URLs clean and meaningful
- Use proper heading hierarchy in HTML content
-
Content Organization
- Group related products in collections
- Use consistent naming conventions
- Maintain a clear content hierarchy
- Keep product descriptions detailed and accurate
- Use high-quality images with descriptive alt text
-
Performance Considerations
- Optimize image sizes
- Use appropriate query limits
- Cache frequently accessed content
- Batch updates when possible
- Monitor API usage
-
Content Management Tips
- Regular content audits
- Consistent branding across all content
- Mobile-friendly formatting
- Regular backups of important content
- Version control for major changes
Error Handling
All tools include comprehensive error handling:
- Invalid ID errors
- Permission errors
- Rate limiting errors
- Validation errors
- Network errors
Error responses include:
- Error code
- Field causing the error
- Detailed error message
- Suggestions for resolution
API Limitations
-
Rate Limits
- Respect Shopify's API rate limits
- Use appropriate query limits
- Implement retry logic for failed requests
- Monitor API usage
-
Content Restrictions
- Maximum content lengths
- Supported HTML tags
- Image size limits
- API version compatibility
-
Authentication
- Required access scopes
- Token expiration
- IP restrictions
- App permissions
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.