Skip to main content
Glama
elsi06

Shopify MCP Manager

by elsi06
README.md
# Shopify MCP Manager

An MCP (Model Context Protocol) server for fully managing a Shopify store through AI assistants like Cursor or Claude Desktop.

## Architecture

```
┌─────────────────┐     stdio      ┌──────────────────┐    GraphQL    ┌──────────────┐
│  Cursor / Claude │◄──────────────►│  MCP Server      │◄────────────►│  Shopify API │
│  (MCP Client)    │                │  (Node.js)       │              │  Admin API   │
└─────────────────┘                └──────────────────┘              └──────────────┘
                                           │
                                           ▼
                                   ┌──────────────────┐
                                   │  token-store.json │
                                   │  (Access Token)   │
                                   └──────────────────┘
```

### OAuth Flow

```
┌──────────┐    1. /auth/start     ┌──────────────────┐
│  Browser  │◄────────────────────►│  OAuth Server     │
│           │                      │  (localhost:3847) │
└─────┬─────┘                      └──────────────────┘
      │                                    ▲
      │ 2. Redirect to Shopify             │ 5. Save token
      ▼                                    │
┌──────────────┐  3. Authorize  ┌──────────────────────────────┐
│  Shopify     │───────────────►│  Cloudflare Worker           │
│  Grant Screen│  4. Callback   │  (your-oauth-callback.       │
└──────────────┘  + Auth Code   │   workers.dev)               │
                                │         │                    │
                                │  Redirect to localhost:3847  │
                                │  /callback                   │
                                └──────────────────────────────┘
```

## Prerequisites

- Node.js >= 18
- A Shopify App (created in the [Dev Dashboard](https://partners.shopify.com/))
- A Cloudflare Worker for URL redirect (OAuth callback)

## Quick Start

### 1. Install dependencies

```bash
npm install
```

### 2. Configuration

Copy `.env.example` to `.env` and fill in your values:

```bash
cp .env.example .env
```

Required values from the Shopify Dev Dashboard:
- **SHOPIFY_API_KEY** → Client ID of your app
- **SHOPIFY_API_SECRET** → Client Secret of your app
- **SHOPIFY_DOMAIN** → Your myshopify.com domain
- **SHOPIFY_REDIRECT_URL** → Your Cloudflare Worker callback URL

### 3. Configure Shopify App

In the Shopify Dev Dashboard under your app:

1. Set **App URL** to your Cloudflare Worker domain (e.g. `https://your-oauth-callback.workers.dev`)
2. Add **Allowed redirection URLs**:
   - `https://your-oauth-callback.workers.dev/callback`

### 4. Configure Cloudflare Worker

Your Cloudflare Worker must redirect OAuth callbacks from Shopify to your local server.

Example Worker:

```typescript
export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    // OAuth callback from Shopify → Redirect to local server
    if (url.pathname === "/callback") {
      const localUrl = `http://localhost:3847/callback${url.search}`;
      return Response.redirect(localUrl, 302);
    }

    // App URL request from Shopify → Redirect to local server
    if (url.searchParams.has("shop")) {
      const localUrl = `http://localhost:3847${url.pathname}${url.search}`;
      return Response.redirect(localUrl, 302);
    }

    return new Response("Shopify OAuth Endpoint active.", { status: 200 });
  },
};
```

### 5. Run OAuth

```bash
npm run oauth
```

This starts a local server and opens the browser. Log in to Shopify and grant the permissions. The access token is automatically saved to `token-store.json`.

### 6. Configure MCP Server in Cursor

Add the following to your Cursor configuration (`~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "shopify-manager": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/src/mcp-server.js"],
      "env": {
        "SHOPIFY_DOMAIN": "your-store.myshopify.com",
        "SHOPIFY_API_VERSION": "2026-01"
      }
    }
  }
}
```

## Available Tools (30+)

### Shop Management
| Tool | Description |
|------|-------------|
| `shop_info` | Shop basics (name, domain, plan, currency) |
| `shop_locales` | Configured languages |
| `shop_policies` | Privacy, terms of service, refund policies |
| `available_shipping_countries` | Shipping destinations |

### Products
| Tool | Description |
|------|-------------|
| `list_products` | List products with filtering & pagination |
| `get_product` | Product details with variants & images |
| `create_product` | Create a new product |
| `update_product` | Update a product |
| `delete_product` | Delete a product |
| `list_collections` | List collections |

### Orders
| Tool | Description |
|------|-------------|
| `list_orders` | List orders with filtering |
| `get_order` | Order details |
| `update_order` | Update an order |
| `cancel_order` | Cancel an order |
| `create_draft_order` | Create a draft order |

### Customers
| Tool | Description |
|------|-------------|
| `list_customers` | List customers |
| `get_customer` | Customer details |
| `create_customer` | Create a new customer |
| `update_customer` | Update a customer |
| `delete_customer` | Delete a customer |

### Inventory
| Tool | Description |
|------|-------------|
| `list_locations` | List locations |
| `get_inventory_levels` | Show inventory levels |
| `adjust_inventory` | Adjust inventory |
| `get_product_inventory` | Full product inventory |

### Discounts
| Tool | Description |
|------|-------------|
| `list_discount_codes` | List discount codes |
| `create_basic_discount` | Create a discount code |
| `list_automatic_discounts` | List automatic discounts |

### Analytics
| Tool | Description |
|------|-------------|
| `get_order_count` | Count orders |
| `get_product_count` | Count products |
| `get_customer_count` | Count customers |
| `shop_dashboard_summary` | Dashboard overview |
| `graphql_query` | Run arbitrary GraphQL queries |

## OAuth Flow Details

The OAuth 2.0 Authorization Code Grant flow works as follows:

1. **Initiation**: User starts the OAuth flow via `http://localhost:3847/auth/start`
2. **Redirect to Shopify**: The app redirects the user to Shopify's authorization page with:
   - `client_id` (App API Key)
   - `scope` (requested permissions)
   - `redirect_uri` (Cloudflare Worker URL)
   - `state` (nonce for CSRF protection)
