Architecture
Layered Design
The server follows a modular with clean principles approach, separating concerns across three layers:
┌─────────────────────────────────────┐
│ Transport Layer (src/index.ts) │ MCP stdio JSON-RPC
├─────────────────────────────────────┤
│ Tool Layer (src/tools/) │ Zod schemas + LLM descriptions
├─────────────────────────────────────┤
│ Service Layer (src/services/) │ Shopify Admin API wrapper
├─────────────────────────────────────┤
│ Common Layer (src/common/) │ Types + data transformation
└─────────────────────────────────────┘
Transport Layer (src/index.ts)
Handles the MCP stdio connection, registers tool schemas, and routes incoming tool calls to the appropriate handler. This is the entry point.
Tool Layer (src/tools/)
Each file defines:
- Schemas — Zod-validated input schemas with descriptions that help the LLM understand when and how to use each tool
- Handlers — thin functions that call the service layer and return MCP-formatted responses
Service Layer (src/services/)
Wraps the Shopify Admin REST API (version 2024-01). All requests authenticate via the X-Shopify-Access-Token header. Error handling covers authentication failures, insufficient scopes, rate limiting (with Retry-After), and not-found errors.
Common Layer (src/common/)
Shared utilities for response transformation:
types.ts— shared TypeScript interfacesutils.ts— data transformation pipeline
Response Transformation
All Shopify API responses pass through an automatic transformation pipeline before being returned to the AI assistant:
1. Metadata Stripping
Internal Shopify fields that waste tokens and add no value for AI context are recursively removed:
admin_graphql_api_id— internal GraphQL IDspresentment_prices— multi-currency presentment datatax_lines— detailed tax breakdowndiscount_allocations— discount calculation metadataduties— international duties metadatapayment_terms— payment terms metadata
2. Store URL Normalization
The SHOPIFY_STORE_URL environment variable is automatically normalized on startup. All of these formats are accepted and handled correctly:
my-store.myshopify.com → https://my-store.myshopify.com/admin/api/2024-01
https://my-store.myshopify.com → https://my-store.myshopify.com/admin/api/2024-01
https://my-store.myshopify.com/ → https://my-store.myshopify.com/admin/api/2024-01
Protocol prefixes and trailing slashes are stripped before constructing the base URL.
3. Money Formatting
Shopify returns prices as plain strings (e.g., "29.99") with a separate currency field. The server formats these into human-readable values with currency symbols:
Before: "price": "29.99" (with currency "USD")
After: "price": "$29.99 USD"
Supported currency symbols: USD ($), EUR, GBP, CAD (CA$), AUD (A$), JPY. Other currencies display the ISO code.
4. Variant Simplification
Product variants are simplified to only the fields relevant for AI context:
Before: { title, price, sku, inventory_quantity, weight, grams, barcode, ... }
After: { title, price, sku, inventory_quantity }
Order line items are similarly simplified to product, variant, quantity, price, and sku.
Security Model
- Read-only by design — no write operations are exposed
- Custom app support — we recommend using Shopify custom apps with minimal scopes (
read_orders,read_products,read_customers) - No data persistence — the server is stateless and does not store any Shopify data
- Stdio transport — communication happens over stdin/stdout, no network ports opened