@salesforce/pwa-kit-mcp 3.12.0-nightly-20250724080225 → 3.12.0-nightly-20250728080226
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
CHANGED
|
@@ -14,7 +14,24 @@ The PWA Storefront MCP Server provides these features.
|
|
|
14
14
|
|
|
15
15
|
- `development_guidelines`: Helps developers understand and follow PWA Storefront developer guidelines and best practices.
|
|
16
16
|
- `create_new_sample_component`: Helps developers create a new sample PWA Storefront component. This feature guides developers through a few simple questions and then generates code for the component based on the commerce data model used, layouts, etc.
|
|
17
|
-
- `create_app_guidelines`:
|
|
17
|
+
- `create_app_guidelines`: This tool provides all the information an agent needs to correctly scaffold a new PWA Kit app using the `@salesforce/pwa-kit-create-app` CLI.
|
|
18
|
+
|
|
19
|
+
It returns:
|
|
20
|
+
- Project creation guidelines for agent behavior
|
|
21
|
+
- CLI description and available options
|
|
22
|
+
- Input schemas for presets or templates
|
|
23
|
+
|
|
24
|
+
The output enables agents to ask the right questions and use the CLI correctly without ever mixing unsupported options.
|
|
25
|
+
|
|
26
|
+
**Example Triggers**
|
|
27
|
+
|
|
28
|
+
This tool is automatically used when the user expresses intent to create a project, such as:
|
|
29
|
+
|
|
30
|
+
- "Create a new PWA Kit app."
|
|
31
|
+
- "Start a new storefront using a preset."
|
|
32
|
+
- "What templates are available for PWA Kit?"
|
|
33
|
+
- "What PWA-Kit presets are available?"
|
|
34
|
+
- "Create a PWA-Kit project using the `retail-react-app-demo` preset in the `~/test-project` directory."
|
|
18
35
|
- `run_site_test`: Run site performance or accessibility test for a given site URL (e.g. [https://pwa-kit.mobify-storefront.com](https://pwa-kit.mobify-storefront.com))
|
|
19
36
|
|
|
20
37
|
## Setup
|
|
@@ -34,11 +51,11 @@ npm ci
|
|
|
34
51
|
|
|
35
52
|
2. In the Cursor Menu on the top menu bar, click **Settings** > **Cursor Settings...**.
|
|
36
53
|
|
|
37
|
-
<img src="
|
|
54
|
+
<img src="https://raw.githubusercontent.com/SalesforceCommerceCloud/pwa-kit/refs/heads/develop/packages/pwa-kit-mcp/docs/images/cursor-settings.png" alt="Cursor Settings Screenshot" width="50%" />
|
|
38
55
|
|
|
39
56
|
3. Click **Tools & Integrations** > **MCP Tools** > **New MCP Server**.
|
|
40
57
|
|
|
41
|
-
<img src="
|
|
58
|
+
<img src="https://raw.githubusercontent.com/SalesforceCommerceCloud/pwa-kit/refs/heads/develop/packages/pwa-kit-mcp/docs/images/cursor-mcp-tools.png" alt="Cursor MCP Tools Screenshot" width="50%" />
|
|
42
59
|
|
|
43
60
|
The `mcp.json` file opens. Add this definition to your `mcp.json` file and replace {{parent-dir-to-mcp}} and {{path-to-app-directory}} placeholders with correct values.
|
|
44
61
|
|
|
@@ -71,7 +88,7 @@ You can go back to MCP Tools and choose to enable/disable any MCP Server or tool
|
|
|
71
88
|
1. In the Claude app menu, on the top menu bar, click **Developer** > **Edit Config**.
|
|
72
89
|
The `claude_desktop_config.json` file opens.
|
|
73
90
|
|
|
74
|
-
<img src="
|
|
91
|
+
<img src="https://raw.githubusercontent.com/SalesforceCommerceCloud/pwa-kit/refs/heads/develop/packages/pwa-kit-mcp/docs/images/claude-config.png" alt="Claude MCP Config Screenshot" width="50%" />
|
|
75
92
|
|
|
76
93
|
2. Add this server definition to your `claude_desktop_config.json` and replace {{path-to-node}}, {{parent-dir-to-mcp}} and {{path-to-app-directory}} placeholders with correct values.
|
|
77
94
|
|
|
@@ -95,7 +112,7 @@ After you modify the `claude_desktop_config.json` file, Claude will do these act
|
|
|
95
112
|
- Connect to the MCP server as a client.
|
|
96
113
|
- List available tools.
|
|
97
114
|
|
|
98
|
-
<img src="
|
|
115
|
+
<img src="https://raw.githubusercontent.com/SalesforceCommerceCloud/pwa-kit/refs/heads/develop/packages/pwa-kit-mcp/docs/images/claude-list-tools.png" alt="Claude MCP Tools Screenshot" width="40%" />
|
|
99
116
|
|
|
100
117
|
You can also enable/disable any available tools from here.
|
|
101
118
|
|
|
@@ -138,26 +155,51 @@ The server outputs debug information to stderr and handle MCP protocol messages
|
|
|
138
155
|
- package.json
|
|
139
156
|
- package-lock.json
|
|
140
157
|
- README.md
|
|
158
|
+
- CHANGELOG.md
|
|
141
159
|
- mcp.json
|
|
142
160
|
- claude_desktop_config.json
|
|
161
|
+
- babel.config.js
|
|
162
|
+
- jest.config.js
|
|
163
|
+
- jest-setup.js
|
|
164
|
+
- .eslintrc.js
|
|
165
|
+
- .eslintignore
|
|
143
166
|
/src
|
|
144
167
|
/server
|
|
145
168
|
- server.js
|
|
169
|
+
- server.test.js
|
|
170
|
+
/tools
|
|
171
|
+
- index.js
|
|
172
|
+
- developer-guideline.js
|
|
173
|
+
- developer-guideline.test.js
|
|
174
|
+
- create-app-guideline.js
|
|
175
|
+
- create-app-guideline.test.js
|
|
176
|
+
- create-new-component.js
|
|
177
|
+
- create-new-component.test.js
|
|
178
|
+
- site-test.js
|
|
179
|
+
- site-test.test.js
|
|
180
|
+
- site-test-accessibility.js
|
|
181
|
+
- site-test-performance.js
|
|
146
182
|
/utils
|
|
147
|
-
-
|
|
183
|
+
- index.js
|
|
148
184
|
- utils.js
|
|
149
|
-
|
|
150
|
-
|
|
185
|
+
- utils.test.js
|
|
186
|
+
/data
|
|
187
|
+
- CategoryDocument.json
|
|
188
|
+
- DocumentList.json
|
|
189
|
+
- ProductDocument.json
|
|
151
190
|
/docs
|
|
152
191
|
/images
|
|
153
192
|
- claude-config.png
|
|
154
193
|
- claude-list-tools.png
|
|
155
|
-
- cursor-
|
|
156
|
-
- cursor-settings.
|
|
194
|
+
- cursor-mcp-tools.png
|
|
195
|
+
- cursor-settings.png
|
|
157
196
|
- cursor-integration-guide.md
|
|
158
|
-
/
|
|
197
|
+
/dist
|
|
159
198
|
```
|
|
160
199
|
|
|
161
200
|
- Server code is in `src/server/`.
|
|
162
|
-
-
|
|
201
|
+
- MCP tools are in `src/tools/`.
|
|
202
|
+
- Utilities are in `src/utils/`.
|
|
203
|
+
- Data files are in `src/data/`.
|
|
163
204
|
- Documentation is in `docs/`.
|
|
205
|
+
- Built distribution files are in `dist/`.
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# How to Programmatically Insert Code Blocks in Cursor
|
|
2
|
+
|
|
3
|
+
This guide shows different methods to programmatically insert code blocks in files using Cursor.
|
|
4
|
+
|
|
5
|
+
## Method 1: Using Your MCP Server (Recommended)
|
|
6
|
+
|
|
7
|
+
### Setup
|
|
8
|
+
1. **Configure the MCP Server in Cursor.**
|
|
9
|
+
```json
|
|
10
|
+
// Add to your Cursor MCP configuration
|
|
11
|
+
{
|
|
12
|
+
"mcpServers": {
|
|
13
|
+
"pwa-kit-mcp": {
|
|
14
|
+
"command": "node",
|
|
15
|
+
"args": ["pwa-kit-mcp/server.js"]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
2. **Restart Cursor** to load the MCP server.
|
|
22
|
+
|
|
23
|
+
### Using the Tools
|
|
24
|
+
|
|
25
|
+
#### 1. Analyze Code Structure
|
|
26
|
+
```javascript
|
|
27
|
+
// Ask Cursor/Claude: "Analyze this React code structure"
|
|
28
|
+
// The MCP server will identify:
|
|
29
|
+
// - Import statements
|
|
30
|
+
// - Component definitions
|
|
31
|
+
// - Export statements
|
|
32
|
+
// - Insertion points
|
|
33
|
+
// - Framework detection (React, Next.js)
|
|
34
|
+
// - Styling system detection (Tailwind, CSS)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### 2. Insert React Components
|
|
38
|
+
```javascript
|
|
39
|
+
// Ask Cursor/Claude: "Insert a ProductCard component with Tailwind styling"
|
|
40
|
+
// The MCP server will:
|
|
41
|
+
// - Analyze the existing code
|
|
42
|
+
// - Generate the appropriate component
|
|
43
|
+
// - Find the best insertion point
|
|
44
|
+
// - Add necessary imports
|
|
45
|
+
// - Insert the component code
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### 3. Create New Component Files
|
|
49
|
+
```javascript
|
|
50
|
+
// Ask Cursor/Claude: "Create a new Button component file"
|
|
51
|
+
// The MCP server will generate a complete component file with:
|
|
52
|
+
// - Proper imports
|
|
53
|
+
// - Component definition
|
|
54
|
+
// - Export statement
|
|
55
|
+
// - Styling (Tailwind or CSS)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Method 2: Direct File Manipulation
|
|
59
|
+
|
|
60
|
+
### Using Node.js Scripts
|
|
61
|
+
```javascript
|
|
62
|
+
import fs from 'fs/promises';
|
|
63
|
+
import path from 'path';
|
|
64
|
+
|
|
65
|
+
async function insertCodeBlock(filePath, codeBlock, insertionPoint = 'end') {
|
|
66
|
+
try {
|
|
67
|
+
// Read existing file
|
|
68
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
69
|
+
const lines = content.split('\n');
|
|
70
|
+
|
|
71
|
+
let insertIndex;
|
|
72
|
+
|
|
73
|
+
switch (insertionPoint) {
|
|
74
|
+
case 'start':
|
|
75
|
+
insertIndex = 0;
|
|
76
|
+
break;
|
|
77
|
+
case 'end':
|
|
78
|
+
insertIndex = lines.length;
|
|
79
|
+
break;
|
|
80
|
+
case 'after-imports':
|
|
81
|
+
// Find last import statement
|
|
82
|
+
insertIndex = findLastImportLine(lines) + 1;
|
|
83
|
+
break;
|
|
84
|
+
case 'before-export':
|
|
85
|
+
// Find export default statement
|
|
86
|
+
insertIndex = findExportDefaultLine(lines);
|
|
87
|
+
break;
|
|
88
|
+
default:
|
|
89
|
+
insertIndex = lines.length;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Insert the code block
|
|
93
|
+
lines.splice(insertIndex, 0, '', codeBlock, '');
|
|
94
|
+
|
|
95
|
+
// Write back to file
|
|
96
|
+
await fs.writeFile(filePath, lines.join('\n'), 'utf-8');
|
|
97
|
+
console.log(`✅ Code inserted into ${filePath}`);
|
|
98
|
+
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('❌ Error inserting code:', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function findLastImportLine(lines) {
|
|
105
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
106
|
+
if (lines[i].trim().startsWith('import ')) {
|
|
107
|
+
return i;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function findExportDefaultLine(lines) {
|
|
114
|
+
for (let i = 0; i < lines.length; i++) {
|
|
115
|
+
if (lines[i].trim().startsWith('export default')) {
|
|
116
|
+
return i;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return lines.length;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Usage
|
|
123
|
+
await insertCodeBlock(
|
|
124
|
+
'./src/App.js',
|
|
125
|
+
`const NewComponent = () => {
|
|
126
|
+
return <div>Hello World</div>;
|
|
127
|
+
};`,
|
|
128
|
+
'after-imports'
|
|
129
|
+
);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Using the fs module with templates
|
|
133
|
+
```javascript
|
|
134
|
+
import fs from 'fs/promises';
|
|
135
|
+
import { AddComponentTool } from './AddComponentTool.js';
|
|
136
|
+
|
|
137
|
+
const componentTool = new AddComponentTool();
|
|
138
|
+
|
|
139
|
+
async function insertReactComponent(filePath, componentType, options) {
|
|
140
|
+
try {
|
|
141
|
+
// Read existing file
|
|
142
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
143
|
+
|
|
144
|
+
// Use our MCP tool to insert the component
|
|
145
|
+
const modifiedCode = componentTool.insertComponent(content, componentType, options);
|
|
146
|
+
|
|
147
|
+
// Write back to file
|
|
148
|
+
await fs.writeFile(filePath, modifiedCode, 'utf-8');
|
|
149
|
+
console.log(`✅ ${componentType} component inserted into ${filePath}`);
|
|
150
|
+
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error('❌ Error:', error);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Usage
|
|
157
|
+
await insertReactComponent('./src/App.js', 'button', {
|
|
158
|
+
name: 'SubmitButton',
|
|
159
|
+
variant: 'primary',
|
|
160
|
+
styling: 'tailwind'
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Method 3: Using Cursor's AI Commands
|
|
165
|
+
|
|
166
|
+
### 1. **Natural Language Commands:**
|
|
167
|
+
```
|
|
168
|
+
"Insert a ProductCard component after the imports in App.js"
|
|
169
|
+
"Add a modal component with Tailwind styling to this file"
|
|
170
|
+
"Create a new button component with these specifications: primary variant, medium size"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 2. **Structured Prompts:**
|
|
174
|
+
```
|
|
175
|
+
Insert a React component with these specifications.
|
|
176
|
+
- Type: ProductCard
|
|
177
|
+
- Name: FeaturedProduct
|
|
178
|
+
- Styling: Tailwind CSS
|
|
179
|
+
- Features: Show price, rating, and add-to-cart button
|
|
180
|
+
- Insert after imports in the current file
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 3. **Code Generation Prompts:**
|
|
184
|
+
```
|
|
185
|
+
Generate and insert a complete React component.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
interface ProductCardProps {
|
|
189
|
+
product: {
|
|
190
|
+
id: string;
|
|
191
|
+
name: string;
|
|
192
|
+
price: number;
|
|
193
|
+
image: string;
|
|
194
|
+
rating?: number;
|
|
195
|
+
};
|
|
196
|
+
onAddToCart: (product: Product) => void;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Create a ProductCard component using this interface.
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Method 4: VSCode/Cursor Extensions
|
|
204
|
+
|
|
205
|
+
### Custom Extension for Code Insertion
|
|
206
|
+
```javascript
|
|
207
|
+
// extension.js
|
|
208
|
+
const vscode = require('vscode');
|
|
209
|
+
|
|
210
|
+
function activate(context) {
|
|
211
|
+
let disposable = vscode.commands.registerCommand('extension.insertComponent', async () => {
|
|
212
|
+
const editor = vscode.window.activeTextEditor;
|
|
213
|
+
if (!editor) return;
|
|
214
|
+
|
|
215
|
+
// Get component type from user
|
|
216
|
+
const componentType = await vscode.window.showQuickPick([
|
|
217
|
+
'button', 'card', 'modal', 'product', 'form'
|
|
218
|
+
], { placeHolder: 'Select component type' });
|
|
219
|
+
|
|
220
|
+
if (!componentType) return;
|
|
221
|
+
|
|
222
|
+
// Generate component code using your MCP server
|
|
223
|
+
const componentCode = await generateComponent(componentType);
|
|
224
|
+
|
|
225
|
+
// Find insertion point
|
|
226
|
+
const insertionPoint = findInsertionPoint(editor.document);
|
|
227
|
+
|
|
228
|
+
// Insert the code
|
|
229
|
+
editor.edit(editBuilder => {
|
|
230
|
+
editBuilder.insert(insertionPoint, `\n${componentCode}\n`);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
context.subscriptions.push(disposable);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function generateComponent(type) {
|
|
238
|
+
// Call your MCP server or use the AddComponentTool directly
|
|
239
|
+
const { AddComponentTool } = await import('./AddComponentTool.js');
|
|
240
|
+
const tool = new AddComponentTool();
|
|
241
|
+
|
|
242
|
+
return tool.createComponentFile(
|
|
243
|
+
`Custom${type.charAt(0).toUpperCase() + type.slice(1)}`,
|
|
244
|
+
type,
|
|
245
|
+
{ styling: 'tailwind' }
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Method 5: Automation Scripts
|
|
251
|
+
|
|
252
|
+
### Batch Component Generation
|
|
253
|
+
```javascript
|
|
254
|
+
import { AddComponentTool } from './AddComponentTool.js';
|
|
255
|
+
import fs from 'fs/promises';
|
|
256
|
+
import path from 'path';
|
|
257
|
+
|
|
258
|
+
const componentTool = new AddComponentTool();
|
|
259
|
+
|
|
260
|
+
const componentsToCreate = [
|
|
261
|
+
{ name: 'ProductCard', type: 'product', options: { styling: 'tailwind' } },
|
|
262
|
+
{ name: 'AddToCartButton', type: 'button', options: { variant: 'primary' } },
|
|
263
|
+
{ name: 'ProductModal', type: 'modal', options: { closeOnOverlay: true } },
|
|
264
|
+
{ name: 'ReviewCard', type: 'card', options: { showHeader: true } }
|
|
265
|
+
];
|
|
266
|
+
|
|
267
|
+
async function generateComponents() {
|
|
268
|
+
const componentsDir = './src/components';
|
|
269
|
+
|
|
270
|
+
// Ensure directory exists
|
|
271
|
+
await fs.mkdir(componentsDir, { recursive: true });
|
|
272
|
+
|
|
273
|
+
for (const comp of componentsToCreate) {
|
|
274
|
+
const componentCode = componentTool.createComponentFile(
|
|
275
|
+
comp.name,
|
|
276
|
+
comp.type,
|
|
277
|
+
comp.options
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const fileName = `${comp.name}.jsx`;
|
|
281
|
+
const filePath = path.join(componentsDir, fileName);
|
|
282
|
+
|
|
283
|
+
await fs.writeFile(filePath, componentCode, 'utf-8');
|
|
284
|
+
console.log(`✅ Created ${fileName}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
generateComponents().catch(console.error);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Best Practices
|
|
292
|
+
|
|
293
|
+
1. **Use the MCP Server**: The MCP server provides intelligent analysis and proper code insertion.
|
|
294
|
+
2. **Validate Syntax**: Always check generated code for syntax errors.
|
|
295
|
+
3. **Preserve Formatting**: Maintain consistent code style and indentation.
|
|
296
|
+
4. **Handle Imports**: Ensure necessary imports are added when inserting components.
|
|
297
|
+
5. **Test Integration**: Verify that inserted components work with existing code.
|
|
298
|
+
|
|
299
|
+
## Demo Commands
|
|
300
|
+
|
|
301
|
+
Run the demo to see the MCP server in action:
|
|
302
|
+
```bash
|
|
303
|
+
npm run demo # or: node demo.js
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
This demo demonstrates the following:
|
|
307
|
+
- Code structure analysis
|
|
308
|
+
- Component insertion
|
|
309
|
+
- New file creation
|
|
310
|
+
- Real-time code generation
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/pwa-kit-mcp",
|
|
3
|
-
"version": "3.12.0-nightly-
|
|
3
|
+
"version": "3.12.0-nightly-20250728080226",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "MCP server that helps you build Salesforce Commerce Cloud PWA Kit Composable Storefront",
|
|
6
6
|
"main": "dist/server/server.js",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"CHANGELOG.md",
|
|
9
9
|
"LICENSE",
|
|
10
10
|
"dist/**/*.{js,d.ts,json}",
|
|
11
|
+
"docs/",
|
|
11
12
|
"!dist/CHANGELOG.md",
|
|
12
13
|
"!dist/README.md",
|
|
13
14
|
"!**/*.test.{ts,js}"
|
|
@@ -52,9 +53,9 @@
|
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@babel/node": "^7.22.5",
|
|
54
55
|
"@playwright/test": "^1.49.0",
|
|
55
|
-
"@salesforce/pwa-kit-dev": "3.12.0-nightly-
|
|
56
|
+
"@salesforce/pwa-kit-dev": "3.12.0-nightly-20250728080226",
|
|
56
57
|
"cross-env": "^5.2.1",
|
|
57
|
-
"internal-lib-build": "3.12.0-nightly-
|
|
58
|
+
"internal-lib-build": "3.12.0-nightly-20250728080226",
|
|
58
59
|
"nodemon": "^2.0.22"
|
|
59
60
|
},
|
|
60
61
|
"engines": {
|
|
@@ -64,5 +65,5 @@
|
|
|
64
65
|
"publishConfig": {
|
|
65
66
|
"directory": "dist"
|
|
66
67
|
},
|
|
67
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "a52aa781d18baaaf4bc31b405879b1c980cc2f2a"
|
|
68
69
|
}
|