@abraracs/better-shopify-wc-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +325 -0
- package/docs/avatar.md +481 -0
- package/docs/badge.md +266 -0
- package/docs/banner.md +350 -0
- package/docs/box.md +618 -0
- package/docs/button.md +604 -0
- package/docs/buttongroup.md +251 -0
- package/docs/checkbox.md +346 -0
- package/docs/chip.md +261 -0
- package/docs/choicelist.md +416 -0
- package/docs/clickable.md +703 -0
- package/docs/clickablechip.md +377 -0
- package/docs/colorfield.md +416 -0
- package/docs/colorpicker.md +152 -0
- package/docs/datefield.md +706 -0
- package/docs/datepicker.md +443 -0
- package/docs/divider.md +263 -0
- package/docs/dropzone.md +331 -0
- package/docs/emailfield.md +377 -0
- package/docs/grid.md +1246 -0
- package/docs/heading.md +201 -0
- package/docs/icon.md +295 -0
- package/docs/image.md +517 -0
- package/docs/link.md +456 -0
- package/docs/menu.md +331 -0
- package/docs/modal.md +640 -0
- package/docs/moneyfield.md +385 -0
- package/docs/numberfield.md +393 -0
- package/docs/orderedlist.md +224 -0
- package/docs/page.md +319 -0
- package/docs/paragraph.md +333 -0
- package/docs/passwordfield.md +381 -0
- package/docs/popover.md +419 -0
- package/docs/querycontainer.md +121 -0
- package/docs/searchfield.md +319 -0
- package/docs/section.md +267 -0
- package/docs/select.md +449 -0
- package/docs/spinner.md +121 -0
- package/docs/stack.md +748 -0
- package/docs/switch.md +365 -0
- package/docs/table.md +805 -0
- package/docs/text.md +339 -0
- package/docs/textarea.md +328 -0
- package/docs/textfield.md +425 -0
- package/docs/thumbnail.md +245 -0
- package/docs/tooltip.md +130 -0
- package/docs/unorderedlist.md +135 -0
- package/docs/urlfield.md +314 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Better Shopify Web Components MCP
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that provides accurate Shopify Polaris web component documentation to AI tools like Cursor, GitHub Copilot, and Claude.
|
|
4
|
+
|
|
5
|
+
## Why This Exists
|
|
6
|
+
|
|
7
|
+
Shopify's official MCP often **hallucinates attributes** because:
|
|
8
|
+
|
|
9
|
+
- Polaris web components have **specialized attributes only**
|
|
10
|
+
- Standard HTML attributes (`style`, `class`, `onclick`) **don't work**
|
|
11
|
+
- AI models haven't learned the correct patterns yet
|
|
12
|
+
|
|
13
|
+
This MCP provides:
|
|
14
|
+
|
|
15
|
+
- ✅ **Only valid attributes** from official docs
|
|
16
|
+
- ✅ **Workaround patterns** for styling limitations
|
|
17
|
+
- ✅ **System prompts** with Polaris-specific rules
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
### Cursor
|
|
22
|
+
|
|
23
|
+
Add to `~/.cursor/mcp.json`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"polaris": {
|
|
29
|
+
"command": "npx",
|
|
30
|
+
"args": ["-y", "@abraracs/better-shopify-wc-mcp"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### GitHub Copilot (VS Code)
|
|
37
|
+
|
|
38
|
+
Add to `.vscode/mcp.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"servers": {
|
|
43
|
+
"polaris": {
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["-y", "@abraracs/better-shopify-wc-mcp"]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Claude Desktop
|
|
52
|
+
|
|
53
|
+
Add to `claude_desktop_config.json`:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"polaris": {
|
|
59
|
+
"command": "npx",
|
|
60
|
+
"args": ["-y", "@abraracs/better-shopify-wc-mcp"]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
Once configured, the AI will have access to:
|
|
69
|
+
|
|
70
|
+
### Tools
|
|
71
|
+
|
|
72
|
+
- `list_components` - List all 47 Polaris components
|
|
73
|
+
- `get_component` - Get full documentation for a component
|
|
74
|
+
- `search_components` - Search by keyword
|
|
75
|
+
|
|
76
|
+
### Resources
|
|
77
|
+
|
|
78
|
+
- `polaris://components/{name}` - Direct access to component docs
|
|
79
|
+
|
|
80
|
+
### Prompts
|
|
81
|
+
|
|
82
|
+
- `polaris_rules` - Critical rules and workaround patterns
|
|
83
|
+
|
|
84
|
+
## Key Concept: Styling Workarounds
|
|
85
|
+
|
|
86
|
+
Polaris web components don't support `style` or `class` attributes. When you need custom styling, put it **INSIDE** the component:
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<!-- ❌ WRONG: style on component does nothing -->
|
|
90
|
+
<s-paragraph style="text-align: center;">Text</s-paragraph>
|
|
91
|
+
|
|
92
|
+
<!-- ✅ CORRECT: style on inner element -->
|
|
93
|
+
<s-paragraph>
|
|
94
|
+
<div style="text-align: center;">Text</div>
|
|
95
|
+
</s-paragraph>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Components Included
|
|
99
|
+
|
|
100
|
+
47 Polaris web components including:
|
|
101
|
+
|
|
102
|
+
- Actions: `button`, `buttongroup`, `link`, `menu`
|
|
103
|
+
- Forms: `textfield`, `select`, `checkbox`, `datepicker`
|
|
104
|
+
- Layout: `box`, `stack`, `grid`, `section`, `page`
|
|
105
|
+
- Feedback: `banner`, `modal`, `popover`, `tooltip`
|
|
106
|
+
- Display: `text`, `heading`, `badge`, `avatar`, `icon`
|
|
107
|
+
|
|
108
|
+
## License
|
|
109
|
+
|
|
110
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Better Shopify Web Components MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Provides accurate Polaris web component documentation with:
|
|
6
|
+
* - Only valid attributes (no hallucinations)
|
|
7
|
+
* - Workaround patterns for styling limitations
|
|
8
|
+
* - System prompts with Polaris-specific rules
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Better Shopify Web Components MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Provides accurate Polaris web component documentation with:
|
|
6
|
+
* - Only valid attributes (no hallucinations)
|
|
7
|
+
* - Workaround patterns for styling limitations
|
|
8
|
+
* - System prompts with Polaris-specific rules
|
|
9
|
+
*/
|
|
10
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
import * as fs from "fs";
|
|
14
|
+
import * as path from "path";
|
|
15
|
+
import { fileURLToPath } from "url";
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = path.dirname(__filename);
|
|
18
|
+
const DOCS_DIR = path.join(__dirname, "..", "docs");
|
|
19
|
+
function loadDocs() {
|
|
20
|
+
const docs = [];
|
|
21
|
+
const files = fs.readdirSync(DOCS_DIR).filter(f => f.endsWith(".md"));
|
|
22
|
+
for (const file of files) {
|
|
23
|
+
const content = fs.readFileSync(path.join(DOCS_DIR, file), "utf-8");
|
|
24
|
+
const name = file.replace(".md", "");
|
|
25
|
+
// Extract description from frontmatter or first paragraph
|
|
26
|
+
let description = "";
|
|
27
|
+
const descMatch = content.match(/description:\s*>-?\s*\n\s+(.+?)(?:\n[a-z_]+:|---)/s);
|
|
28
|
+
if (descMatch) {
|
|
29
|
+
description = descMatch[1].replace(/\n\s+/g, " ").trim();
|
|
30
|
+
}
|
|
31
|
+
docs.push({ name, filename: file, content, description });
|
|
32
|
+
}
|
|
33
|
+
return docs;
|
|
34
|
+
}
|
|
35
|
+
const componentDocs = loadDocs();
|
|
36
|
+
// Create server
|
|
37
|
+
const server = new Server({
|
|
38
|
+
name: "better-shopify-wc-mcp",
|
|
39
|
+
version: "1.0.0",
|
|
40
|
+
}, {
|
|
41
|
+
capabilities: {
|
|
42
|
+
resources: {},
|
|
43
|
+
tools: {},
|
|
44
|
+
prompts: {},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
// ============ RESOURCES ============
|
|
48
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
49
|
+
return {
|
|
50
|
+
resources: componentDocs.map(doc => ({
|
|
51
|
+
uri: `polaris://components/${doc.name}`,
|
|
52
|
+
name: doc.name,
|
|
53
|
+
description: doc.description || `Documentation for ${doc.name} component`,
|
|
54
|
+
mimeType: "text/markdown",
|
|
55
|
+
})),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
59
|
+
const uri = request.params.uri;
|
|
60
|
+
const match = uri.match(/^polaris:\/\/components\/(.+)$/);
|
|
61
|
+
if (!match) {
|
|
62
|
+
throw new Error(`Invalid resource URI: ${uri}`);
|
|
63
|
+
}
|
|
64
|
+
const componentName = match[1].toLowerCase();
|
|
65
|
+
const doc = componentDocs.find(d => d.name.toLowerCase() === componentName);
|
|
66
|
+
if (!doc) {
|
|
67
|
+
throw new Error(`Component not found: ${componentName}`);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
contents: [
|
|
71
|
+
{
|
|
72
|
+
uri,
|
|
73
|
+
mimeType: "text/markdown",
|
|
74
|
+
text: doc.content,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
// ============ TOOLS ============
|
|
80
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
81
|
+
return {
|
|
82
|
+
tools: [
|
|
83
|
+
{
|
|
84
|
+
name: "list_components",
|
|
85
|
+
description: "List all available Shopify Polaris web components",
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "get_component",
|
|
93
|
+
description: "Get full documentation for a specific Polaris component including all valid attributes",
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
name: {
|
|
98
|
+
type: "string",
|
|
99
|
+
description: "Component name (e.g., 'button', 'modal', 'stack')",
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
required: ["name"],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "search_components",
|
|
107
|
+
description: "Search for Polaris components by keyword in name or description",
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: "object",
|
|
110
|
+
properties: {
|
|
111
|
+
query: {
|
|
112
|
+
type: "string",
|
|
113
|
+
description: "Search keyword",
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
required: ["query"],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
123
|
+
const { name, arguments: args } = request.params;
|
|
124
|
+
switch (name) {
|
|
125
|
+
case "list_components": {
|
|
126
|
+
const list = componentDocs.map(d => ({
|
|
127
|
+
name: d.name,
|
|
128
|
+
tag: `<s-${d.name}>`,
|
|
129
|
+
description: d.description.slice(0, 100) + (d.description.length > 100 ? "..." : ""),
|
|
130
|
+
}));
|
|
131
|
+
return {
|
|
132
|
+
content: [
|
|
133
|
+
{
|
|
134
|
+
type: "text",
|
|
135
|
+
text: JSON.stringify(list, null, 2),
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
case "get_component": {
|
|
141
|
+
const componentName = args.name.toLowerCase();
|
|
142
|
+
const doc = componentDocs.find(d => d.name.toLowerCase() === componentName);
|
|
143
|
+
if (!doc) {
|
|
144
|
+
return {
|
|
145
|
+
content: [
|
|
146
|
+
{
|
|
147
|
+
type: "text",
|
|
148
|
+
text: `Component "${componentName}" not found. Use list_components to see available components.`,
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
isError: true,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
content: [
|
|
156
|
+
{
|
|
157
|
+
type: "text",
|
|
158
|
+
text: doc.content,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
case "search_components": {
|
|
164
|
+
const query = args.query.toLowerCase();
|
|
165
|
+
const results = componentDocs.filter(d => d.name.toLowerCase().includes(query) ||
|
|
166
|
+
d.description.toLowerCase().includes(query) ||
|
|
167
|
+
d.content.toLowerCase().includes(query));
|
|
168
|
+
if (results.length === 0) {
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: `No components found matching "${query}"`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const summary = results.map(d => ({
|
|
179
|
+
name: d.name,
|
|
180
|
+
tag: `<s-${d.name}>`,
|
|
181
|
+
description: d.description.slice(0, 150) + (d.description.length > 150 ? "..." : ""),
|
|
182
|
+
}));
|
|
183
|
+
return {
|
|
184
|
+
content: [
|
|
185
|
+
{
|
|
186
|
+
type: "text",
|
|
187
|
+
text: JSON.stringify(summary, null, 2),
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
default:
|
|
193
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// ============ PROMPTS ============
|
|
197
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
198
|
+
return {
|
|
199
|
+
prompts: [
|
|
200
|
+
{
|
|
201
|
+
name: "polaris_rules",
|
|
202
|
+
description: "Critical rules for working with Shopify Polaris web components - MUST READ before generating any Polaris UI code",
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
208
|
+
if (request.params.name === "polaris_rules") {
|
|
209
|
+
return {
|
|
210
|
+
description: "Critical rules for Shopify Polaris web components",
|
|
211
|
+
messages: [
|
|
212
|
+
{
|
|
213
|
+
role: "user",
|
|
214
|
+
content: {
|
|
215
|
+
type: "text",
|
|
216
|
+
text: POLARIS_RULES_PROMPT,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
throw new Error(`Unknown prompt: ${request.params.name}`);
|
|
223
|
+
});
|
|
224
|
+
// ============ SYSTEM PROMPT ============
|
|
225
|
+
const POLARIS_RULES_PROMPT = `# Shopify Polaris Web Components - Critical Rules
|
|
226
|
+
|
|
227
|
+
You are working with Shopify Polaris web components (tags starting with \`s-\`).
|
|
228
|
+
These are SPECIALIZED WEB COMPONENTS with strict rules. Follow them exactly.
|
|
229
|
+
|
|
230
|
+
## ⚠️ CRITICAL: Attribute Rules
|
|
231
|
+
|
|
232
|
+
1. **ONLY use attributes documented for each component**
|
|
233
|
+
2. **DO NOT use standard HTML attributes** - they will NOT work:
|
|
234
|
+
- ❌ style
|
|
235
|
+
- ❌ class
|
|
236
|
+
- ❌ id
|
|
237
|
+
- ❌ onclick / onchange / on*
|
|
238
|
+
- ❌ data-*
|
|
239
|
+
|
|
240
|
+
3. Each component has its OWN specific attributes (e.g., \`variant\`, \`tone\`, \`gap\`)
|
|
241
|
+
|
|
242
|
+
## 🔧 Styling Workarounds
|
|
243
|
+
|
|
244
|
+
When you need styling that's not available as a component attribute,
|
|
245
|
+
put the override **INSIDE** the web component using standard HTML:
|
|
246
|
+
|
|
247
|
+
### Example: Center-aligned text
|
|
248
|
+
\`\`\`html
|
|
249
|
+
<!-- ❌ WRONG: style attribute on s-paragraph does nothing -->
|
|
250
|
+
<s-paragraph style="text-align: center;">Text</s-paragraph>
|
|
251
|
+
|
|
252
|
+
<!-- ✅ CORRECT: put styled div INSIDE the component -->
|
|
253
|
+
<s-paragraph>
|
|
254
|
+
<div style="text-align: center;">Text</div>
|
|
255
|
+
</s-paragraph>
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
### Example: Custom spacing
|
|
259
|
+
\`\`\`html
|
|
260
|
+
<!-- ❌ WRONG: margin on component does nothing -->
|
|
261
|
+
<s-button style="margin-top: 20px;">Click</s-button>
|
|
262
|
+
|
|
263
|
+
<!-- ✅ CORRECT: use s-box or s-stack for spacing -->
|
|
264
|
+
<s-stack gap="large">
|
|
265
|
+
<s-text>Some text above</s-text>
|
|
266
|
+
<s-button>Click</s-button>
|
|
267
|
+
</s-stack>
|
|
268
|
+
\`\`\`
|
|
269
|
+
|
|
270
|
+
### Example: Flex / Grid layouts
|
|
271
|
+
\`\`\`html
|
|
272
|
+
<!-- ✅ Use s-stack with direction for flex-like layouts -->
|
|
273
|
+
<s-stack direction="inline" gap="base">
|
|
274
|
+
<s-button>Button 1</s-button>
|
|
275
|
+
<s-button>Button 2</s-button>
|
|
276
|
+
</s-stack>
|
|
277
|
+
|
|
278
|
+
<!-- ✅ Use s-grid for grid layouts -->
|
|
279
|
+
<s-grid columns="2">
|
|
280
|
+
<s-box>Cell 1</s-box>
|
|
281
|
+
<s-box>Cell 2</s-box>
|
|
282
|
+
</s-grid>
|
|
283
|
+
\`\`\`
|
|
284
|
+
|
|
285
|
+
## 📋 Common Workaround Patterns
|
|
286
|
+
|
|
287
|
+
| Need | Wrong Approach | Correct Pattern |
|
|
288
|
+
|------|----------------|-----------------|
|
|
289
|
+
| Center text | \`<s-paragraph style="text-align:center">\` | \`<s-paragraph><div style="text-align:center">text</div></s-paragraph>\` |
|
|
290
|
+
| Custom margins | \`<s-button style="margin:...">\` | Use \`<s-stack>\` or \`<s-box>\` with gap/padding attrs |
|
|
291
|
+
| Inline layout | \`<div style="display:flex">\` | \`<s-stack direction="inline">\` |
|
|
292
|
+
| Colors | \`<s-text style="color:red">\` | Use \`tone\` attribute if available |
|
|
293
|
+
| Visibility | \`style="display:none"\` | Wrap in \`<div>\` with display logic |
|
|
294
|
+
|
|
295
|
+
## 🏷️ Component Tag Format
|
|
296
|
+
|
|
297
|
+
All Polaris web components use the \`s-\` prefix:
|
|
298
|
+
- \`<s-button>\` - Buttons
|
|
299
|
+
- \`<s-stack>\` - Flex layouts
|
|
300
|
+
- \`<s-box>\` - Container with padding
|
|
301
|
+
- \`<s-modal>\` - Modal dialogs
|
|
302
|
+
- \`<s-text>\` - Text display
|
|
303
|
+
- etc.
|
|
304
|
+
|
|
305
|
+
## 📚 Before Using Any Component
|
|
306
|
+
|
|
307
|
+
1. Use \`get_component\` tool to fetch its documentation
|
|
308
|
+
2. Check the **Properties** section for valid attributes
|
|
309
|
+
3. Check **Examples** for proper usage patterns
|
|
310
|
+
4. NEVER assume an attribute exists - verify in docs first
|
|
311
|
+
|
|
312
|
+
## 🚫 Common Mistakes to Avoid
|
|
313
|
+
|
|
314
|
+
1. Using \`className\` or \`class\` - use component's own styling props
|
|
315
|
+
2. Using inline \`style\` on components - put styles on inner elements
|
|
316
|
+
3. Using React event handlers (\`onClick\`) - components have their own events
|
|
317
|
+
4. Assuming HTML attributes work - they don't on web components
|
|
318
|
+
`;
|
|
319
|
+
// ============ START SERVER ============
|
|
320
|
+
async function main() {
|
|
321
|
+
const transport = new StdioServerTransport();
|
|
322
|
+
await server.connect(transport);
|
|
323
|
+
console.error("Better Shopify WC MCP server running on stdio");
|
|
324
|
+
}
|
|
325
|
+
main().catch(console.error);
|