npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shopify-claude-mcp

v0.1.0

Published

MCP server for the Shopify Admin API — read and write your store's products, collections, orders, and online-store content (pages, blogs, articles) with SEO, from Claude.

Readme

shopify-mcp

An MCP server for the Shopify Admin API. It lets Claude read and write your store's products, collections, orders, and online-store content (pages, blogs, articles) — including SEO — directly.

Two ways to authenticate — pick one:

  • Access token (easiest). Create a Shopify custom app (Settings → Apps and sales channels → Develop apps), install it, and copy its Admin API access token (shpat_…). Pass it as --accessToken. No OAuth, nothing to refresh.
  • Client credentials. A Dev Dashboard app's client_id + client_secret are exchanged for a short-lived Admin API token that the server caches and refreshes automatically. Pass --clientId + --clientSecret.

Either way there is no browser step.

Tools

| Tool | What it does | | --- | --- | | get_products | List products as a markdown table with optional search query, sort key, and cursor pagination. | | get_product | Fetch full detail for one product (variants, options, image, SEO) by id. | | create_product | Create a product (DRAFT by default), optionally setting price/SKU on the default variant and SEO title/description. | | update_product | Update an existing product's title, description, vendor, type, tags, status, or SEO title/description. | | delete_product | Permanently delete a product. | | manage_variants | Create and/or update variants (price, compare-at, SKU, barcode, option values). | | delete_variants | Delete one or more variants from a product. | | manage_options | Create / update / delete product options (e.g. Size, Color) and their values. | | get_collections | List collections as a table (smart vs manual, product counts) with search/sort/pagination. | | get_collection | Fetch one collection by id, including its rules (if smart), SEO title/description, and member products. | | create_collection | Create a manual collection, or a smart one by passing rules; optionally set SEO title/description. | | update_collection | Update a collection's title, description, handle, SEO title/description, or smart rules. | | delete_collection | Delete a collection (products are not deleted). | | manage_collection_products | Add/remove products in a manual collection. | | get_orders | List orders as a markdown table (customer, total, payment & fulfillment status) with search/sort/pagination. | | get_order | Fetch one order by id: line items, customer, shipping address, status, and totals. | | update_order | Update an order's email, note, tags, or custom attributes. | | cancel_order | Cancel an order, optionally refunding and/or restocking (destructive, cannot be undone). | | manage_order_status | Close (archive) or reopen an order. | | get_pages | List online-store pages as a markdown table (title, published status, handle) with search/sort/pagination. | | get_page | Fetch one page by id, including its body (HTML) and SEO title/description. | | create_page | Create an online-store page, optionally setting SEO title/description. | | update_page | Update a page's title, body, handle, visibility, or SEO title/description. | | delete_page | Permanently delete a page. | | get_blogs | List blogs as a markdown table (title, article count, handle) with search/sort/pagination. | | get_blog | Fetch one blog by id, including comment policy and SEO title/description. | | create_blog | Create a blog (article container), optionally setting comment policy and SEO. | | update_blog | Update a blog's title, handle, comment policy, or SEO title/description. | | delete_blog | Permanently delete a blog and all its articles. | | get_articles | List blog articles as a markdown table (title, status, blog, author) with blog filter/search/sort/pagination. | | get_article | Fetch one article by id, including body (HTML), author, tags, and SEO title/description. | | create_article | Create an article in a blog (requires blogId + author), optionally setting body, summary, tags, image, and SEO. | | update_article | Update an article's title, author, body, summary, tags, visibility, blog, or SEO title/description. | | delete_article | Permanently delete an article. | | manage_tags | Add or remove tags on any taggable resource (product, order, customer, …) by GID. |

Tools are annotated with readOnly / destructive hints, and the server ships instructions telling the model to render products as a table, confirm before writes, ask for missing fields, and treat deletes as destructive.

Status — orders: The order tools (get_orders, get_order, update_order, cancel_order, manage_order_status) compile but have not yet been tested against a live store. They are not needed right now; testing is required before relying on them — verify the GraphQL (notably orderCancel and the shipping-address shape) and the destructive-confirmation flow for cancel_order. The product and collection tools are unaffected.

Prerequisites

  1. A Shopify app installed on your store — either a custom app (which issues an Admin API access token) or a Dev Dashboard app (which issues a Client ID + Client Secret).
  2. The app must be granted these access scopes:
    • read_products
    • write_products
    • read_orders
    • write_orders
    • read_content
    • write_content (pages, blogs, articles; SEO title/description are written as global.* metafields)
  3. Node.js 18+ (developed on Node 22).

Install & build

npm install
npm run build

Configure in Claude

Each user supplies their own store domain and credentials. CLI flags take precedence; environment variables (SHOPIFY_ACCESS_TOKEN, or SHOPIFY_CLIENT_ID + SHOPIFY_CLIENT_SECRET, plus SHOPIFY_DOMAIN and SHOPIFY_API_VERSION) are a fallback.

The examples below use client credentials; to use a custom-app token instead, replace the --clientId / --clientSecret pair with a single --accessToken "<shpat_…>".

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) and add:

