TC

tomi-claycosmos/shopify-store-assistant-mcp

Browser automation
0 stars 0 forks Quality 55 Trend 20

Demo MCP server: Shopify store assistant for ChatGPT Apps & Grok Bot — OAuth 2.1 (DCR+PKCE), safety-bounded tools, MCP Apps widget. Sample data.

Overview

Portfolio demo by Tomi (https://ziy.one/). from a fictional store ("Kopi & Co. Demo Store"). Not affiliated with Shopify. A TypeScript MCP server (official @modelcontextprotocol/sdk 1.32, Streamable HTTP) that lets a store owner query products, inventory and orders from ChatGPT, Grok Bot or Cursor, and draft discount codes. Every tool has explicit safety bounds. These were captured with headless Chromium (Playwright) against the local server. All tool output is real; all store data is sample data. Regenerate them with npx tsx scripts/screenshots.ts. covers product search with cards, order lookup with masked PII, a 15% discount draft that succeeds, an 80% discount blocked by the cap, and a rejected refund: Walkthrough video: screenshots/walkthrough.mp4 (webm) Safety bounds: - There are no refund, delete, cancel or customer-edit tools. - Discount drafts live in server memory and never change Shopify. - Every call is appended to an audit log (JSONL, no tokens, no raw PII).

README

Shopify Store Assistant — MCP server demo (ChatGPT App · Grok Bot connector · Muse-ready)

Portfolio demo by Tomi (https://ziy.one/). Default data is SAMPLE data from a fictional store (“Kopi & Co. Demo Store”). Not affiliated with Shopify.

A TypeScript MCP server (official @modelcontextprotocol/sdk 1.32, Streamable HTTP) that lets a store owner query products, inventory and orders from ChatGPT, Grok Bot or Cursor, and draft discount codes. Every tool has explicit safety bounds.

Architecture

flowchart LR
  subgraph Clients
    C1[ChatGPT Developer Mode]
    C2[Grok Bot / Cursor]
    C3[Muse connector / MCP Inspector]
  end
  C1 & C2 & C3 -- "OAuth 2.1 (DCR + PKCE S256)" --> AS[Built-in demo Authorization Server/register /authorize /token]
  C1 & C2 & C3 -- "Bearer token · Streamable HTTP POST /mcp" --> MW[Bearer middleware401 + WWW-Authenticate resource_metadata]
  MW --> MCP[McpServer per request6 tools + UI resource]
  MCP --> SAFE[Safety layerscope checks · 20% discount cap · PII masking · no refund/delete]
  SAFE --> AUD[(logs/audit.jsonl)]
  SAFE --> DATA{Store adapter}
  DATA -->|default| MOCK[Mock sample store]
  DATA -->|SHOPIFY_STORE_DOMAIN + SHOPIFY_ADMIN_TOKEN| SHOP[Shopify Admin GraphQLread-only, untested live]
  MCP --> UI[ui://shopify-assistant/product-list-v1.htmltext/html;profile=mcp-app]

Screenshots

These were captured with headless Chromium (Playwright) against the local server. All tool output is real; all store data is sample data. Regenerate them with npx tsx scripts/screenshots.ts.

OAuth consent Widget in a chat host

Demo transcript covers product search with cards, order lookup with masked PII, a 15% discount draft that succeeds, an 80% discount blocked by the cap, and a rejected refund:

Walkthrough video: screenshots/walkthrough.mp4 (webm)

Tools

Tool Purpose readOnly destructive openWorld Scope
search_products keyword/type/SKU search ✅ ❌ ❌ store.read
check_inventory stock for one SKU ✅ ❌ ❌ store.read
lookup_order order details, customer PII masked ✅ ❌ ❌ store.read
get_order_status payment/fulfillment/tracking only ✅ ❌ ❌ store.read
create_discount_draft inactive draft, capped at MAX_DISCOUNT_PERCENT (20) ❌ ❌ ❌ discounts.write
render_product_list renders the widget (decoupled render tool) ✅ ❌ ❌ —

Safety bounds:

  • There are no refund, delete, cancel or customer-edit tools.
  • Discount drafts live in server memory and never change Shopify.
  • Every call is appended to an audit log (JSONL, no tokens, no raw PII).
  • Input is validated with zod.
  • Server instructions tell the model to confirm with the user before any write.

Run

npm install
npm test             # vitest: 15 tests (tools, safety bounds, auth rejection)
npm start            # http://localhost:3000/mcp  (mock data)
npm run demo         # in another shell: full OAuth + MCP run -> DEMO_TRANSCRIPT.md

Sample credential: the consent page login defaults to demo / demo-pass. It is a demo-only placeholder and not a secret. Always set DEMO_USER and DEMO_PASSWORD via env on any public deployment. To use a real store, set SHOPIFY_STORE_DOMAIN and SHOPIFY_ADMIN_TOKEN. The token needs these custom-app scopes: read_products, read_inventory, read_orders. This adapter has not been tested against a live store.

OAuth (demo authorization server)

Endpoints:

  • /.well-known/oauth-protected-resource (RFC 9728)
  • /.well-known/oauth-authorization-server (RFC 8414; advertises S256 and registration_endpoint)
  • POST /register (RFC 7591 DCR, public clients; https or localhost redirect URIs only)
  • GET/POST /authorize (consent page + login)
  • POST /token (authorization_code with PKCE verification, refresh_token with rotation)

Behaviour:

  • Tokens are opaque, live in memory, last 1 hour and are audience-bound to /mcp.
  • A request without a valid token to /mcp gets a 401 with WWW-Authenticate: Bearer resource_metadata="…". This is how ChatGPT discovers the OAuth configuration.

Production:

  • Replace this server with a real IdP (Auth0, WorkOS, Stytch) or Shopify’s own OAuth.
  • Persist clients and tokens.
  • Add CIMD if needed (ChatGPT prefers CIMD when it is advertised).

Deploy

  • Render (free): connect this repo as a Blueprint (render.yaml). It builds the Dockerfile, and PUBLIC_BASE_URL defaults to RENDER_EXTERNAL_URL. Free instances sleep when idle, so the first request after a sleep is slow.
  • Fly.io: fly launch --copy-config --no-deploy && fly secrets set DEMO_PASSWORD=... && fly deploy. PUBLIC_BASE_URL defaults to https://$FLY_APP_NAME.fly.dev.
  • Any Docker host: set PUBLIC_BASE_URL to the public https origin.

⚠️ OAuth clients and tokens are in memory, so a restart or sleep logs every client out. That is fine for a demo; production needs a persistent store or a real IdP.

Connect in ChatGPT Developer Mode

  1. Deploy behind a public HTTPS URL. Set PUBLIC_BASE_URL=https://your-host so the OAuth metadata URLs match.
  2. In ChatGPT, enable Developer Mode (Settings → Apps/Connectors → Advanced) and create a custom app/connector with URL https://your-host/mcp and OAuth auth.
  3. ChatGPT runs DCR, then sends you to the consent page. Log in as demo/demo-pass.
  4. Try: “Which brewing products are low on stock? Show them as cards”, “What’s the status of order #1001?”, “Create a 15% discount draft KOPI15”.

Docs:

Public submission requires all of the following:

  • a stable domain (no temporary tunnel)
  • a verified org
  • a privacy policy
  • a demo account
  • test cases

OpenAI also rejects demo/trial apps, so this repo is for portfolio and Developer Mode only: https://developers.openai.com/apps-sdk/app-submission-guidelines

Grok Bot / Cursor marketplace

The form is at https://x.ai/bot/marketplace/submit-a-plugin (opened 2026-10-14). It asks for:

  • a remote MCP URL or public GitHub repo
  • a 1:1 logo
  • an organization handle
  • a description
  • testing instructions (with test credentials)

Submitting accepts Cursor’s Marketplace Publisher Terms. Grok itself is listed as “coming soon”. Not submitted.

Meta Muse connector notes

The Muse Connector Platform (https://muse.ai/platform/docs) accepts MCP/API connectors. Requirements relevant here:

  • offer read-only OAuth where possible
  • document read/write classification, sensitive designations, side effects, errors and rate limits for each tool

The tool table above is written in that format. Not submitted.

Layout

src/app.ts        express app, /mcp (stateless Streamable HTTP)
src/auth.ts       demo OAuth 2.1 AS + bearer middleware
src/mcp.ts        tools, UI resource, scope checks
src/safety.ts     masking, discount cap, audit log
src/widget.ts     MCP Apps HTML widget
src/data/         mock store (sample) + Shopify GraphQL adapter
scripts/          oauth-flow.ts, demo-client.ts
tests/            vitest suite

中文摘要

这是一个可以直接演示的 Shopify 店铺助手 MCP server:TypeScript,用官方 SDK,走 Streamable HTTP 传输。

  • 鉴权:内置一个演示用的 OAuth 2.1 授权服务器,支持动态客户端注册(DCR)和 PKCE S256。没带有效 token 访问 /mcp 会返回 401,并附带 resource_metadata,供客户端发现鉴权配置。
  • 工具:5 个业务工具加 1 个渲染工具,都标注了 readOnly/destructive/openWorld 三个提示字段。
  • 安全边界:折扣最高 20%,而且只生成草稿;没有退款或删除工具;客户信息脱敏;每次调用写审计日志。
  • 数据:默认用模拟样本数据,无需任何凭据即可运行。设置 SHOPIFY_STORE_DOMAIN 和 SHOPIFY_ADMIN_TOKEN 后改用真实 Shopify 只读适配器(未连真实店铺测试过)。
  • UI:符合 MCP Apps 标准的商品列表组件(text/html;profile=mcp-app),兼容 ChatGPT。
  • 运行:npm install && npm test && npm start,再开一个终端跑 npm run demo,会生成 DEMO_TRANSCRIPT.md。
  • 限制:OpenAI 不收 demo 类 app,这个仓库只用于作品集和 Developer Mode 演示。没有提交到任何市场。
View this README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide