@salesforce/b2c-dx-mcp 0.3.1 → 0.4.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 +47 -27
- package/content/page-designer.md +4 -4
- package/dist/commands/mcp.d.ts +13 -1
- package/dist/commands/mcp.js +16 -4
- package/dist/registry.d.ts +4 -4
- package/dist/registry.js +10 -10
- package/dist/services.d.ts +75 -1
- package/dist/services.js +124 -1
- package/dist/tools/adapter.d.ts +29 -21
- package/dist/tools/adapter.js +34 -24
- package/dist/tools/cartridges/index.d.ts +5 -3
- package/dist/tools/cartridges/index.js +55 -25
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/mrt/index.d.ts +2 -2
- package/dist/tools/mrt/index.js +29 -10
- package/dist/tools/page-designer-decorator/analyzer.d.ts +169 -0
- package/dist/tools/page-designer-decorator/analyzer.js +535 -0
- package/dist/tools/page-designer-decorator/index.d.ts +252 -0
- package/dist/tools/page-designer-decorator/index.js +597 -0
- package/dist/tools/page-designer-decorator/rules/1-mode-selection.d.ts +8 -0
- package/dist/tools/page-designer-decorator/rules/1-mode-selection.js +65 -0
- package/dist/tools/page-designer-decorator/rules/2a-auto-mode.d.ts +13 -0
- package/dist/tools/page-designer-decorator/rules/2a-auto-mode.js +87 -0
- package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.d.ts +4 -0
- package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.js +55 -0
- package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.d.ts +22 -0
- package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.js +109 -0
- package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.d.ts +21 -0
- package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.js +60 -0
- package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.d.ts +27 -0
- package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.js +68 -0
- package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.d.ts +4 -0
- package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.js +65 -0
- package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.d.ts +11 -0
- package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.js +92 -0
- package/dist/tools/page-designer-decorator/rules.d.ts +51 -0
- package/dist/tools/page-designer-decorator/rules.js +70 -0
- package/dist/tools/page-designer-decorator/templates/decorator-generator.d.ts +116 -0
- package/dist/tools/page-designer-decorator/templates/decorator-generator.js +350 -0
- package/dist/tools/pwav3/index.d.ts +2 -2
- package/dist/tools/pwav3/index.js +13 -13
- package/dist/tools/scapi/index.d.ts +10 -2
- package/dist/tools/scapi/index.js +5 -56
- package/dist/tools/scapi/scapi-custom-apis-status.d.ts +9 -0
- package/dist/tools/scapi/scapi-custom-apis-status.js +152 -0
- package/dist/tools/scapi/scapi-schemas-list.d.ts +12 -0
- package/dist/tools/scapi/scapi-schemas-list.js +248 -0
- package/dist/tools/storefrontnext/developer-guidelines.d.ts +2 -2
- package/dist/tools/storefrontnext/developer-guidelines.js +3 -3
- package/dist/tools/storefrontnext/index.d.ts +2 -2
- package/dist/tools/storefrontnext/index.js +13 -13
- package/oclif.manifest.json +15 -4
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -22,16 +22,14 @@ The most important flag is **`--working-directory`** (or env var `SFCC_WORKING_D
|
|
|
22
22
|
|
|
23
23
|
> **Important:** MCP clients like Cursor and Claude Desktop spawn servers from the home directory (`~`), not your project. Always set `--working-directory`.
|
|
24
24
|
|
|
25
|
-
<!-- TODO: Update command to use npx once published to npm -->
|
|
26
|
-
|
|
27
25
|
**Cursor** (supports `${workspaceFolder}`):
|
|
28
26
|
|
|
29
27
|
```json
|
|
30
28
|
{
|
|
31
29
|
"mcpServers": {
|
|
32
30
|
"b2c-dx": {
|
|
33
|
-
"command": "
|
|
34
|
-
"args": ["/
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "@salesforce/b2c-dx-mcp", "--working-directory", "${workspaceFolder}", "--allow-non-ga-tools"]
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
}
|
|
@@ -43,8 +41,8 @@ The most important flag is **`--working-directory`** (or env var `SFCC_WORKING_D
|
|
|
43
41
|
{
|
|
44
42
|
"mcpServers": {
|
|
45
43
|
"b2c-dx": {
|
|
46
|
-
"command": "
|
|
47
|
-
"args": ["/
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["-y", "@salesforce/b2c-dx-mcp", "--working-directory", "/path/to/your/project", "--allow-non-ga-tools"]
|
|
48
46
|
}
|
|
49
47
|
}
|
|
50
48
|
}
|
|
@@ -57,7 +55,7 @@ The server analyzes your working directory and enables toolsets based on what it
|
|
|
57
55
|
| Project Type | Detection | Toolsets Enabled |
|
|
58
56
|
|--------------|-----------|------------------|
|
|
59
57
|
| **PWA Kit v3** | `@salesforce/pwa-kit-*`, `@salesforce/retail-react-app`, or `ccExtensibility` in package.json | PWAV3, MRT, SCAPI |
|
|
60
|
-
| **Storefront Next** | `@salesforce/storefront-next
|
|
58
|
+
| **Storefront Next** | Root or a workspace package has `@salesforce/storefront-next*` dependency, or package name starting with `storefront-next`. | STOREFRONTNEXT, MRT, CARTRIDGES, SCAPI |
|
|
61
59
|
| **Cartridges** | `.project` file in cartridge directory | CARTRIDGES, SCAPI |
|
|
62
60
|
| **No project detected** | No B2C markers found | SCAPI (base toolset only) |
|
|
63
61
|
|
|
@@ -120,15 +118,38 @@ The `storefront_next_development_guidelines` tool provides critical architecture
|
|
|
120
118
|
- ✅ "I'm starting a new PWA Kit project. Use the MCP tool to get the development guidelines."
|
|
121
119
|
- ✅ "Use the MCP tool to create a new product listing page component in my PWA Kit project."
|
|
122
120
|
- ✅ "Use the MCP tool to recommend React hooks for fetching product data in PWA Kit."
|
|
123
|
-
- ✅ "Use the MCP tool to explore the SCAPI Shop API endpoints available for my PWA Kit storefront."
|
|
124
121
|
|
|
125
122
|
##### SCAPI Discovery
|
|
126
123
|
|
|
127
|
-
**
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
124
|
+
Use **scapi_schemas_list** for both standard SCAPI (Shop, Admin, Shopper APIs) and custom APIs. Use **scapi_custom_apis_status** for endpoint-level registration status (active/not_registered).
|
|
125
|
+
|
|
126
|
+
**SCAPI Schemas (tool: `scapi_schemas_list`):**
|
|
127
|
+
|
|
128
|
+
Discover schema metadata and fetch OpenAPI specs for both standard and custom SCAPI:
|
|
129
|
+
|
|
130
|
+
**Standard SCAPI:**
|
|
131
|
+
- ✅ "Use the MCP tool to list all available SCAPI schemas." → list mode (no includeSchemas).
|
|
132
|
+
- ✅ "Use the MCP tool to show me what checkout APIs exist." → list with apiFamily: checkout.
|
|
133
|
+
- ✅ "Use the MCP tool to discover SCAPI product endpoints." → list with apiFamily: product.
|
|
134
|
+
- ✅ "Use the MCP tool to get the OpenAPI schema for shopper-baskets v1." → fetch with apiFamily, apiName, apiVersion, includeSchemas: true.
|
|
135
|
+
- ✅ "Use the MCP tool to show me the full OpenAPI spec for shopper-products v1." → fetch with includeSchemas: true, expandAll: true.
|
|
136
|
+
|
|
137
|
+
**Custom APIs (use apiFamily: "custom"):**
|
|
138
|
+
- ✅ "Use the MCP tool to list custom API definitions." → list with apiFamily: custom.
|
|
139
|
+
- ✅ "Use the MCP tool to show me the loyalty-points custom API schema." → apiFamily: custom, apiName: loyalty-points, apiVersion: v1, includeSchemas: true.
|
|
140
|
+
|
|
141
|
+
**Custom API Endpoint Status (tool: `scapi_custom_apis_status`):**
|
|
142
|
+
|
|
143
|
+
Get registration status of custom API endpoints deployed on the instance (remote only). Returns individual HTTP endpoints (e.g., GET /hello, POST /items/{id}) with registration status (active/not_registered), one row per endpoint per site. Requires OAuth with `sfcc.custom-apis` scope.
|
|
144
|
+
|
|
145
|
+
- ✅ "Use the MCP tool to list custom SCAPI endpoints on my instance."
|
|
146
|
+
- ✅ "Use the MCP tool to show which custom APIs are active vs not registered."
|
|
147
|
+
- ✅ "Use the MCP tool to list custom API endpoints grouped by site." → groupBy: site
|
|
148
|
+
- ✅ "Use the MCP tool to list custom API endpoints grouped by type." → groupBy: type
|
|
149
|
+
- ✅ "Use the MCP tool to list only active custom API endpoints." → status: active
|
|
150
|
+
- ✅ "Use the MCP tool to find custom API endpoints that failed to register." → status: not_registered
|
|
151
|
+
- ✅ "Use the MCP tool to show endpoint details with all fields." → extended: true
|
|
152
|
+
- ✅ "Use the MCP tool to show only apiName and status for active endpoints." → status: active, columns: "apiName,status"
|
|
132
153
|
|
|
133
154
|
##### Cartridge Deployment
|
|
134
155
|
|
|
@@ -142,7 +163,7 @@ The `storefront_next_development_guidelines` tool provides critical architecture
|
|
|
142
163
|
**Good prompts:**
|
|
143
164
|
- ✅ "Use the MCP tool to build and push my Storefront Next bundle to staging."
|
|
144
165
|
- ✅ "Use the MCP tool to push the bundle from ./build directory to Managed Runtime."
|
|
145
|
-
- ✅ "Use the MCP tool to deploy my PWA Kit bundle to production with a deployment message."
|
|
166
|
+
- ✅ "Use the MCP tool to deploy my PWA Kit or Storefront Next bundle to production with a deployment message."
|
|
146
167
|
|
|
147
168
|
#### Tips for Better Results
|
|
148
169
|
|
|
@@ -157,7 +178,7 @@ Credentials can be provided via **config files** (recommended), **environment va
|
|
|
157
178
|
|
|
158
179
|
| Toolset | Required Credentials |
|
|
159
180
|
|---------|---------------------|
|
|
160
|
-
| **SCAPI** | `hostname` + `client-id` + `client-secret` |
|
|
181
|
+
| **SCAPI** | `hostname` + `client-id` + `client-secret` (for `scapi_custom_apis_status`: requires `sfcc.custom-apis` scope) |
|
|
161
182
|
| **CARTRIDGES** | `hostname` + `username` + `password` (or OAuth) |
|
|
162
183
|
| **MRT** | `api-key` + `project` (optionally `environment`) |
|
|
163
184
|
| **PWAV3** | `--working-directory` only (+ MRT config for deployments) |
|
|
@@ -264,20 +285,19 @@ PWA Kit v3 development tools for building headless storefronts.
|
|
|
264
285
|
| `pwakit_recommend_hooks` | Recommend appropriate React hooks for PWA Kit use cases |
|
|
265
286
|
| `pwakit_run_site_test` | Run site tests for PWA Kit project |
|
|
266
287
|
| `pwakit_install_agent_rules` | Install AI agent rules for PWA Kit development |
|
|
267
|
-
| `
|
|
268
|
-
| `
|
|
269
|
-
| `scapi_custom_api_discovery` | Discover custom SCAPI API endpoints |
|
|
288
|
+
| `scapi_schemas_list` | List or fetch SCAPI schemas (standard and custom). Use apiFamily: "custom" for custom APIs. |
|
|
289
|
+
| `scapi_custom_apis_status` | Get registration status of custom API endpoints (active/not_registered). Remote only, requires OAuth. |
|
|
270
290
|
| `mrt_bundle_push` | Build, push bundle (optionally deploy) |
|
|
271
291
|
|
|
272
292
|
#### SCAPI
|
|
273
293
|
Salesforce Commerce API discovery and exploration.
|
|
274
|
-
- **Status:** 🚧
|
|
294
|
+
- **Status:** 🚧 Early Access
|
|
275
295
|
|
|
276
296
|
| Tool | Description |
|
|
277
297
|
|------|-------------|
|
|
278
|
-
| `
|
|
279
|
-
| `
|
|
280
|
-
| `
|
|
298
|
+
| `scapi_schemas_list` | List or fetch SCAPI schemas (standard and custom). Use apiFamily: "custom" for custom APIs. |
|
|
299
|
+
| `scapi_custom_apis_status` | Get registration status of custom API endpoints (active/not_registered). Remote only, requires OAuth. |
|
|
300
|
+
| `scapi_customapi_scaffold` | Scaffold a new custom SCAPI API (not yet implemented) |
|
|
281
301
|
|
|
282
302
|
#### STOREFRONTNEXT
|
|
283
303
|
Storefront Next development tools for building modern storefronts.
|
|
@@ -290,13 +310,13 @@ Storefront Next development tools for building modern storefronts.
|
|
|
290
310
|
| `storefront_next_figma_to_component_workflow` | Convert Figma designs to Storefront Next components |
|
|
291
311
|
| `storefront_next_generate_component` | Generate a new Storefront Next component |
|
|
292
312
|
| `storefront_next_map_tokens_to_theme` | Map design tokens to Storefront Next theme configuration |
|
|
293
|
-
| `
|
|
313
|
+
| `storefront_next_page_designer_decorator` | Add Page Designer decorators to Storefront Next components |
|
|
294
314
|
| `storefront_next_generate_page_designer_metadata` | Generate Page Designer metadata for Storefront Next components |
|
|
295
|
-
| `
|
|
296
|
-
| `
|
|
315
|
+
| `scapi_schemas_list` | List or fetch SCAPI schemas (standard and custom). Use apiFamily: "custom" for custom APIs. |
|
|
316
|
+
| `scapi_custom_apis_status` | Get registration status of custom API endpoints (active/not_registered). Remote only, requires OAuth. |
|
|
297
317
|
| `mrt_bundle_push` | Build, push bundle (optionally deploy) |
|
|
298
318
|
|
|
299
|
-
> **Note:** Some tools appear in multiple toolsets (e.g., `mrt_bundle_push`, `
|
|
319
|
+
> **Note:** Some tools appear in multiple toolsets (e.g., `mrt_bundle_push`, `scapi_schemas_list`, `scapi_custom_apis_status`). When using multiple toolsets, tools are automatically deduplicated.
|
|
300
320
|
|
|
301
321
|
## Telemetry
|
|
302
322
|
|
|
@@ -393,7 +413,7 @@ npx mcp-inspector --cli node bin/dev.js --toolsets all --allow-non-ga-tools --me
|
|
|
393
413
|
# Call a specific tool
|
|
394
414
|
npx mcp-inspector --cli node bin/dev.js --toolsets all --allow-non-ga-tools \
|
|
395
415
|
--method tools/call \
|
|
396
|
-
--tool-name
|
|
416
|
+
--tool-name storefront_next_page_designer_decorator
|
|
397
417
|
```
|
|
398
418
|
|
|
399
419
|
#### 2. IDE Integration
|
package/content/page-designer.md
CHANGED
|
@@ -35,7 +35,7 @@ To add a new content page: define a page type and ID in Commerce Cloud, then in
|
|
|
35
35
|
|
|
36
36
|
- **Add a metadata class** with `@Component('typeId', { name, description })` and `@AttributeDefinition()` (and optionally `@AttributeDefinition({ type: 'image' })`, `type: 'url'`, etc.) for each prop you want editable in Page Designer. Use `@RegionDefinition([...])` if the component has nested regions (e.g. a grid with slots).
|
|
37
37
|
- **Implement the React component** so it accepts those props (and strips Page Designer–only props like `component`, `page`, `componentData`, `designMetadata` before spreading to the DOM). If the component needs server data (e.g. products for a carousel), export a `loader({ componentData, context })` and optionally a `fallback` component; the registry calls the loader during `collectComponentDataPromises` and passes resolved data as the `data` prop.
|
|
38
|
-
- **Use the MCP tool `
|
|
38
|
+
- **Use the MCP tool `storefront_next_page_designer_decorator`** to generate decorators instead of writing them by hand. Example components: `components/hero/index.tsx`, `components/content-card/index.tsx`, `components/product-carousel/index.tsx`.
|
|
39
39
|
|
|
40
40
|
### After changes
|
|
41
41
|
|
|
@@ -50,7 +50,7 @@ To add a new content page: define a page type and ID in Commerce Cloud, then in
|
|
|
50
50
|
|
|
51
51
|
Use the **B2C DX MCP server** for Page Designer work instead of hand-writing decorators and metadata. Configure the B2C DX MCP server in your IDE (e.g. in MCP settings) so these tools are available.
|
|
52
52
|
|
|
53
|
-
### 1. `
|
|
53
|
+
### 1. `storefront_next_page_designer_decorator` (STOREFRONTNEXT toolset)
|
|
54
54
|
|
|
55
55
|
Adds Page Designer decorators to an existing React component so it can be used in Business Manager. The tool analyzes the component, picks suitable props, infers types (e.g. `*Url`/`*Link` → url, `*Image` → image, `is*`/`show*` → boolean), and generates `@Component('typeId', { name, description })`, `@AttributeDefinition()` on a metadata class, and optionally `@RegionDefinition([...])` for nested regions. It skips complex or UI-only props (e.g. className, style, callbacks).
|
|
56
56
|
|
|
@@ -71,7 +71,7 @@ Packages the cartridge, uploads it to Commerce Cloud via WebDAV, and unpacks it
|
|
|
71
71
|
|
|
72
72
|
### Typical workflow
|
|
73
73
|
|
|
74
|
-
1. **`
|
|
74
|
+
1. **`storefront_next_page_designer_decorator`** — Add decorators to the component (use autoMode for a quick first pass).
|
|
75
75
|
2. **`storefront_next_generate_page_designer_metadata`** — Generate metadata JSON so the component and regions appear in Page Designer.
|
|
76
76
|
3. **`cartridge_deploy`** — Deploy to Commerce Cloud so merchants can use the component in Business Manager.
|
|
77
77
|
|
|
@@ -81,6 +81,6 @@ Packages the cartridge, uploads it to Commerce Cloud via WebDAV, and unpacks it
|
|
|
81
81
|
2. **Use registry for components**: Register all Page Designer components with proper `typeId`
|
|
82
82
|
3. **Handle design mode**: Adapt UI when `pageDesignerMode` is `'EDIT'` or `'PREVIEW'`
|
|
83
83
|
4. **Rebuild after registry changes**: Static registry is generated at build time
|
|
84
|
-
5. **Use MCP tools**: Leverage `
|
|
84
|
+
5. **Use MCP tools**: Leverage `storefront_next_page_designer_decorator` and `storefront_next_generate_page_designer_metadata` for faster development
|
|
85
85
|
|
|
86
86
|
**Reference:** See README.md for complete Page Designer documentation and MCP tool setup.
|
package/dist/commands/mcp.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseCommand } from '@salesforce/b2c-tooling-sdk/cli';
|
|
2
2
|
import type { ResolvedB2CConfig } from '@salesforce/b2c-tooling-sdk/config';
|
|
3
|
+
import { Services } from '../services.js';
|
|
3
4
|
/**
|
|
4
5
|
* oclif Command that starts the B2C DX MCP server.
|
|
5
6
|
*
|
|
@@ -32,7 +33,7 @@ export default class McpServerCommand extends BaseCommand<typeof McpServerComman
|
|
|
32
33
|
verify: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
33
34
|
'client-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
34
35
|
'client-secret': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
35
|
-
scope: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
36
|
+
'auth-scope': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
36
37
|
'short-code': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
37
38
|
'tenant-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
38
39
|
'auth-methods': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -41,6 +42,7 @@ export default class McpServerCommand extends BaseCommand<typeof McpServerComman
|
|
|
41
42
|
'log-level': import("@oclif/core/interfaces").OptionFlag<"trace" | "debug" | "info" | "warn" | "error" | "silent" | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
42
43
|
debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
43
44
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
45
|
+
jsonl: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
44
46
|
lang: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
45
47
|
config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
46
48
|
instance: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -80,6 +82,16 @@ export default class McpServerCommand extends BaseCommand<typeof McpServerComman
|
|
|
80
82
|
* 4. ~/.mobify file (for MRT API key)
|
|
81
83
|
*/
|
|
82
84
|
protected loadConfiguration(): ResolvedB2CConfig;
|
|
85
|
+
/**
|
|
86
|
+
* Loads configuration and creates a new Services instance.
|
|
87
|
+
*
|
|
88
|
+
* This method loads configuration files (dw.json, ~/.mobify) on each call,
|
|
89
|
+
* allowing tools to pick up changes to configuration between invocations.
|
|
90
|
+
* Flags remain the same (parsed once at startup).
|
|
91
|
+
*
|
|
92
|
+
* @returns A new Services instance with loaded configuration
|
|
93
|
+
*/
|
|
94
|
+
protected loadServices(): Services;
|
|
83
95
|
/**
|
|
84
96
|
* Main entry point - starts the MCP server.
|
|
85
97
|
*
|
package/dist/commands/mcp.js
CHANGED
|
@@ -249,6 +249,19 @@ export default class McpServerCommand extends BaseCommand {
|
|
|
249
249
|
};
|
|
250
250
|
return loadConfig(flagConfig, options);
|
|
251
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Loads configuration and creates a new Services instance.
|
|
254
|
+
*
|
|
255
|
+
* This method loads configuration files (dw.json, ~/.mobify) on each call,
|
|
256
|
+
* allowing tools to pick up changes to configuration between invocations.
|
|
257
|
+
* Flags remain the same (parsed once at startup).
|
|
258
|
+
*
|
|
259
|
+
* @returns A new Services instance with loaded configuration
|
|
260
|
+
*/
|
|
261
|
+
loadServices() {
|
|
262
|
+
const config = this.loadConfiguration();
|
|
263
|
+
return Services.fromResolvedConfig(config);
|
|
264
|
+
}
|
|
252
265
|
/**
|
|
253
266
|
* Main entry point - starts the MCP server.
|
|
254
267
|
*
|
|
@@ -302,10 +315,9 @@ export default class McpServerCommand extends BaseCommand {
|
|
|
302
315
|
},
|
|
303
316
|
telemetry: this.telemetry,
|
|
304
317
|
});
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
await registerToolsets(startupFlags, server, services);
|
|
318
|
+
// Register toolsets with loader function that loads config and creates Services on each tool call
|
|
319
|
+
// This allows tools to pick up changes to config files (dw.json, ~/.mobify) between invocations
|
|
320
|
+
await registerToolsets(startupFlags, server, this.loadServices.bind(this));
|
|
309
321
|
// Connect to stdio transport
|
|
310
322
|
const transport = new StdioServerTransport();
|
|
311
323
|
await server.connect(transport);
|
package/dist/registry.d.ts
CHANGED
|
@@ -11,10 +11,10 @@ export type ToolRegistry = Record<Toolset, McpTool[]>;
|
|
|
11
11
|
* Tools are organized by their declared `toolsets` array, allowing
|
|
12
12
|
* a single tool to appear in multiple toolsets.
|
|
13
13
|
*
|
|
14
|
-
* @param
|
|
14
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
15
15
|
* @returns Complete tool registry
|
|
16
16
|
*/
|
|
17
|
-
export declare function createToolRegistry(
|
|
17
|
+
export declare function createToolRegistry(loadServices: () => Services): ToolRegistry;
|
|
18
18
|
/**
|
|
19
19
|
* Register tools with the MCP server based on startup flags.
|
|
20
20
|
*
|
|
@@ -32,6 +32,6 @@ export declare function createToolRegistry(services: Services): ToolRegistry;
|
|
|
32
32
|
*
|
|
33
33
|
* @param flags - Startup flags from CLI
|
|
34
34
|
* @param server - B2CDxMcpServer instance
|
|
35
|
-
* @param
|
|
35
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
36
36
|
*/
|
|
37
|
-
export declare function registerToolsets(flags: StartupFlags, server: B2CDxMcpServer,
|
|
37
|
+
export declare function registerToolsets(flags: StartupFlags, server: B2CDxMcpServer, loadServices: () => Services): Promise<void>;
|
package/dist/registry.js
CHANGED
|
@@ -58,10 +58,10 @@ function getToolsetsForProjectTypes(projectTypes) {
|
|
|
58
58
|
* Tools are organized by their declared `toolsets` array, allowing
|
|
59
59
|
* a single tool to appear in multiple toolsets.
|
|
60
60
|
*
|
|
61
|
-
* @param
|
|
61
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
62
62
|
* @returns Complete tool registry
|
|
63
63
|
*/
|
|
64
|
-
export function createToolRegistry(
|
|
64
|
+
export function createToolRegistry(loadServices) {
|
|
65
65
|
const registry = {
|
|
66
66
|
CARTRIDGES: [],
|
|
67
67
|
MRT: [],
|
|
@@ -71,11 +71,11 @@ export function createToolRegistry(services) {
|
|
|
71
71
|
};
|
|
72
72
|
// Collect all tools from all factories
|
|
73
73
|
const allTools = [
|
|
74
|
-
...createCartridgesTools(
|
|
75
|
-
...createMrtTools(
|
|
76
|
-
...createPwav3Tools(
|
|
77
|
-
...createScapiTools(
|
|
78
|
-
...createStorefrontNextTools(
|
|
74
|
+
...createCartridgesTools(loadServices),
|
|
75
|
+
...createMrtTools(loadServices),
|
|
76
|
+
...createPwav3Tools(loadServices),
|
|
77
|
+
...createScapiTools(loadServices),
|
|
78
|
+
...createStorefrontNextTools(loadServices),
|
|
79
79
|
];
|
|
80
80
|
// Organize tools by their declared toolsets (supports multi-toolset)
|
|
81
81
|
for (const tool of allTools) {
|
|
@@ -132,15 +132,15 @@ async function performAutoDiscovery(flags, reason) {
|
|
|
132
132
|
*
|
|
133
133
|
* @param flags - Startup flags from CLI
|
|
134
134
|
* @param server - B2CDxMcpServer instance
|
|
135
|
-
* @param
|
|
135
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
136
136
|
*/
|
|
137
|
-
export async function registerToolsets(flags, server,
|
|
137
|
+
export async function registerToolsets(flags, server, loadServices) {
|
|
138
138
|
const toolsets = flags.toolsets ?? [];
|
|
139
139
|
const individualTools = flags.tools ?? [];
|
|
140
140
|
const allowNonGaTools = flags.allowNonGaTools ?? false;
|
|
141
141
|
const logger = getLogger();
|
|
142
142
|
// Create the tool registry (all available tools)
|
|
143
|
-
const toolRegistry = createToolRegistry(
|
|
143
|
+
const toolRegistry = createToolRegistry(loadServices);
|
|
144
144
|
// Build flat list of all tools for lookup
|
|
145
145
|
const allTools = Object.values(toolRegistry).flat();
|
|
146
146
|
const allToolsByName = new Map(allTools.map((tool) => [tool.name, tool]));
|
package/dist/services.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ import fs from 'node:fs';
|
|
|
40
40
|
import type { B2CInstance } from '@salesforce/b2c-tooling-sdk';
|
|
41
41
|
import type { AuthStrategy } from '@salesforce/b2c-tooling-sdk/auth';
|
|
42
42
|
import type { ResolvedB2CConfig } from '@salesforce/b2c-tooling-sdk/config';
|
|
43
|
+
import { WebDavClient, type CustomApisClient, type ScapiSchemasClient } from '@salesforce/b2c-tooling-sdk/clients';
|
|
43
44
|
/**
|
|
44
45
|
* MRT (Managed Runtime) configuration.
|
|
45
46
|
* Groups auth, project, environment, and origin settings.
|
|
@@ -62,6 +63,8 @@ export interface ServicesOptions {
|
|
|
62
63
|
b2cInstance?: B2CInstance;
|
|
63
64
|
/** Pre-resolved MRT configuration (auth, project, environment) */
|
|
64
65
|
mrtConfig?: MrtConfig;
|
|
66
|
+
/** Resolved configuration for access to SCAPI settings */
|
|
67
|
+
resolvedConfig: ResolvedB2CConfig;
|
|
65
68
|
}
|
|
66
69
|
/**
|
|
67
70
|
* Services class that provides utilities for MCP tools.
|
|
@@ -92,7 +95,13 @@ export declare class Services {
|
|
|
92
95
|
* Resolved once at server startup from MrtCommand flags and ~/.mobify.
|
|
93
96
|
*/
|
|
94
97
|
readonly mrtConfig: MrtConfig;
|
|
95
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Resolved configuration for accessing SCAPI settings.
|
|
100
|
+
* Provides access to shortCode, tenantId, and OAuth credentials.
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
private readonly resolvedConfig;
|
|
104
|
+
constructor(opts: ServicesOptions);
|
|
96
105
|
/**
|
|
97
106
|
* Creates a Services instance from an already-resolved configuration.
|
|
98
107
|
*
|
|
@@ -113,6 +122,14 @@ export declare class Services {
|
|
|
113
122
|
* @returns True if exists, false otherwise
|
|
114
123
|
*/
|
|
115
124
|
exists(targetPath: string): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Get Custom APIs client for managing custom SCAPI endpoints.
|
|
127
|
+
* Requires shortCode, tenantId, and OAuth credentials to be configured.
|
|
128
|
+
*
|
|
129
|
+
* @throws Error if shortCode, tenantId, or OAuth credentials are missing
|
|
130
|
+
* @returns Typed Custom APIs client
|
|
131
|
+
*/
|
|
132
|
+
getCustomApisClient(): CustomApisClient;
|
|
116
133
|
/**
|
|
117
134
|
* Get the current working directory.
|
|
118
135
|
*/
|
|
@@ -121,14 +138,62 @@ export declare class Services {
|
|
|
121
138
|
* Get the user's home directory.
|
|
122
139
|
*/
|
|
123
140
|
getHomeDir(): string;
|
|
141
|
+
/**
|
|
142
|
+
* Get organization ID for SCAPI API calls.
|
|
143
|
+
* Ensures the tenant ID has the required f_ecom_ prefix.
|
|
144
|
+
*
|
|
145
|
+
* @throws Error if tenantId is not configured
|
|
146
|
+
* @returns Organization ID with f_ecom_ prefix
|
|
147
|
+
*/
|
|
148
|
+
getOrganizationId(): string;
|
|
124
149
|
/**
|
|
125
150
|
* Get OS platform information.
|
|
126
151
|
*/
|
|
127
152
|
getPlatform(): NodeJS.Platform;
|
|
153
|
+
/**
|
|
154
|
+
* Get SCAPI Schemas client for discovering available SCAPI APIs.
|
|
155
|
+
* Requires shortCode, tenantId, and OAuth credentials to be configured.
|
|
156
|
+
*
|
|
157
|
+
* @throws Error if shortCode, tenantId, or OAuth credentials are missing
|
|
158
|
+
* @returns Typed SCAPI Schemas client
|
|
159
|
+
*/
|
|
160
|
+
getScapiSchemasClient(): ScapiSchemasClient;
|
|
161
|
+
/**
|
|
162
|
+
* Get SCAPI shortCode from configuration.
|
|
163
|
+
* Returns undefined if not configured.
|
|
164
|
+
*
|
|
165
|
+
* @returns shortCode or undefined
|
|
166
|
+
*/
|
|
167
|
+
getShortCode(): string | undefined;
|
|
168
|
+
/**
|
|
169
|
+
* Get tenant ID from configuration.
|
|
170
|
+
* Returns undefined if not configured.
|
|
171
|
+
*
|
|
172
|
+
* @returns tenantId or undefined
|
|
173
|
+
*/
|
|
174
|
+
getTenantId(): string | undefined;
|
|
128
175
|
/**
|
|
129
176
|
* Get system temporary directory.
|
|
130
177
|
*/
|
|
131
178
|
getTmpDir(): string;
|
|
179
|
+
/**
|
|
180
|
+
* Get WebDAV client for file operations on B2C instances.
|
|
181
|
+
* Requires hostname and WebDAV credentials to be configured.
|
|
182
|
+
*
|
|
183
|
+
* @throws Error if hostname or B2C instance is missing
|
|
184
|
+
* @returns WebDAV client instance
|
|
185
|
+
*/
|
|
186
|
+
getWebDavClient(): WebDavClient;
|
|
187
|
+
/**
|
|
188
|
+
* Get the project working directory.
|
|
189
|
+
* Falls back to process.cwd() if not explicitly set.
|
|
190
|
+
*
|
|
191
|
+
* This is the directory where the project is located, which may differ from process.cwd()
|
|
192
|
+
* when MCP clients spawn servers from a different location (e.g., home directory).
|
|
193
|
+
*
|
|
194
|
+
* @returns Project working directory path
|
|
195
|
+
*/
|
|
196
|
+
getWorkingDirectory(): string;
|
|
132
197
|
/**
|
|
133
198
|
* Join path segments.
|
|
134
199
|
*
|
|
@@ -165,4 +230,13 @@ export declare class Services {
|
|
|
165
230
|
* @returns File stats object
|
|
166
231
|
*/
|
|
167
232
|
stat(targetPath: string): fs.Stats;
|
|
233
|
+
/**
|
|
234
|
+
* Get OAuth strategy from resolved configuration.
|
|
235
|
+
* Mirrors the pattern from OAuthCommand.getOAuthStrategy().
|
|
236
|
+
*
|
|
237
|
+
* @throws Error if OAuth credentials are not configured
|
|
238
|
+
* @returns OAuth auth strategy
|
|
239
|
+
* @private
|
|
240
|
+
*/
|
|
241
|
+
private getOAuthStrategy;
|
|
168
242
|
}
|
package/dist/services.js
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
import fs from 'node:fs';
|
|
45
45
|
import path from 'node:path';
|
|
46
46
|
import os from 'node:os';
|
|
47
|
+
import { createCustomApisClient, createScapiSchemasClient, toOrganizationId, WebDavClient, } from '@salesforce/b2c-tooling-sdk/clients';
|
|
47
48
|
/**
|
|
48
49
|
* Services class that provides utilities for MCP tools.
|
|
49
50
|
*
|
|
@@ -73,9 +74,16 @@ export class Services {
|
|
|
73
74
|
* Resolved once at server startup from MrtCommand flags and ~/.mobify.
|
|
74
75
|
*/
|
|
75
76
|
mrtConfig;
|
|
76
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Resolved configuration for accessing SCAPI settings.
|
|
79
|
+
* Provides access to shortCode, tenantId, and OAuth credentials.
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
resolvedConfig;
|
|
83
|
+
constructor(opts) {
|
|
77
84
|
this.b2cInstance = opts.b2cInstance;
|
|
78
85
|
this.mrtConfig = opts.mrtConfig ?? {};
|
|
86
|
+
this.resolvedConfig = opts.resolvedConfig;
|
|
79
87
|
}
|
|
80
88
|
/**
|
|
81
89
|
* Creates a Services instance from an already-resolved configuration.
|
|
@@ -102,6 +110,7 @@ export class Services {
|
|
|
102
110
|
return new Services({
|
|
103
111
|
b2cInstance,
|
|
104
112
|
mrtConfig,
|
|
113
|
+
resolvedConfig: config,
|
|
105
114
|
});
|
|
106
115
|
}
|
|
107
116
|
// ============================================
|
|
@@ -117,6 +126,25 @@ export class Services {
|
|
|
117
126
|
exists(targetPath) {
|
|
118
127
|
return fs.existsSync(targetPath);
|
|
119
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Get Custom APIs client for managing custom SCAPI endpoints.
|
|
131
|
+
* Requires shortCode, tenantId, and OAuth credentials to be configured.
|
|
132
|
+
*
|
|
133
|
+
* @throws Error if shortCode, tenantId, or OAuth credentials are missing
|
|
134
|
+
* @returns Typed Custom APIs client
|
|
135
|
+
*/
|
|
136
|
+
getCustomApisClient() {
|
|
137
|
+
const { shortCode, tenantId } = this.resolvedConfig.values;
|
|
138
|
+
if (!shortCode) {
|
|
139
|
+
throw new Error('SCAPI short code required. Provide --short-code, set SFCC_SHORTCODE, or configure short-code in dw.json.');
|
|
140
|
+
}
|
|
141
|
+
if (!tenantId) {
|
|
142
|
+
throw new Error('Tenant ID required. Provide --tenant-id, set SFCC_TENANT_ID, or configure tenant-id in dw.json.');
|
|
143
|
+
}
|
|
144
|
+
// This will throw if OAuth credentials are missing
|
|
145
|
+
const oauthStrategy = this.getOAuthStrategy();
|
|
146
|
+
return createCustomApisClient({ shortCode, tenantId }, oauthStrategy);
|
|
147
|
+
}
|
|
120
148
|
/**
|
|
121
149
|
* Get the current working directory.
|
|
122
150
|
*/
|
|
@@ -129,18 +157,94 @@ export class Services {
|
|
|
129
157
|
getHomeDir() {
|
|
130
158
|
return os.homedir();
|
|
131
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Get organization ID for SCAPI API calls.
|
|
162
|
+
* Ensures the tenant ID has the required f_ecom_ prefix.
|
|
163
|
+
*
|
|
164
|
+
* @throws Error if tenantId is not configured
|
|
165
|
+
* @returns Organization ID with f_ecom_ prefix
|
|
166
|
+
*/
|
|
167
|
+
getOrganizationId() {
|
|
168
|
+
const { tenantId } = this.resolvedConfig.values;
|
|
169
|
+
if (!tenantId) {
|
|
170
|
+
throw new Error('Tenant ID required. Provide --tenant-id, set SFCC_TENANT_ID, or configure tenant-id in dw.json.');
|
|
171
|
+
}
|
|
172
|
+
return toOrganizationId(tenantId);
|
|
173
|
+
}
|
|
132
174
|
/**
|
|
133
175
|
* Get OS platform information.
|
|
134
176
|
*/
|
|
135
177
|
getPlatform() {
|
|
136
178
|
return os.platform();
|
|
137
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Get SCAPI Schemas client for discovering available SCAPI APIs.
|
|
182
|
+
* Requires shortCode, tenantId, and OAuth credentials to be configured.
|
|
183
|
+
*
|
|
184
|
+
* @throws Error if shortCode, tenantId, or OAuth credentials are missing
|
|
185
|
+
* @returns Typed SCAPI Schemas client
|
|
186
|
+
*/
|
|
187
|
+
getScapiSchemasClient() {
|
|
188
|
+
const { shortCode, tenantId } = this.resolvedConfig.values;
|
|
189
|
+
if (!shortCode) {
|
|
190
|
+
throw new Error('SCAPI short code required. Provide --short-code, set SFCC_SHORTCODE, or configure short-code in dw.json.');
|
|
191
|
+
}
|
|
192
|
+
if (!tenantId) {
|
|
193
|
+
throw new Error('Tenant ID required. Provide --tenant-id, set SFCC_TENANT_ID, or configure tenant-id in dw.json.');
|
|
194
|
+
}
|
|
195
|
+
// This will throw if OAuth credentials are missing
|
|
196
|
+
const oauthStrategy = this.getOAuthStrategy();
|
|
197
|
+
return createScapiSchemasClient({ shortCode, tenantId }, oauthStrategy);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get SCAPI shortCode from configuration.
|
|
201
|
+
* Returns undefined if not configured.
|
|
202
|
+
*
|
|
203
|
+
* @returns shortCode or undefined
|
|
204
|
+
*/
|
|
205
|
+
getShortCode() {
|
|
206
|
+
return this.resolvedConfig.values.shortCode;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get tenant ID from configuration.
|
|
210
|
+
* Returns undefined if not configured.
|
|
211
|
+
*
|
|
212
|
+
* @returns tenantId or undefined
|
|
213
|
+
*/
|
|
214
|
+
getTenantId() {
|
|
215
|
+
return this.resolvedConfig.values.tenantId;
|
|
216
|
+
}
|
|
138
217
|
/**
|
|
139
218
|
* Get system temporary directory.
|
|
140
219
|
*/
|
|
141
220
|
getTmpDir() {
|
|
142
221
|
return os.tmpdir();
|
|
143
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Get WebDAV client for file operations on B2C instances.
|
|
225
|
+
* Requires hostname and WebDAV credentials to be configured.
|
|
226
|
+
*
|
|
227
|
+
* @throws Error if hostname or B2C instance is missing
|
|
228
|
+
* @returns WebDAV client instance
|
|
229
|
+
*/
|
|
230
|
+
getWebDavClient() {
|
|
231
|
+
if (!this.b2cInstance) {
|
|
232
|
+
throw new Error('B2C instance required for WebDAV operations. Configure hostname and authentication in dw.json.');
|
|
233
|
+
}
|
|
234
|
+
return this.b2cInstance.webdav;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get the project working directory.
|
|
238
|
+
* Falls back to process.cwd() if not explicitly set.
|
|
239
|
+
*
|
|
240
|
+
* This is the directory where the project is located, which may differ from process.cwd()
|
|
241
|
+
* when MCP clients spawn servers from a different location (e.g., home directory).
|
|
242
|
+
*
|
|
243
|
+
* @returns Project working directory path
|
|
244
|
+
*/
|
|
245
|
+
getWorkingDirectory() {
|
|
246
|
+
return this.resolvedConfig.values.workingDirectory ?? process.cwd();
|
|
247
|
+
}
|
|
144
248
|
/**
|
|
145
249
|
* Join path segments.
|
|
146
250
|
*
|
|
@@ -159,6 +263,9 @@ export class Services {
|
|
|
159
263
|
listDirectory(dirPath) {
|
|
160
264
|
return fs.readdirSync(dirPath, { withFileTypes: true });
|
|
161
265
|
}
|
|
266
|
+
// ============================================
|
|
267
|
+
// SCAPI Helper Methods
|
|
268
|
+
// ============================================
|
|
162
269
|
/**
|
|
163
270
|
* Read a file from the filesystem.
|
|
164
271
|
*
|
|
@@ -187,5 +294,21 @@ export class Services {
|
|
|
187
294
|
stat(targetPath) {
|
|
188
295
|
return fs.statSync(targetPath);
|
|
189
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Get OAuth strategy from resolved configuration.
|
|
299
|
+
* Mirrors the pattern from OAuthCommand.getOAuthStrategy().
|
|
300
|
+
*
|
|
301
|
+
* @throws Error if OAuth credentials are not configured
|
|
302
|
+
* @returns OAuth auth strategy
|
|
303
|
+
* @private
|
|
304
|
+
*/
|
|
305
|
+
getOAuthStrategy() {
|
|
306
|
+
if (!this.resolvedConfig.hasOAuthConfig()) {
|
|
307
|
+
throw new Error('OAuth client ID required. Provide --client-id, set SFCC_CLIENT_ID, or configure in dw.json.');
|
|
308
|
+
}
|
|
309
|
+
// Use resolvedConfig factory to create OAuth strategy
|
|
310
|
+
// This handles client-credentials vs implicit flow automatically
|
|
311
|
+
return this.resolvedConfig.createOAuth();
|
|
312
|
+
}
|
|
190
313
|
}
|
|
191
314
|
//# sourceMappingURL=services.js.map
|