{
  "mcpServers": {
    "shopify": {
      "command": "node",
      "args": [
        "/ABSOLUTE/PATH/TO/shopify-mcp/dist/index.js",
        "--clientId", "<YOUR_CLIENT_ID>",
        "--clientSecret", "<YOUR_CLIENT_SECRET>",
        "--domain", "<YOUR_SHOP>.myshopify.com"
      ]
    }
  }
}

This package is published to npm as shopify-claude-mcp, so the same config works with npx and no local build:

{
  "mcpServers": {
    "shopify": {
      "command": "npx",
      "args": [
        "shopify-claude-mcp",
        "--clientId", "<YOUR_CLIENT_ID>",
        "--clientSecret", "<YOUR_CLIENT_SECRET>",
        "--domain", "<YOUR_SHOP>.myshopify.com"
      ]
    }
  }
}

Or install it globally (npm i -g shopify-claude-mcp) and use the shopify-claude-mcp command in place of the npx invocation.

Restart Claude Desktop after editing. The shopify tools appear in the tools menu.

Claude Code

One line, no local build (custom-app token shown; swap in --clientId/--clientSecret if you prefer client credentials):

claude mcp add shopify -- npx shopify-claude-mcp \
  --accessToken <shpat_...> --domain <YOUR_SHOP>.myshopify.com

Flags

  • --accessToken <shpat_...> — Admin API access token from a custom app. or
  • --clientId <id> --clientSecret <secret> — Dev Dashboard app client credentials.
  • --domain <shop>.myshopify.com — your store (required).
  • --apiVersion <YYYY-MM> — Admin API version. Defaults to 2026-01.

Verify it works (smoke test)

Before wiring into Claude you can confirm credentials and scopes with a one-shot test:

npm run smoke -- --clientId <ID> --clientSecret <SECRET> --domain <SHOP>.myshopify.com

It performs the token exchange and runs a real products query, printing a sample of titles.

How it's built

src/
  index.ts              # entry: load config, build server, serve over stdio
  config.ts             # CLI flags + env fallback, validation
  shopify/
    auth.ts             # client-credentials token exchange + cache/refresh
    client.ts           # Admin GraphQL client (token header, 401 retry, error surfacing)
  graphql/
    products.ts         # product queries/mutations + result types (validated vs 2026-01 schema)
    collections.ts      # collection queries/mutations + result types
    orders.ts           # order queries/mutations + result types
    content.ts          # page, blog & article queries/mutations + result types
    metafields.ts       # metafieldsSet (page/article SEO via global.* metafields; general metafields later)
    tags.ts             # cross-resource tag mutations
  tools/
    shared.ts           # cross-domain helpers (results, GID normalization, setSeoMetafields)
    index.ts            # registerAllTools() — register each domain here
    manageTags.ts       # cross-resource tool (not product-specific)
    products/           # product-domain tools, registered via registerProductTools()
      index.ts  getProducts.ts  getProduct.ts  createProduct.ts  updateProduct.ts
      deleteProduct.ts  manageVariants.ts  deleteVariants.ts  manageOptions.ts
    collections/        # collection-domain tools, registered via registerCollectionTools()
      index.ts  getCollections.ts  getCollection.ts  createCollection.ts
      updateCollection.ts  deleteCollection.ts  manageCollectionProducts.ts
    orders/             # order-domain tools, registered via registerOrderTools()
      index.ts  getOrders.ts  getOrder.ts  updateOrder.ts
      cancelOrder.ts  manageOrderStatus.ts
    content/            # content-domain tools (pages, blogs, articles), via registerContentTools()
      index.ts
      getPages.ts  getPage.ts  createPage.ts  updatePage.ts  deletePage.ts
      getBlogs.ts  getBlog.ts  createBlog.ts  updateBlog.ts  deleteBlog.ts
      getArticles.ts  getArticle.ts  createArticle.ts  updateArticle.ts  deleteArticle.ts

Adding a new domain later (orders, customers, inventory) means a tools/<domain>/ folder, a graphql/<domain>.ts, and one line in tools/index.ts.

  • Transport: stdio (the standard for local MCP servers). All logs go to stderr so they never corrupt the protocol stream on stdout.
  • API: Shopify Admin GraphQL API. Product variant SKU is set via inventoryItem.sku, and the default variant's price is applied with productVariantsBulkUpdate after productCreate.

Troubleshooting

  • "Failed to obtain an access token (HTTP 401/403)" — check the client id/secret and that the app is installed on the store named in --domain.
  • "Shopify GraphQL error: Access denied ... requires write_products" — add the missing scope to the app and reinstall.
  • Tools don't appear in Claude — confirm the path to dist/index.js is absolute and that you ran npm run build; then fully restart Claude.

Roadmap

Customers, inventory, and metafields, plus deeper order operations (fulfillment and refunds). Auth is isolated in shopify/auth.ts, so adding a full 3-legged OAuth flow for multi-merchant distribution later is contained.

License

MIT