cob-shopify-mcp

io.github.callobuzzPublished by GitHub account callobuzzv0.12.1Updated Nov 12, 2026

Run a Shopify store from any MCP client: products, orders, customers, stock and analytics.

VerifiedSTDIODesktop onlyData & AnalyticsBusiness & Commerce

Overview

AI-generated overview

Connects an AI assistant to a Shopify store's Admin API to manage products, orders, customers, inventory and run sales analytics.

What you can do
  • List, search, create and update products, variants, collections and tags
  • List, search and inspect orders, add notes and tags, create draft orders, mark paid, cancel, and manage fulfillments and tracking
  • List, search, create and update customers, their orders, lifetime value and tags
  • Check inventory items and levels by SKU or location, run low-stock reports, adjust quantities
  • Run ShopifyQL analytics: sales summaries, top products, refund and repeat-customer rates, cohorts, funnels, traffic and inventory risk
  • Expose shop info, locations, policies and currencies as resources, plus ready-made prompts such as health check and sales report
When to use it
Useful when an assistant should answer questions about a live Shopify store or act on it: product and stock lookups, order and fulfillment support, customer history, and sales reporting, including read-only setups.
Requirements
Runs locally as an npm package (Node.js) over stdio, or as an HTTP container. Needs SHOPIFY_STORE_DOMAIN plus either SHOPIFY_ACCESS_TOKEN or SHOPIFY_CLIENT_ID and SHOPIFY_CLIENT_SECRET from a Shopify app installed on the store, with the relevant scopes granted. Network access to the Shopify API.
Before you install
The credentials grant broad store access; the README's full-access scope list includes write scopes for products, orders, customers, inventory and fulfillments. Tools can create, update, cancel and mark orders paid, change stock and customer data. Set COB_SHOPIFY_READ_ONLY=true and grant only read scopes if you want read-only use. Keep secrets out of shared config files.

Installation

In SourceWeft

  1. Open cob-shopify-mcp in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

cob-shopify-mcp

[npm version] [build] [license] [node] [tools] [TypeScript] [GitHub stars]

The most complete open-source MCP server and CLI for Shopify. 62 built-in tools + 2 custom tool examples across 5 domains — use it as an MCP server for AI agents (Claude, Cursor, Windsurf) or as a standalone CLI to manage Shopify stores directly from your terminal.

