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

@curless/shopify-storefront

v0.54.0

Published

One Shopify storefront MCP connector, driven by a config file. Identity, tool names, vocabulary and shop wiring come from a StorefrontConfig, so a second merchant is a JSON file rather than a fork of 3,400 lines.

Readme

@curless/shopify-storefront

A Shopify store as an MCP connector for AI assistants (Claude, ChatGPT and any other MCP host). A buyer browses the catalogue, picks options, builds a cart and is handed a link to the merchant's own Shopify checkout — the money and the order stay in the merchant's Shopify. Results render as an MCP Apps card.

One server, driven by a config file: the merchant's name, tool names, the words for what they sell and the shop wiring all come from config.json, so a second merchant is a second file, not a fork.

npm install -g @curless/shopify-storefront
STOREFRONT_CONFIG=./config.json \
STOREFRONT_SHOPIFY_CLIENT_ID=… STOREFRONT_SHOPIFY_CLIENT_SECRET=… \
curless-shopify-storefront

Deployed on Node 22. It listens on PORT (default 8090) and expects a TLS-terminating reverse proxy in front of it that sets X-Forwarded-For.

The tools

Named from the config's naming.prefix and nouns — with prefix acme and the default noun product:

| Tool | What it does | |---|---| | list_acme_products | The catalogue as a card; optional query, maxPrice, limit. | | get_acme_product | One product: options, prices, which combinations are in stock. | | add_to_acme_cart / view_acme_cart / clear_acme_cart | A cart kept by this server, in memory, per conversation. Nothing reaches Shopify until the buyer pays. | | get_acme_checkout_link | A Shopify cart permalink for one variant, or for the whole cart. Creates nothing. | | lookup_acme_order | One order, given its order number and the email it was placed with. | | get_acme_store_policies | The shop's published returns, shipping, privacy and terms pages. | | check_acme_checkout_status | For the card only: whether the checkout it opened has been paid. |

Configuration

config.json holds everything that identifies the merchant; the environment holds only secrets and machine settings.

{
  "id": "acme",
  "server": { "name": "acme-shop", "title": "Acme", "websiteUrl": "https://acme.example" },
  "naming": { "prefix": "acme" },
  "shopify": { "mode": "env", "shopDomain": "acme.myshopify.com" },
  "urls": { "appUrl": "https://mcp.acme.example" },
  "legal": {
    "operatorContact": "[email protected]",
    "merchantContact": "[email protected]",
    "updated": "1 October 2026"
  }
}
  • shopify.mode: "env" serves one shop, installed once through the app's OAuth flow (/auth/install); the token is stored at shopify.tokenPath (default /app/data/<id>-token.json — keep it on a volume). "oauth-install" is the multi-shop form, where the shop is whoever installed the app and the connector URL is /s/<shop>/mcp.
  • urls.appUrl is the app URL registered with Shopify; urls.publicUrl, when set, is the hostname buyers connect to.
  • legal.* fills the /privacy, /terms and /docs pages that directory reviewers read. Missing contacts do not fail the boot, but leave gaps there.

| env | | |---|---| | STOREFRONT_CONFIG | Path to config.json (required). | | STOREFRONT_SHOPIFY_CLIENT_ID / _CLIENT_SECRET | The Shopify app's credentials; the secret also signs the OAuth callback and webhooks. | | STOREFRONT_SHOPIFY_ADMIN_TOKEN | Optional: an existing Admin API token, skipping the install. | | PORT | Default 8090. | | CATALOG_REFRESH_MS | Default 300000 (5 minutes). A failed refresh keeps serving the last good catalogue. | | OPENAI_APPS_CHALLENGE_TOKENS | host=token,… — ChatGPT Apps domain verification. |

Endpoints

POST /mcp (and /) is the MCP endpoint (streamable HTTP, JSON responses). Alongside it: /healthz, /docs, /privacy, /terms, /icon.png, /logo.png, /img (the card's image proxy for Shopify's CDN), and the Shopify install routes /auth/install, /auth/callback, /webhooks/shopify.

What it guards

  • No write access to the shop is needed for selling. Checkout is a Shopify link; no card number or payment token reaches this server.
  • Order lookup needs the order number and the email together, answers a wrong email and a missing order alike, and pauses lookups after five misses in fifteen minutes for one order number, one email or one conversation (fifty for one network address, a hundred for the whole shop).
  • Limits: 60 requests a minute per address, a 1 MB request body, bounded tool arguments.
  • The merchant's own text (descriptions, policies) is stripped of control and invisible characters, length-capped and fenced before it reaches the assistant.

License

MIT