shopify-graphql-extension-mcp
v2.3.0
Published
MCP server that runs Shopify Admin GraphQL through the Shopify GraphQL API Client Chrome extension's browser session — no API tokens.
Maintainers
Readme
shopify-graphql-extension-mcp
MCP server that runs Shopify Admin GraphQL through the Shopify GraphQL API Client Chrome extension's browser session. Any MCP client (Claude Code, Cursor, Claude Desktop, etc.) can query or mutate any Shopify store you have open in the browser — no API tokens, no app install. Pairs with the Chrome extension (hence the name).
How it works
MCP client ──stdio MCP──► this server ──ws://127.0.0.1:6789──► extension service worker
│ chrome.tabs.sendMessage
▼
content script → store Admin APIA Chrome MV3 service worker can't listen on a port, only dial out — so the server
is the WebSocket host and the extension connects to it. Runs on plain Node (no
Bun) so it ships to npm and launches with npx.
Install
Install the extension first (from the Chrome Web Store), then add the MCP server.
Claude Code:
claude mcp add shopify-admin -- npx -y shopify-graphql-extension-mcpOther MCP clients (Cursor, Claude Desktop, …):
{
"mcpServers": {
"shopify-admin": {
"command": "npx",
"args": ["-y", "shopify-graphql-extension-mcp"]
}
}
}Keep an admin.shopify.com tab open; the extension reconnects to the server
automatically and the extension's MCP tab shows the live status.
Local development
cd mcp-bridge
bun install
bun run build # bundle to dist/index.js for publishing
node dist/index.js # or: bun run src/index.tsThe wire contract is shared from ../chrome-extension/src/lib/bridge-protocol.ts
(single source of truth, inlined into the bundle at build time, reusable by the
cloud relay later).
Requires jq (used by the mutation approval hook below).
Tools
list_stores— the stores currently open in the browser (handle + domain).run_graphql— run a read-only QUERY. Mutations are rejected with a pointer to the mutation tool. Args:query,variables?,store?(handle or domain; required only when more than one store is open),apiVersion?.run_graphql_mutation— run a MUTATION (write). Same args. Reads are rejected. This split lets the approval gate target writes only.
Mutation approval
Writes are gated in the MCP client, not the bridge, so they survive
--dangerously-skip-permissions:
- An
askrule in~/.claude/settings.json:"permissions": { "ask": ["mcp__shopify-admin__run_graphql_mutation"] }. - A
PreToolUsehook (hooks/mutation-ask.sh) that summarizes the mutation into a readable prompt and forces theask. Wire it in settings.json with a matcher ofmcp__shopify-admin__run_graphql_mutation.
Hook changes load at Claude Code startup, so restart after editing them.
Subscription gate
Every tool call checks the user's subscription (trial or active) via the extension. Non-subscribers get a message with a checkout link.
Auth (bridge ↔ extension)
The WS server accepts a connection only if it presents ?token=<SHOPIFY_BRIDGE_TOKEN>
(when that env var is set), otherwise it requires a chrome-extension:// origin.
To use a token: start the bridge with SHOPIFY_BRIDGE_TOKEN=<secret> and set the
same value as bridgeToken in the extension's chrome.storage.local.
Config
SHOPIFY_BRIDGE_PORT— bridge WS port (default6789). If you change it, also setbridgePortin the extension'schrome.storage.local.SHOPIFY_BRIDGE_TOKEN— optional shared secret (see Auth above).
Notes / current limits
- One bridge owns the port. On startup the bridge evicts any stale process holding the port, so the newest bridge (the one your MCP client talks to) always wins.
- Works only while Chrome is open with a logged-in Shopify session in a tab.