Features

  • 62 built-in tools + 2 custom tool examples across 5 domains — Products (15), Orders (15), Customers (9), Inventory (7), Analytics (16)
  • Standalone CLI — natural domain commands from the terminal without MCP (cob-shopify products list --limit 5, orders get --id ..., etc.)
  • MCP server — connect to Claude, Cursor, Windsurf, or any MCP-compatible AI agent
  • 4 MCP resources (Shop info, Locations, Policies, Currencies)
  • 4 MCP prompts (Health check, Sales report, Inventory risk, Support summary)
  • Dual transport — stdio (default) + Streamable HTTP
  • 3 auth methods — Static token, OAuth client credentials, OAuth authorization code
  • Both Shopify GraphQL APIs — Admin by default, Storefront via api: storefront on a custom tool, for the objects that exist on one schema only (Shop.brand — the merchant's logo and brand colours — has no Admin equivalent). The Storefront token is minted automatically from your Admin credentials, because a client-credentials app has no token page in the Shopify admin to copy one from
  • Cost tracking — Every response includes Shopify API cost metadata
  • Rate limiting — Respects Shopify's cost-based throttling
  • Query caching — Configurable TTL per query type
  • 82% less context bloat — Advertise-and-Activate mode: 1 meta-tool instead of 62 schemas, domains loaded on demand
  • Config-driven — YAML config, env vars, CLI overrides
  • Type-safe — Full TypeScript with Zod validation

Why cob-shopify-mcp

What you get
Dual-modeSame 64 tools work as both CLI commands and MCP server — no competitor offers both
ShopifyQL Analytics16 analytics tools powered by ShopifyQL — sales summaries, cohort analysis, vendor performance, period-over-period comparison — each in a single API call
82% less AI contextAdvertise-and-Activate loads 1 meta-tool instead of 62 schemas. Domains activate on demand
Production-gradeCost-based rate limiting, query caching, retry with backoff, encrypted token storage, 600 tests

MCP vs CLI — When to Use What

This project gives you two ways to interact with Shopify. Same tools, same engine, same auth — different interfaces.

CLIMCP
What it isDirect terminal commandsProtocol for AI agents
Who it's forDevelopers, scripts, CI/CDClaude, Cursor, Windsurf, custom agents
How to usecob-shopify products list --limit 5AI calls tools via MCP protocol
Install vianpm install -g cob-shopify-mcpSame npm install, then claude mcp add
DockerNot applicableYes — HTTP transport for remote/multi-agent
Custom YAML toolsAuto-discoveredAuto-discovered
Storefront APISame: api: storefront on a custom tool, token minted automaticallySame
OutputTable (TTY), JSON when piped; --json, --fields, --jqJSON via MCP response
Schema introspection--schema flag on any commandBuilt into MCP protocol
Context windowZero impact — no tool schemas loadedAll schemas injected — use Advertise-and-Activate for 82% reduction
Best forQuick lookups, scripting, pipelines, CI/CDConversational AI, multi-step workflows

You don't have to choose — install once, use both:

bash
# CLI — run directly from terminalcob-shopify products list --limit 5cob-shopify products list --limit 5 --fields id,title,statuscob-shopify orders get --id gid://shopify/Order/123 --json
# MCP — connect to Claude and let AI use the same toolsclaude mcp add cob-shopify-mcp -- cob-shopify-mcp start

Advertise-and-Activate

Every MCP server on GitHub dumps all tool schemas into the AI's context on connect. With 62 tools, that's ~19,000 tokens consumed before the user even asks a question. Most conversations use 1-2 tools — 95% of those tokens are wasted.

Advertise-and-Activate fixes this. Instead of loading all 62 tool schemas, the server registers a single activate_tools meta-tool with a lightweight domain summary:

Before (default):   62 tool schemas → ~19,000 tokens per promptAfter (activate):   1 meta-tool     → ~300 tokens per promptOn-demand:          AI activates 1 domain → +2,000-3,000 tokens only when needed

How it works:

  1. Connect — AI sees 1 tool: activate_tools with a description listing all domains and their tool counts
  2. Activate — AI calls activate_tools("analytics") — server dynamically registers 16 analytics tools
  3. Execute — AI calls top_products as normal

Typical conversation: ~2,800 tokens instead of ~19,000. That's an 82% reduction.

No competitor Shopify MCP server has this. It requires clean domain grouping, a dynamic registry, and a meta-tool pattern — all built into this server's architecture.

Enable it:

yaml
# cob-shopify-mcp.config.yamltools:  advertise_and_activate: true

Or via environment variable:

bash
COB_SHOPIFY_ADVERTISE_AND_ACTIVATE=true

Custom YAML tools are included automatically — they declare a domain and appear in the corresponding summary.

CLI as Agent Tool (Zero-Config AI Access)

AI agents like Claude Code and Cursor have built-in terminal access. That means they can run CLI commands directly — no MCP server needed, no config required:

bash
# AI agent runs this via its Bash tool — zero setupcob-shopify products list --limit 5 --jsoncob-shopify orders get-by-name --name "#1001" --jsoncob-shopify analytics sales-summary --start_date 2026-01-01 --end_date 2026-03-15 --json

Every command outputs clean JSON when piped or when --json is passed. The AI reads the output and uses the data. The --schema flag lets the AI discover what inputs any command accepts:

bash
cob-shopify products list --schema   # AI reads the schema, knows what flags to pass

No MCP connection, no server process, no protocol overhead. Just npm install -g cob-shopify-mcp and the AI can use every tool immediately.

CLI via Agent's TerminalMCP Protocol
Setupnpm install -g onlyInstall + claude mcp add config
Tool discovery--schema flag per commandAutomatic schema injection
Context costZero tokens~16K tokens (or ~800 with Advertise-and-Activate)
Best forQuick access, zero-config, CI/CDRich tool discovery, multi-agent, streaming

You don't have to choose — install once, use both. Same tools, same engine, same Shopify API.

Use Cases

mermaid
flowchart LR    subgraph AGENTS["Your AI Layer"]        direction TB        SALES["Sales Assistant"]        SUPPORT["Customer Support Bot"]        WAREHOUSE["Warehouse Manager"]        SHIPPING["Shipping Tracker"]        BI["Business Intelligence"]        AUTO["Automation Workflows"]    end
    MCP["cob-shopify-mcp\n62 tools · 4 resources · 4 prompts\nAdvertise-and-Activate: 82% less context"]
    SHOPIFY["Shopify Store"]
    AGENTS --> MCP --> SHOPIFY
RoleWhat it doesTools used
Sales AssistantAnswer product questions, check inventory, create draft orders, look up customer history and lifetime valuesearch_products, get_product, list_inventory_levels, create_draft_order, get_customer_lifetime_value
Customer Support BotLook up orders by name/number, track fulfillment, view timeline, pull customer detailsget_order_by_name, get_order_fulfillment_status, get_order_timeline, get_customer, get_customer_orders
Warehouse ManagerMonitor stock levels, get low-stock alerts, adjust inventory, check location inventorylow_stock_report, list_inventory_levels, adjust_inventory, set_inventory_level, get_location_inventory
Shipping ExecutiveTrack fulfillment status, view order details, update order notes/tagsget_order_fulfillment_status, list_orders, add_order_note, update_order_tags
Business IntelligenceSales summaries, top products, refund rates, repeat customer analysis, inventory risksales_summary, top_products, refund_rate_summary, repeat_customer_rate, inventory_risk_report
Automation PipelineBulk product updates, tag management, order processing, customer segmentationupdate_product, manage_product_tags, add_order_tag, add_customer_tag, create_product

Integration Patterns

1. Direct MCP (simplest) — Claude, Cursor, or any MCP client connects directly:

AI Agent → MCP Protocol → cob-shopify-mcp → Shopify API

2. Agent Orchestration Layer — Your custom agent framework uses MCP as the Shopify bridge:

User → Your App → Agent Layer (LangChain, CrewAI, etc.) → MCP Client → cob-shopify-mcp → Shopify API

3. RAG + MCP — Combine retrieval-augmented generation with live Shopify data:

User → Your App → RAG (product docs, policies, FAQs) + MCP (live store data) → Response

4. Multi-Agent System — Multiple specialized agents share one MCP server:

Sales Agent    ─┐Support Agent  ─┤→ cob-shopify-mcp (HTTP transport) → Shopify APIWarehouse Agent─┘

Quick Start

Binary names: cob-shopify for CLI use, cob-shopify-mcp for MCP server setup. Same binary, two names.

First: Complete Getting Shopify Credentials below to get your Client ID, Client Secret, and store domain. Then come back here.

Pick one of the three paths below. All get you to the same result — a working MCP server connected to Claude.


Path A: npm install (simplest — no clone, no build)

Install globally and connect in two commands. No .env file needed — credentials go straight into the Claude config.

bash
npm install -g cob-shopify-mcp

Connect to Claude CLI:

bash
claude mcp add cob-shopify-mcp \  -e SHOPIFY_CLIENT_ID=your_client_id \  -e SHOPIFY_CLIENT_SECRET=shpss_your_secret \  -e SHOPIFY_STORE_DOMAIN=your-store.myshopify.com \  -- cob-shopify-mcp start

Done. Claude launches the server automatically when needed. Verify:

bash
claude mcp list# cob-shopify-mcp: ... - ✓ Connected

Or with npx (no install at all):

bash
claude mcp add cob-shopify-mcp \  -e SHOPIFY_CLIENT_ID=your_client_id \  -e SHOPIFY_CLIENT_SECRET=shpss_your_secret \  -e SHOPIFY_STORE_DOMAIN=your-store.myshopify.com \  -- npx cob-shopify-mcp start

Or connect to Claude Desktop — add to claude_desktop_config.json (file location):

json
{  "mcpServers": {    "cob-shopify-mcp": {      "command": "cob-shopify-mcp",      "args": ["start"],      "env": {        "SHOPIFY_CLIENT_ID": "your_client_id",        "SHOPIFY_CLIENT_SECRET": "shpss_your_secret",        "SHOPIFY_STORE_DOMAIN": "your-store.myshopify.com"      }    }  }}

Restart Claude Desktop after saving. You'll see the tools icon showing 62 available tools.


Path B: Clone and build (for development / contributing)

Clone the repo and build from source. Claude launches the server via stdio — you don't run it yourself.

B1. Clone and build:

bash
git clone https://github.com/svinpeace/cob-shopify-mcp.gitcd cob-shopify-mcppnpm installpnpm build

B2. Connect to Claude CLI:

bash
claude mcp add cob-shopify-mcp \  -e SHOPIFY_CLIENT_ID=your_client_id \  -e SHOPIFY_CLIENT_SECRET=shpss_your_secret \  -e SHOPIFY_STORE_DOMAIN=your-store.myshopify.com \  -- node /absolute/path/to/cob-shopify-mcp/dist/cli/index.js start

Done. Verify:

bash
claude mcp list# cob-shopify-mcp: ... - ✓ Connected

Or connect to Claude Desktop — add to claude_desktop_config.json (file location):

json
{  "mcpServers": {    "cob-shopify-mcp": {      "command": "node",      "args": ["/absolute/path/to/cob-shopify-mcp/dist/cli/index.js", "start"],      "env": {        "SHOPIFY_CLIENT_ID": "your_client_id",        "SHOPIFY_CLIENT_SECRET": "shpss_your_secret",        "SHOPIFY_STORE_DOMAIN": "your-store.myshopify.com"      }    }  }}

Path C: Docker (long-running HTTP server)

Run the server as a container via HTTP transport. Good for always-on setups, VPS deployments, or shared team access.

C1. Clone and configure:

bash
git clone https://github.com/svinpeace/cob-shopify-mcp.gitcd cob-shopify-mcpcp .env.example .env

Edit .env with your credentials:

env
SHOPIFY_CLIENT_ID=your_client_idSHOPIFY_CLIENT_SECRET=shpss_your_secretSHOPIFY_STORE_DOMAIN=your-store.myshopify.com

C2. Build and start the container:

bash
docker compose up --build# Server starts at http://127.0.0.1:3000

Verify it's running:

bash
curl http://127.0.0.1:3000/health# {"status":"ok"}

C3. Connect to Claude CLI:

bash
claude mcp add --transport http shopify http://127.0.0.1:3000
# Verifyclaude mcp list# cob-shopify-mcp: http://127.0.0.1:3000 (HTTP) - ✓ Connected

Or connect to Claude Desktop — add to claude_desktop_config.json (file location):

json
{  "mcpServers": {    "cob-shopify-mcp": {      "url": "http://127.0.0.1:3000"    }  }}

Windows note: Use 127.0.0.1 not localhost — Docker on Windows may not bind to IPv6 ::1 which localhost can resolve to.


Claude Desktop config file location:

OSPath
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json

Getting Shopify Credentials

Everything happens through the Shopify Developer Dashboard at dev.shopify.com. You need two things: a dev store (free) and an app with the right scopes.

Step 1 — Sign in to the Developer Dashboard

  1. Go to dev.shopify.com
  2. Sign in with your Shopify account (or create one — it's free, no credit card needed)
  3. You'll land on the Developer Dashboard with Apps, Dev stores, and Catalogs in the left sidebar

Step 2 — Create a development store

You need a store to test against. Dev stores are free and never expire.

  1. Click Dev stores in the left sidebar
  2. Click Create store
  3. Fill in the store name (e.g., my-dev-store) — this becomes my-dev-store.myshopify.com
  4. Complete the setup

Note your store domain — you'll need it: my-dev-store.myshopify.com

Step 3 — Create an app and configure scopes

  1. Click Apps in the left sidebar

  2. Click Create app (top-right)

  3. Enter an app name (e.g., Shopify MCP Server) and click Next

  4. You'll land on the version configuration page

  5. Scroll down to the Access section

  6. Click Select scopes — this opens a dropdown where you can either:

    • Search and check each scope individually, or
    • Paste a comma-separated list directly into the field

Full access (recommended — copy-paste this entire block):

read_products, write_products, read_orders, write_orders, read_all_orders, read_draft_orders, write_draft_orders, read_order_edits, write_order_edits, read_customers, write_customers, read_inventory, write_inventory, read_locations, read_fulfillments, write_fulfillments, read_assigned_fulfillment_orders, write_assigned_fulfillment_orders, read_merchant_managed_fulfillment_orders, write_merchant_managed_fulfillment_orders, read_third_party_fulfillment_orders, write_third_party_fulfillment_orders, read_shipping, read_reports, read_legal_policies

Read-only? Use only the read scopes and set COB_SHOPIFY_READ_ONLY=true in .env:

read_products, read_orders, read_all_orders, read_draft_orders, read_customers, read_inventory, read_locations, read_fulfillments, read_assigned_fulfillment_orders, read_merchant_managed_fulfillment_orders, read_third_party_fulfillment_orders, read_shipping, read_reports, read_legal_policies

What each scope enables:

ScopeWhat it covers
Products
read_productsList, search, get products, variants, collections, tags
write_productsCreate/update/delete products, variants, tags, status, collections
Orders
read_ordersList, search, get orders (last 60 days), timeline, analytics
read_all_ordersRead orders older than 60 days (historical data — requires approval)
write_ordersUpdate order notes/tags, mark paid, cancel orders
read_draft_ordersList, get draft orders
write_draft_ordersCreate draft orders, complete draft orders to real orders
read_order_editsView order modification history
write_order_editsEdit existing orders (add/remove items, adjust prices)
Customers
read_customersList, search, get customers, lifetime value, order history
write_customersCreate/update customers, manage tags
Inventory
read_inventoryInventory levels, items, SKU lookup, low stock reports
write_inventoryAdjust quantities, set inventory levels
read_locationsStore locations (required by inventory tools)
Fulfillment
read_fulfillmentsRead fulfillment data and services
write_fulfillmentsCreate/modify fulfillment services
read_assigned_fulfillment_ordersRead fulfillment orders assigned to your app
write_assigned_fulfillment_ordersCreate fulfillments, update tracking for assigned orders
read_merchant_managed_fulfillment_ordersRead merchant-managed fulfillment orders
write_merchant_managed_fulfillment_ordersFulfill and track merchant-managed orders
read_third_party_fulfillment_ordersRead 3PL fulfillment orders
write_third_party_fulfillment_ordersFulfill and track 3PL orders
Other
read_shippingShipping zones, rates, and delivery carrier services
read_reportsStore reports and analytics data
read_legal_policiesStore policies (used by shop-policies MCP resource)

For even more scopes (themes, discounts, metafields, gift cards, marketing, returns, etc.) for custom YAML tools, see the Custom Tools Guide.

  1. Click Release (top-right) to create the app version with these scopes

Step 4 — Get your Client ID and Client Secret

  1. Click Settings in the left sidebar
  2. Under Credentials, copy the Client ID (a 32-character hex string)
  3. Click the reveal icon next to Secret and copy it (starts with shpss_)

Step 5 — Install the app on your dev store

  1. Click Overview in the left sidebar (or your app name at the top)
  2. Under Installs, click Install app
  3. Select your development store and approve the permissions

Step 6 — Configure .env

bash
cp .env.example .env

Fill in your credentials:

env
SHOPIFY_CLIENT_ID=your_client_id_hereSHOPIFY_CLIENT_SECRET=shpss_your_secret_hereSHOPIFY_STORE_DOMAIN=my-dev-store.myshopify.comSHOPIFY_API_VERSION=2026-01

The server uses client credentials auth — it automatically exchanges your Client ID + Secret for a 24-hour access token, and refreshes it before it expires. No manual token management needed.

Alternative: Static access token. If you already have a shpat_ token (from Shopify CLI, a custom app, or another source), you can use that instead:

env
SHOPIFY_ACCESS_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxSHOPIFY_STORE_DOMAIN=my-dev-store.myshopify.com

When SHOPIFY_ACCESS_TOKEN is set, the server uses it directly and ignores Client ID/Secret.

Done. Proceed to Quick Start to run the server.

Configuration

Config File

Create cob-shopify-mcp.config.yaml in your project root:

yaml
auth:  method: token                    # token | client-credentials | authorization-code  store_domain: ${SHOPIFY_STORE_DOMAIN}  access_token: ${SHOPIFY_ACCESS_TOKEN}
shopify:  api_version: "2026-01"  cache:    read_ttl: 30                   # seconds    search_ttl: 10    analytics_ttl: 300
tools:  read_only: false                 # disable all mutations  disable: []                      # tool names to disable  enable: []                       # tool names to force-enable (even tier 2)  advertise_and_activate: false    # lazy tool loading — 82% less context tokens
transport:  type: stdio                      # stdio | http  port: 3000  host: "0.0.0.0"
storage:  backend: json                    # json | sqlite  path: "~/.cob-shopify-mcp/"
observability:  log_level: info                  # debug | info | warn | error  audit_log: true
rate_limit:  respect_shopify_cost: true  max_concurrent: 10

Environment Variables

VariableMaps To
SHOPIFY_ACCESS_TOKENauth.access_token
SHOPIFY_STORE_DOMAINauth.store_domain
SHOPIFY_CLIENT_IDauth.client_id
SHOPIFY_CLIENT_SECRETauth.client_secret
SHOPIFY_AUTH_METHODauth.method (token, client-credentials, authorization-code)
SHOPIFY_API_VERSIONshopify.api_version
COB_SHOPIFY_READ_ONLYtools.read_only
COB_SHOPIFY_ADVERTISE_AND_ACTIVATEtools.advertise_and_activate
COB_SHOPIFY_LOG_LEVELobservability.log_level

Config Precedence

defaults < config file < environment variables < CLI flags

auth.method is inferred as client-credentials when client_id and client_secret are set and no access_token is — but only when no layer declared a method. The authorization-code flow needs those same credentials, so set SHOPIFY_AUTH_METHOD=authorization-code (or auth.method in the config file) to use it; an explicit value is never overridden.

CLI Commands

bash
# Natural commands — cob-shopify <domain> <action> [flags]cob-shopify products list --limit 5cob-shopify products list --limit 5 --fields id,title,statuscob-shopify products get --id gid://shopify/Product/123cob-shopify products search --query "snowboard" --limit 10cob-shopify orders list --limit 10 --jsoncob-shopify orders get --id gid://shopify/Order/456 --fields id,namecob-shopify customers search --query "email:[email protected]"cob-shopify inventory low-stock-report --threshold 10cob-shopify analytics sales-summary --start_date 2025-01-01 --end_date 2025-12-31
# Global flags (available on every command)--json              # Force JSON output (auto when piped)--fields <f1,f2>    # Select specific response fields--jq <expr>         # Filter JSON with jq expression--schema            # Show command schema, don't execute--dry-run           # Preview mutations without executing--yes               # Skip confirmation prompts
# Schema introspection (for AI agents)cob-shopify products list --schema
# Mutation safetycob-shopify products create --title "New Widget" --dry-runcob-shopify products delete --id gid://shopify/Product/123  # prompts for confirmation
# Server commandscob-shopify-mcp start              # Start the MCP servercob-shopify-mcp start --transport http --port 8080cob-shopify connect --store my-store.myshopify.comcob-shopify connect                # --store is optional; falls back to the configured storecob-shopify config show
# Legacy commands (deprecated, will be removed in v1.0)cob-shopify tools listcob-shopify tools info list_products

Tools Reference

Products (15 tools)

ToolDescriptionScope
list_productsList products with filtersread_products
get_productGet product by IDread_products
get_product_by_handleGet product by URL handleread_products
search_productsFull-text product searchread_products
list_product_variantsList variants for a productread_products
get_product_variantGet variant by IDread_products
list_collectionsList collectionsread_products
get_collectionGet collection by IDread_products
create_productCreate a new productwrite_products
create_product_variantAdd variant to productwrite_products
create_collectionCreate a collectionwrite_products
update_productUpdate product fieldswrite_products
update_product_variantUpdate variant fieldswrite_products
update_product_statusChange product statuswrite_products
manage_product_tagsAdd/remove product tagswrite_products

Orders (15 built-in + 2 custom examples)

ToolDescriptionScope
list_ordersList orders with filtersread_orders
search_ordersSearch orders by queryread_orders
get_orderGet order by IDread_orders
get_order_by_nameGet order by name (#1001)read_orders
get_order_timelineGet order events timelineread_orders
get_order_fulfillment_statusGet fulfillment detailsread_orders
create_draft_orderCreate a draft orderwrite_draft_orders
add_order_noteAdd note to orderwrite_orders
update_order_noteUpdate order notewrite_orders
add_order_tagAdd tags to orderwrite_orders
update_order_tagsUpdate order tagswrite_orders
mark_order_paidMark order as paidwrite_orders
cancel_order (custom example)Cancel an order (async)write_orders
complete_draft_order (custom example)Complete draft to real orderwrite_draft_orders
get_fulfillment_ordersGet fulfillment order IDsread_assigned_fulfillment_orders
create_fulfillmentCreate fulfillment with trackingwrite_assigned_fulfillment_orders
update_fulfillment_trackingUpdate tracking infowrite_assigned_fulfillment_orders

Customers (9 tools)

ToolDescriptionScope
list_customersList customersread_customers
search_customersSearch customersread_customers
get_customerGet customer by IDread_customers
get_customer_ordersGet customer's ordersread_customers
get_customer_lifetime_valueGet customer LTVread_customers
create_customerCreate a customerwrite_customers
update_customerUpdate customer fieldswrite_customers
add_customer_tagAdd tags to customerwrite_customers
remove_customer_tagRemove tags from customerwrite_customers

Inventory (7 tools)

ToolDescriptionScope
get_inventory_itemGet inventory item by IDread_inventory
get_inventory_by_skuGet inventory by SKUread_inventory
list_inventory_levelsList inventory levelsread_inventory, read_locations
get_location_inventoryGet inventory at locationread_inventory, read_locations
low_stock_reportLow stock items reportread_inventory, read_locations
adjust_inventoryAdjust inventory quantitywrite_inventory
set_inventory_levelSet inventory levelwrite_inventory

Analytics (16 tools)

All analytics tools use ShopifyQL — single API call per query, no cursor pagination.

ToolDescriptionScope
sales_summarySales totals for date rangeread_reports
top_productsBest sellers by revenue or ordersread_reports
orders_by_date_rangeOrders grouped by day/week/monthread_reports
refund_rate_summaryRefund rate and amountsread_reports
repeat_customer_rateRepeat purchase analysisread_reports
sales_by_channelRevenue by sales channelread_reports
sales_by_geographySales by country/regionread_reports
sales_comparisonPeriod-over-period comparisonread_reports
discount_performanceDiscount impact analysisread_reports
product_vendor_performanceRevenue by vendorread_reports
customer_cohort_analysisCohort analysis by periodread_reports
customer_lifetime_valueTop customers by CLVread_reports
conversion_funnelSessions to orders funnelread_reports
traffic_analyticsSession traffic over timeread_reports
inventory_risk_reportOver/understock risk analysisread_inventory, read_products
shopifyql_queryRaw ShopifyQL passthrough — Tier 2, disabled by defaultread_reports

Other Editors (Cursor / Windsurf)

Add to .cursor/mcp.json or equivalent:

json
{  "mcpServers": {    "cob-shopify-mcp": {      "command": "npx",      "args": ["-y", "cob-shopify-mcp", "start"],      "env": {        "SHOPIFY_CLIENT_ID": "your_client_id",        "SHOPIFY_CLIENT_SECRET": "shpss_your_secret",        "SHOPIFY_STORE_DOMAIN": "your-store.myshopify.com"      }    }  }}

Development

bash
pnpm installpnpm test           # Unit tests only — no network, no .env neededpnpm test:integration  # Everything, incl. live tests against a real store (loads .env)pnpm lint           # Biome linterpnpm typecheck      # TypeScript type checkingpnpm build          # Build with tsup

Running the live tests

Live tests are gated on credentials and skip cleanly without them. Put either auth method in .env (gitignored) — client credentials are enough, no separate access token required:

env
SHOPIFY_STORE_DOMAIN=your-dev-store.myshopify.comSHOPIFY_CLIENT_ID=xxxxxxxxxxxxSHOPIFY_CLIENT_SECRET=xxxxxxxxxxxx# ...or a static token instead, which takes precedence if both are present:# SHOPIFY_ACCESS_TOKEN=shpat_xxxxxxxxxxxx

The app needs all 13 scopes the tools use — read_reports in particular, or every ShopifyQL analytics tool fails:

read_products, write_products, read_orders, write_orders, write_draft_orders,read_customers, write_customers, read_inventory, write_inventory, read_locations,read_assigned_fulfillment_orders, write_assigned_fulfillment_orders, read_reports

A fresh dev store has no data, so analytics assertions will be vacuous — node scripts/create-test-orders.js seeds it first.

pnpm test deliberately does not load .env: the unit suite stays hermetic. That means live tests always skip there, by design. Use pnpm test:integration to actually exercise a store.

Architecture

[Interactive Architecture Diagram]

Animated, interactive diagram showing how Entry Points, Core Engine, Shopify Shell, and the GraphQL API connect

mermaid
flowchart TB    subgraph ENTRY["Entry Points"]        direction LR        CLI["CLI\nproducts · orders · customers\ninventory · analytics"]        STDIO["MCP Server\nstdio transport"]        HTTP["HTTP Server\nStreamable HTTP"]    end
    subgraph CORE["Core Engine (API-Agnostic)"]        direction TB
        subgraph REGISTRY["Registry & Discovery"]            direction LR            AD["Auto-Discover\n*.tool.ts"]            REG["Tool Registry\nregister · list · filter"]            CF["Config Filter\nenable · disable · tiers"]        end
        subgraph ENGINES["MCP Engines"]            direction LR            TE["Tool Engine\nschema gen · execute"]            RE["Resource Engine\nread-only data"]            PE["Prompt Engine\ntemplates · workflows"]        end
        subgraph INFRA["Infrastructure"]            direction LR            AUTH["Auth Manager\nstatic · client-creds · OAuth"]            OBS["Observability\nlogs · metrics · audit"]            STORE["Storage\nJSON · SQLite+encryption"]        end
        DT["defineTool() Helper"]    end
    subgraph SHOPIFY["Shopify Shell"]        direction TB
        subgraph CLIENT["Shopify GraphQL Client"]            direction LR            GQL["GraphQL Client\n@shopify/admin-api-client"]            RL["Rate Limiter"]            CACHE["Cache Layer"]        end
        subgraph TOOLS["62 Tool Definitions"]            direction LR            PROD["Products\n15 tools"]            ORD["Orders\n12 tools"]            CUST["Customers\n9 tools"]            INV["Inventory\n7 tools"]            ANAL["Analytics\n16 tools"]        end
        subgraph MCPPRIM["MCP Primitives"]            direction LR            RES["Resources\nshop info · locations"]            PROMPT["Prompts\nstore health · reports"]        end    end
    SHOPIFY_API["Shopify Admin GraphQL API"]
    CLI --> CORE    STDIO --> CORE    HTTP --> CORE
    AD --> REG    REG --> CF    CF --> TE    CF --> RE    CF --> PE
    DT -.-> REG
    TE --> CLIENT    RE --> CLIENT    PE --> CLIENT
    AUTH --> CLIENT    OBS -.-> TE    STORE -.-> AUTH
    GQL --> RL    RL --> CACHE
    TOOLS --> DT    MCPPRIM --> RE    MCPPRIM --> PE
    CACHE --> SHOPIFY_API

Project Structure

src/├── core/               # API-agnostic MCP server core│   ├── config/         # Zod config schema, multi-source loader│   ├── auth/           # Static token, client credentials, OAuth│   ├── engine/         # Tool, Resource, Prompt execution engines│   ├── registry/       # Tool registry with config filtering│   ├── storage/        # JSON + SQLite backends with encryption│   ├── transport/      # stdio + HTTP transports│   ├── observability/  # pino logger, cost tracker, audit log│   └── helpers/        # defineTool, defineResource, definePrompt├── shopify/            # Shopify-specific implementation│   ├── client/         # GraphQL client, rate limiter, cache, retry│   ├── tools/          # 62 tools across 5 domains│   ├── resources/      # 4 MCP resources│   └── prompts/        # 4 MCP prompts├── server/             # Server bootstrap and registration bridges└── cli/                # CLI commands (Commander + consola)

How It Compares

61 tools ship enabled out of the box (all Tier 1; the 62nd, shopifyql_query, is Tier 2 and opt-in) — but the tool count is unlimited. Developers can add any Shopify GraphQL operation as a custom tool using simple YAML files, no TypeScript required:

yaml
# my-tools/get-metafields.yamlname: get_shop_metafieldsdomain: shopdescription: Get shop metafields by namespacescopes: [read_metafields]input:  namespace:    type: string    description: Metafield namespace    required: truegraphql: |  query($namespace: String!) {    shop {      metafields(first: 10, namespace: $namespace) {        edges { node { key value } }      }    }  }response:  mapping: shop.metafields.edges

Point your config at the directory and they're live:

yaml
tools:  custom_paths: ["./my-tools/"]

The 3-tier system gives full control: Tier 1 (enabled by default), Tier 2 (disabled by default, opt-in via config), Tier 3 (custom YAML tools, enabled by default). Plus tools.enable / tools.disable for granular overrides.

See the Custom Tools Guide for the full reference — YAML structure, variable naming rules, response mapping, scopes reference, error handling, and step-by-step examples.

The package ships with 5 ready-to-use custom tools in custom-tools/ — draft order completion, fulfillment orders, create fulfillment with tracking, update tracking, and order cancellation. They're enabled by default in .env.example (COB_SHOPIFY_CUSTOM_TOOLS=./custom-tools). To disable them, remove or comment out that line.

Managing Tools

bash
# Via environment variablesCOB_SHOPIFY_CUSTOM_TOOLS=./custom-tools    # Load custom YAML tools from directoryCOB_SHOPIFY_DISABLE=cancel_order,tool2     # Disable specific toolsCOB_SHOPIFY_ENABLE=some_tier2_tool         # Enable specific Tier 2 toolsCOB_SHOPIFY_READ_ONLY=true                 # Disable ALL write operations

Custom YAML Tools

Any Shopify GraphQL query or mutation can become a tool without writing TypeScript: drop a .yaml file in a directory and point custom_paths (or COB_SHOPIFY_CUSTOM_TOOLS) at it. Admin is the default; since 0.10.0 a tool can declare api: storefront and reach the Storefront API instead — see Talking to the Storefront API.

Input fields declare a type, and the vocabulary is:

type:Notes
string
numbermin / max bound the value
boolean
enumrequires enum: — the list of valid values
arrayrequires items:; min / max bound the element count
objectrequires properties:

array and object arrived in 0.8.0. They are what let a tool take a list — choosing which lines go in a fulfillment, for instance:

yaml
input:  line_items:    type: array    required: false    min: 1                   # an empty list is refused, not read as "all of them"    items:      type: object      properties:        id:          type: string          required: true        quantity:          type: number          required: true

Two things are worth knowing before you reach for them:

  • An omitted optional list is not an empty one. GraphQL drops an argument whose variable was never provided, so leaving a list out means "the API decides" while [] means "none". For fulfillmentCreate those two readings differ by the whole order — omitted fulfils everything remaining. Use min: 1 when an empty list must be refused rather than interpreted.
  • Undeclared properties are stripped, silently. A key you do not list under properties: never reaches Shopify. If a variable appears to be ignored, check that every field of it is declared.
Talking to the Storefront API

Shopify has two GraphQL APIs, and a few things live on only one of them. Shop.brand — the merchant's uploaded logo, square logo, cover image and brand colours — is Storefront-only and has no Admin equivalent, so before 0.10.0 no tool in this package could reach it: the query loaded, the server booted, the connection reported healthy, and the call failed with Field 'brand' doesn't exist on type 'Shop'.

Declare the API on the tool. admin is the default and what every tool written before 0.10.0 is:

yaml
name: get_shop_branddomain: shopdescription: The merchant's logo and brand coloursapi: storefrontinput: {}graphql: |  query {    shop {      brand {        logo { image { url } }        squareLogo { image { url } }      }    }  }

The token is minted for you. An app installed with client credentials has no Storefront token page anywhere in the Shopify admin — that panel belongs to admin-created custom apps — so there is usually nothing to paste even if you want to. storefrontAccessTokenCreate is an Admin mutation, so this package creates the token from the credentials it already has, reusing an existing one where the store has it. Nothing is requested until a api: storefront tool actually runs.

To supply your own instead, set auth.storefront_access_token or SHOPIFY_STOREFRONT_ACCESS_TOKEN.

What a Storefront token may read comes from the app's unauthenticated_* scopes, which are separate from its Admin ones. An app with fifty Admin scopes and none of these mints a token successfully and then reads nothing. Shop-level content generally wants unauthenticated_read_content. Add it to the app's release and re-install the app — a client-credentials app picks up new scopes only on re-authorisation.

A broken tool fails to load, rather than running wrongly

0.9.0 turned two mistakes from silent runtime behaviour into a refusal at load time. Both used to produce a tool that registered, reported healthy, and did the wrong thing when called.

A type: the loader does not implement is refused. It used to fall through to string, so type: integer quietly became a string field — 5 was rejected and "5" was sent to Shopify as text. The error names the field, including nested ones:

YAML tool "my_tool" at "./my-tools/thing.yaml": input "lines.items.quantity" has unknowntype "integer". Valid types: string, number, boolean, enum, array, object

input: and your GraphQL variables must be the same set, in both directions. A YAML tool has no handler — the engine runs your document with the validated input as its variables and nothing else — so any difference between the two is a bug you cannot see:

  • a variable no input: declares can never be supplied, and GraphQL reads an absent optional variable as "not specified";
  • an input: no variable uses is validated and then dropped, so the tool advertises a parameter it ignores.

One typo causes both. The complete_draft_order tool shipped with payment_pending in its input and $paymentPending in its mutation, so asking for a pending payment completed the draft order as paid — with no error anywhere. It is fixed in 0.9.0, and the loader now refuses that shape.

A $ inside a string literal, a # comment or a """ block is not read as a variable, so query: "price:>$100" is fine.

Full guide, including the scopes reference → Custom Tools Guide

Featurecob-shopify-mcp (11⭐)GeLi2001 (147⭐)pashpashpash (35⭐)antoineschaller (10⭐)benwmerritt
Tools64 (62 built-in + 2 custom)14152230+
MCP Resources40000
MCP Prompts40000
Auth methods3 (static, client-creds, OAuth)2112
HTTP TransportStreamable HTTPNoNoNoNo
Encrypted StorageJSON + SQLiteNoNoNoNo
Unit Tests673~2minimal1~2
DockerMulti-stageNoNoNoNo
Rate LimiterYesNoNoNoNo
Query CacheYesNoNoNoNo
Observabilitypino + audit + costNoNoNoNo
Context Reduction82% (Advertise-and-Activate)NoNoNoNo
Config-drivenTier system + YAMLNoNoNoNo

Ecosystem

This server manages your store via the Admin GraphQL API. Pair it with Shopify's official MCP servers for the complete experience:

ServerPurposeComplements cob-shopify-mcp
@shopify/dev-mcpSearch Shopify docs, introspect Admin GraphQL schemaLearn the API while this server manages your store
Storefront MCPProduct browsing, cart, checkout (built into every store)Customer-facing shopping vs admin-side management

Changelog

See the full changelog here → CHANGELOG.md

About

Built by Call O Buzz Services — AI-driven software development, SaaS solutions, and open source tools.

License

MIT

Source: README.md at commit d53db36

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v0.12.1LatestNov 12, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts