@salesforce/b2c-dx-mcp 0.3.2 → 0.4.1

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.
Files changed (54) hide show
  1. package/README.md +47 -27
  2. package/content/page-designer.md +4 -4
  3. package/dist/commands/mcp.d.ts +14 -2
  4. package/dist/commands/mcp.js +21 -9
  5. package/dist/registry.d.ts +4 -4
  6. package/dist/registry.js +13 -13
  7. package/dist/services.d.ts +75 -1
  8. package/dist/services.js +124 -1
  9. package/dist/tools/adapter.d.ts +29 -21
  10. package/dist/tools/adapter.js +34 -24
  11. package/dist/tools/cartridges/index.d.ts +5 -3
  12. package/dist/tools/cartridges/index.js +55 -25
  13. package/dist/tools/index.d.ts +1 -0
  14. package/dist/tools/index.js +1 -0
  15. package/dist/tools/mrt/index.d.ts +2 -2
  16. package/dist/tools/mrt/index.js +29 -10
  17. package/dist/tools/page-designer-decorator/analyzer.d.ts +169 -0
  18. package/dist/tools/page-designer-decorator/analyzer.js +535 -0
  19. package/dist/tools/page-designer-decorator/index.d.ts +252 -0
  20. package/dist/tools/page-designer-decorator/index.js +597 -0
  21. package/dist/tools/page-designer-decorator/rules/1-mode-selection.d.ts +8 -0
  22. package/dist/tools/page-designer-decorator/rules/1-mode-selection.js +65 -0
  23. package/dist/tools/page-designer-decorator/rules/2a-auto-mode.d.ts +13 -0
  24. package/dist/tools/page-designer-decorator/rules/2a-auto-mode.js +87 -0
  25. package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.d.ts +4 -0
  26. package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.js +55 -0
  27. package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.d.ts +22 -0
  28. package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.js +109 -0
  29. package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.d.ts +21 -0
  30. package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.js +60 -0
  31. package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.d.ts +27 -0
  32. package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.js +68 -0
  33. package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.d.ts +4 -0
  34. package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.js +65 -0
  35. package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.d.ts +11 -0
  36. package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.js +92 -0
  37. package/dist/tools/page-designer-decorator/rules.d.ts +51 -0
  38. package/dist/tools/page-designer-decorator/rules.js +70 -0
  39. package/dist/tools/page-designer-decorator/templates/decorator-generator.d.ts +116 -0
  40. package/dist/tools/page-designer-decorator/templates/decorator-generator.js +350 -0
  41. package/dist/tools/pwav3/index.d.ts +2 -2
  42. package/dist/tools/pwav3/index.js +13 -13
  43. package/dist/tools/scapi/index.d.ts +10 -2
  44. package/dist/tools/scapi/index.js +5 -56
  45. package/dist/tools/scapi/scapi-custom-apis-status.d.ts +9 -0
  46. package/dist/tools/scapi/scapi-custom-apis-status.js +152 -0
  47. package/dist/tools/scapi/scapi-schemas-list.d.ts +12 -0
  48. package/dist/tools/scapi/scapi-schemas-list.js +248 -0
  49. package/dist/tools/storefrontnext/developer-guidelines.d.ts +2 -2
  50. package/dist/tools/storefrontnext/developer-guidelines.js +3 -3
  51. package/dist/tools/storefrontnext/index.d.ts +2 -2
  52. package/dist/tools/storefrontnext/index.js +13 -13
  53. package/oclif.manifest.json +20 -6
  54. 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": "node",
34
- "args": ["/path/to/packages/b2c-dx-mcp/bin/dev.js", "--working-directory", "${workspaceFolder}", "--allow-non-ga-tools"]
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": "node",
47
- "args": ["/path/to/packages/b2c-dx-mcp/bin/dev.js", "--working-directory", "/path/to/your/project", "--allow-non-ga-tools"]
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-*` in package.json | STOREFRONTNEXT, MRT, SCAPI |
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
- **Good prompts:**
128
- - ✅ "Use the MCP tool to discover what SCAPI endpoints are available for product data."
129
- - "Use the MCP tool to discover custom SCAPI APIs in my B2C instance."
130
- - ✅ "Use the MCP tool to show me all available SCAPI endpoints and their capabilities."
131
- - "Use the MCP tool to scaffold a new custom SCAPI API for order management."
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
- | `pwakit_explore_scapi_shop_api` | Explore SCAPI Shop API endpoints and capabilities |
268
- | `scapi_discovery` | Discover available SCAPI endpoints and capabilities |
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:** 🚧 Placeholder
294
+ - **Status:** 🚧 Early Access
275
295
 
276
296
  | Tool | Description |
277
297
  |------|-------------|
278
- | `scapi_discovery` | Discover available SCAPI endpoints and capabilities |
279
- | `scapi_customapi_scaffold` | Scaffold a new custom SCAPI API |
280
- | `scapi_custom_api_discovery` | Discover custom SCAPI API endpoints |
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
- | `storefront_next_design_decorator` | Apply design decorators to Storefront Next components |
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
- | `scapi_discovery` | Discover available SCAPI endpoints and capabilities |
296
- | `scapi_custom_api_discovery` | Discover custom SCAPI API endpoints |
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`, `scapi_discovery`). When using multiple toolsets, tools are automatically deduplicated.
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 storefront_next_design_decorator
416
+ --tool-name storefront_next_page_designer_decorator
397
417
  ```
398
418
 
399
419
  #### 2. IDE Integration
@@ -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 `storefront_next_design_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`.
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. `storefront_next_design_decorator` (STOREFRONTNEXT toolset)
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. **`storefront_next_design_decorator`** — Add decorators to the component (use autoMode for a quick first pass).
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 `storefront_next_design_decorator` and `storefront_next_generate_page_designer_metadata` for faster development
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.
@@ -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
  *
@@ -41,10 +42,11 @@ 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>;
47
- 'working-directory': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
49
+ 'project-directory': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
48
50
  'extra-query': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
49
51
  'extra-body': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
50
52
  'extra-headers': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -76,10 +78,20 @@ export default class McpServerCommand extends BaseCommand<typeof McpServerComman
76
78
  * Priority (highest to lowest):
77
79
  * 1. CLI flags (--server, --username, --api-key, etc.)
78
80
  * 2. Environment variables (SFCC_SERVER, SFCC_USERNAME, SFCC_MRT_API_KEY, etc.)
79
- * 3. dw.json file (via --config flag or auto-discovered from --working-directory)
81
+ * 3. dw.json file (via --config flag or auto-discovered from --project-directory)
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
  *
@@ -47,7 +47,7 @@
47
47
  * ### Global Flags (inherited from BaseCommand)
48
48
  * | Flag | Env Variable | Description |
49
49
  * |------|--------------|-------------|
50
- * | `--working-directory` | `SFCC_WORKING_DIRECTORY` | Project working directory (see note below) |
50
+ * | `--project-directory` | `SFCC_PROJECT_DIRECTORY` | Project directory (see note below) |
51
51
  * | `--config` | `SFCC_CONFIG` | Path to dw.json config file (auto-discovered if not provided) |
52
52
  * | `--instance` | `SFCC_INSTANCE` | Instance name from configuration file |
53
53
  * | `--log-level` | `SFCC_LOG_LEVEL` | Set logging verbosity (trace, debug, info, warn, error, silent) |
@@ -55,13 +55,13 @@
55
55
  * | `--json` | - | Output logs as JSON lines |
56
56
  * | `--lang` | - | Language for messages |
57
57
  *
58
- * **Note on `--working-directory`**: Many MCP clients (Cursor, Claude Desktop) spawn servers from the
58
+ * **Note on `--project-directory`**: Many MCP clients (Cursor, Claude Desktop) spawn servers from the
59
59
  * user's home directory (`~`) rather than the project directory. This flag is used for:
60
60
  * - Auto-discovery (detecting project type when no `--toolsets` or `--tools` are provided)
61
61
  * - Scaffolding tools (creating files in the correct project location)
62
62
  * - Any tool that needs to operate on the project directory
63
63
  *
64
- * Use `--working-directory` or `SFCC_WORKING_DIRECTORY` env var to specify the actual project path.
64
+ * Use `--project-directory` or `SFCC_PROJECT_DIRECTORY` env var to specify the actual project path.
65
65
  *
66
66
  * ## Configuration
67
67
  *
@@ -233,7 +233,7 @@ export default class McpServerCommand extends BaseCommand {
233
233
  * Priority (highest to lowest):
234
234
  * 1. CLI flags (--server, --username, --api-key, etc.)
235
235
  * 2. Environment variables (SFCC_SERVER, SFCC_USERNAME, SFCC_MRT_API_KEY, etc.)
236
- * 3. dw.json file (via --config flag or auto-discovered from --working-directory)
236
+ * 3. dw.json file (via --config flag or auto-discovered from --project-directory)
237
237
  * 4. ~/.mobify file (for MRT API key)
238
238
  */
239
239
  loadConfiguration() {
@@ -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
  *
@@ -285,7 +298,7 @@ export default class McpServerCommand extends BaseCommand {
285
298
  allowNonGaTools: this.flags['allow-non-ga-tools'],
286
299
  configPath: this.flags.config,
287
300
  // Working directory for auto-discovery. oclif handles flag with env fallback.
288
- workingDirectory: this.flags['working-directory'],
301
+ workingDirectory: this.flags['project-directory'],
289
302
  };
290
303
  // Add toolsets to telemetry attributes
291
304
  if (this.telemetry && startupFlags.toolsets) {
@@ -302,10 +315,9 @@ export default class McpServerCommand extends BaseCommand {
302
315
  },
303
316
  telemetry: this.telemetry,
304
317
  });
305
- // Create services from already-resolved config (BaseCommand.init() already resolved it)
306
- const services = Services.fromResolvedConfig(this.resolvedConfig);
307
- // Register toolsets
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);
@@ -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 services - Services instance for dependency injection
14
+ * @param loadServices - Function that loads configuration and returns Services instance
15
15
  * @returns Complete tool registry
16
16
  */
17
- export declare function createToolRegistry(services: Services): ToolRegistry;
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 services - Services instance
35
+ * @param loadServices - Function that loads configuration and returns Services instance
36
36
  */
37
- export declare function registerToolsets(flags: StartupFlags, server: B2CDxMcpServer, services: Services): Promise<void>;
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 services - Services instance for dependency injection
61
+ * @param loadServices - Function that loads configuration and returns Services instance
62
62
  * @returns Complete tool registry
63
63
  */
64
- export function createToolRegistry(services) {
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(services),
75
- ...createMrtTools(services),
76
- ...createPwav3Tools(services),
77
- ...createScapiTools(services),
78
- ...createStorefrontNextTools(services),
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) {
@@ -95,13 +95,13 @@ export function createToolRegistry(services) {
95
95
  */
96
96
  async function performAutoDiscovery(flags, reason) {
97
97
  const logger = getLogger();
98
- // Working directory from --working-directory flag or SFCC_WORKING_DIRECTORY env var
98
+ // Working directory from --project-directory flag or SFCC_PROJECT_DIRECTORY env var
99
99
  const workingDirectory = flags.workingDirectory ?? process.cwd();
100
100
  // Warn if working directory wasn't explicitly configured
101
101
  if (!flags.workingDirectory) {
102
- logger.warn({ cwd: workingDirectory }, 'No --working-directory flag or SFCC_WORKING_DIRECTORY env var provided. ' +
102
+ logger.warn({ cwd: workingDirectory }, 'No --project-directory flag or SFCC_PROJECT_DIRECTORY env var provided. ' +
103
103
  'MCP clients like Cursor and Claude Desktop often spawn servers from ~ instead of the project directory. ' +
104
- 'Set --working-directory or SFCC_WORKING_DIRECTORY for reliable auto-discovery.');
104
+ 'Set --project-directory or SFCC_PROJECT_DIRECTORY for reliable auto-discovery.');
105
105
  }
106
106
  const detectionResult = await detectWorkspaceType(workingDirectory);
107
107
  // Map all detected project types to MCP toolsets (union)
@@ -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 services - Services instance
135
+ * @param loadServices - Function that loads configuration and returns Services instance
136
136
  */
137
- export async function registerToolsets(flags, server, services) {
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(services);
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]));
@@ -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
- constructor(opts?: ServicesOptions);
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
  }