3. **User authorizes**: The store owner grants the requested permissions
4. **Callback**: Shopify sends an authorization code to the redirect_uri
5. **Cloudflare Worker**: Redirects the callback to the local OAuth server
6. **Security checks**:
   - HMAC verification (message authenticity from Shopify)
   - State/nonce comparison (CSRF protection)
   - Shop domain validation
7. **Token exchange**: The authorization code is exchanged for an access token via `POST https://{shop}/admin/oauth/access_token`
8. **Persistence**: The token is saved to `token-store.json`

## Security Notes

- **Never** commit `token-store.json` or `.env` (both are in `.gitignore`)
- The `SHOPIFY_API_SECRET` is confidential
- Access tokens have the permissions of the configured scopes
- If you suspect token compromise: rotate the token via the Shopify Dev Dashboard

## License

MIT

TDQS

C2.9/5.0

Scored across 32 tools

Disambiguation4/5

Most tools have a clear resource-action distinction (products, orders, customers), but there is some overlap between inventory tools (get_inventory_levels vs get_product_inventory) and count tools vs shop_dashboard_summary. Descriptions help clarify, but a few could cause misselection.

Naming Consistency4/5

The dominant pattern is verb_noun (list_*, get_*, create_*, update_*, delete_*), but exceptions like shop_info, available_shipping_countries, and graphql_query break the pattern. Also, get_product_inventory and get_inventory_levels invert the noun order, creating minor inconsistency.

Tool Count2/5

With 32 tools, this exceeds the 25+ threshold considered 'too many' in the calibration. While Shopify has many domains, the count feels heavy; some tools like get_product_count, get_order_count, and get_customer_count could be consolidated into a single metrics tool.

Completeness3/5

Core resources (products, orders, customers) have solid CRUD coverage, but collections are only listable, discounts lack update/delete, normal order creation is missing (only draft), and variant-level management is absent. These are notable gaps for a Shopify management server.

Maintenance

ActivityInactive
ResponsivenessNo issues