@salesforce/b2c-dx-mcp 3.3.0 → 3.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.
Files changed (47) hide show
  1. package/content/guidance/b2c-cli/b2c-config/SKILL.md +23 -4
  2. package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +2 -0
  3. package/content/guidance/b2c-cli/b2c-job/SKILL.md +9 -3
  4. package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +35 -6
  5. package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +5 -1
  6. package/content/guidance/b2c-ops/b2c-edge-traffic-triage/SKILL.md +69 -0
  7. package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +11 -6
  8. package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +1 -0
  9. package/content/guidance/index.json +67 -22
  10. package/content/guidance/mcp/b2c-mcp-scapi/SKILL.md +50 -226
  11. package/content/guidance/mcp/b2c-mcp-scapi/references/authentication.md +34 -0
  12. package/content/guidance/mcp/b2c-mcp-scapi/references/compose-verify.md +25 -0
  13. package/content/guidance/mcp/b2c-mcp-scapi/references/confirmation.md +30 -0
  14. package/content/guidance/mcp/b2c-mcp-scapi/references/discover.md +94 -0
  15. package/content/guidance/mcp/b2c-mcp-scapi/references/jobs.md +42 -0
  16. package/content/guidance/mcp/b2c-mcp-scapi/references/workflows.md +28 -0
  17. package/content/guidance/mcp/b2c-mcp-server/SKILL.md +4 -1
  18. package/dist/commands/mcp.js +7 -7
  19. package/dist/tools/docs/docs-read.js +4 -2
  20. package/dist/tools/docs/docs-search.js +10 -8
  21. package/dist/tools/docs/topics.d.ts +5 -0
  22. package/dist/tools/docs/topics.js +5 -0
  23. package/dist/tools/scapi/index.d.ts +1 -1
  24. package/dist/tools/scapi/index.js +2 -2
  25. package/dist/tools/scapi/scapi-code.js +96 -27
  26. package/dist/tools/scapi/scapi-schemas-list.js +93 -56
  27. package/node_modules/@salesforce/b2c-agent-plugins/CHANGELOG.md +12 -0
  28. package/node_modules/@salesforce/b2c-agent-plugins/b2c/.codex-plugin/plugin.json +1 -1
  29. package/node_modules/@salesforce/b2c-agent-plugins/b2c/plugin.json +1 -1
  30. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/.codex-plugin/plugin.json +1 -1
  31. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/plugin.json +1 -1
  32. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-config/SKILL.md +23 -4
  33. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/SKILL.md +2 -0
  34. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/SKILL.md +9 -3
  35. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/RUN-AND-MONITOR.md +35 -6
  36. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-schemas/SKILL.md +5 -1
  37. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/.codex-plugin/plugin.json +4 -3
  38. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/README.md +1 -0
  39. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/plugin.json +4 -3
  40. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-edge-traffic-triage/SKILL.md +69 -0
  41. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-job-health/SKILL.md +11 -6
  42. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-production-triage/SKILL.md +1 -0
  43. package/node_modules/@salesforce/b2c-agent-plugins/package.json +1 -1
  44. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/.codex-plugin/plugin.json +1 -1
  45. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/plugin.json +1 -1
  46. package/oclif.manifest.json +2 -2
  47. package/package.json +4 -4
@@ -5,46 +5,43 @@ description: Required before scapi_search or scapi_execute. Discover standard an
5
5
 
6
6
  # SCAPI Code Mode
7
7
 
8
- Prefer dedicated tools. Otherwise discover with `scapi_search`, compose with
9
- `scapi_execute`. Use JavaScript async arrow functions; no TypeScript or imports.
10
- Warehouse reports/SQL use `cip_discover` / `cip_query`, not code mode;
11
- see [CIP analytics](skill://mcp/b2c-mcp-cip/SKILL.md).
12
- Use code mode for API discovery, request composition, and result processing.
13
- Use terminal/file tools for local development, builds, and filesystem work.
14
- Filesystem APIs, subprocesses, worker threads, and native addons are restricted.
15
- Read this skill once via resources or `skills_read`,
16
- then pass `skillRead: true`. This does not authorize mutations.
8
+ Dedicated tool first. Else `scapi_search` (find op) then `scapi_execute` (call it). Code = JS async arrow fn. No TypeScript, no imports.
9
+ Read this once, then pass `skillRead: true`. Reading does not authorize mutations.
10
+ Warehouse SQL/reports: `cip_*`, not here. Files: `webdav_*`. Local build/fs: terminal.
11
+ Operations or incidents (jobs, checkout, orders, eCDN traffic/bots): read the matching `b2c-ops` runbook from the [skill index](skill://mcp/b2c-mcp-server/SKILL.md#skill-index) first.
17
12
 
18
- ## Code objects
13
+ ## `spec` shape (search and execute)
19
14
 
20
- Write JavaScript against these objects, not TypeScript.
21
-
22
- `scapi_search`:
15
+ Only these exist. No `spec.schemas`, no `spec.operations`. Do not probe.
23
16
 
24
17
  ```ts
18
+ declare const spec: {
19
+ apis: Array<{id: string; apiFamily: string; apiName: string; apiVersion: string; status: string}>; // id: 'product/catalogs/v1'
20
+ paths: Record<string, Record<string, Operation>>; // fullPath -> lowercase method -> op
21
+ resolve(value: unknown, apiId: string): unknown; // expand local $ref
22
+ };
23
+ // fullPath = '/' + api id + path, e.g. '/product/catalogs/v1/organizations/{organizationId}/catalogs/{catalogId}'
25
24
  interface Operation {
26
25
  api: string;
27
26
  operationId: string;
28
27
  summary?: string;
28
+ description?: string;
29
+ tags?: string[];
29
30
  parameters: Array<{name: string; in: string; required?: boolean; schema?: unknown}>;
30
31
  requestBody?: {required?: boolean; content: Record<string, {schema: any}>};
31
32
  responses?: Record<string, unknown>;
32
33
  security: Array<Record<string, string[]>>;
33
- auth: {types: string[]; schemes: string[]; executable: boolean}; // runtime support, not access
34
+ auth: {types: string[]; schemes: string[]; executable: boolean}; // executable = runtime support, not access
34
35
  }
35
- declare const spec: {
36
- apis: Array<{id: string; apiFamily: string; apiName: string; apiVersion: string; authTypes: string[]}>;
37
- paths: Record<string, Record<string, Operation>>; // full paths, lowercase HTTP methods
38
- };
39
36
  ```
40
37
 
41
- `scapi_execute` (`async (input) => ...` receives the tool's `input`):
38
+ `scapi_execute` also has (`async (input) => ...`, `input` = tool input):
42
39
 
43
40
  ```ts
44
- declare const organizationId: string | undefined; // resolved tenant
45
- declare const siteId: string | undefined; // configured site
41
+ declare const organizationId: string | undefined;
42
+ declare const siteId: string | undefined;
46
43
  declare const scapi: {
47
- request(options: {
44
+ request(o: {
48
45
  method: string;
49
46
  path: string;
50
47
  query?: Record<string, unknown>;
@@ -53,222 +50,49 @@ declare const scapi: {
53
50
  };
54
51
  ```
55
52
 
56
- Both tools also expose `codemode.search`/`codemode.describe`; `codemode.run` and
57
- `auth.*` are execute-only. See [Reusable workflows](#reusable-workflows) and [Authentication](#authentication).
53
+ ## Rules
58
54
 
59
- Search examples:
55
+ - Result cap 24 KB (`SCAPI_RESULT_TOO_LARGE`). Whole op = 6-20 KB. NEVER return `op` or `spec.paths` entries whole. List `{operationId, method, path, summary}`; then return only `parameters`/`requestBody` of ops you will call.
56
+ - Search prose too: `summary`, `description`, `tags`, not only operationId/path.
57
+ - `scapi_search` default `detail:"outline"` drops nested descriptions/examples. `detail:"full"` restores. Execute sees full.
58
+ - Default corpus = bundled standard. `schemas:"live"` = tenant (`c_*`, custom APIs, newer APIs); falls back to bundled with `warnings`. Tell user if `c_*`/custom APIs matter.
59
+ - `scapi.request` auths itself. Never fetch tokens first. Path `{organizationId}` auto-fills.
60
+ - Check `ok`/`status`. Writes: read back. Check before retry. Await every request.
61
+ - Limits: 20 calls, 4 parallel, 30 s. `fetch`/`WebSocket` disabled.
62
+ - Write needing approval pauses for client elicitation. Decline = whole run ends. Never fake approval.
60
63
 
61
64
  ```js
62
- // Find product operations
65
+ // list candidates by prose
63
66
  async () =>
64
67
  Object.entries(spec.paths)
65
- .filter(([path]) => path.startsWith('/product/products/'))
66
68
  .flatMap(([path, methods]) =>
67
- Object.entries(methods).map(([method, op]) => ({method, path, operationId: op.operationId})),
68
- );
69
+ Object.entries(methods).map(([method, op]) => ({method, path, operationId: op.operationId, summary: op.summary})),
70
+ )
71
+ .filter((o) => /basket/i.test(o.summary ?? '') && /coupon|promotion/i.test(o.summary ?? ''));
69
72
 
70
- // Inspect only fields needed for creation
73
+ // inspect only needed fields
71
74
  async () => {
72
75
  const op = spec.paths['/product/products/v1/organizations/{organizationId}/products/{productId}'].put;
73
76
  const body = op.requestBody.content['application/json'].schema;
74
- const fields = [...new Set([...(body.required ?? []), 'name', 'owningCatalogId', 'onlineFlag'])];
75
- return {
76
- parameters: op.parameters,
77
- required: body.required,
78
- fields: Object.fromEntries(fields.map((k) => [k, body.properties[k]])),
79
- auth: op.auth,
80
- security: op.security,
81
- };
77
+ return {parameters: op.parameters, required: body.required, security: op.security, auth: op.auth};
82
78
  };
83
79
  ```
84
80
 
85
- ## Discover
86
-
87
- Discovery defaults to the bundled standard contracts offline; no credentials needed.
88
- Pass `schemas: "live"` to search the configured tenant's Schemas API contracts
89
- instead: tenant `c_*` properties, custom APIs, and APIs newer than the bundle.
90
- Live search needs `sfcc.scapi-schemas`, uses the same project context as
91
- `scapi_execute`, and caches per tenant for the server session (`refresh: true` refetches). Contracts that
92
- failed to load are listed in `schemaFailures`. APIs with `origin: "local"` are
93
- developer-supplied beta contracts (`--scapi-schemas`). They replace the bundled and live versions in search and
94
- execution. Schemas and responses can be huge.
95
- Return only what the next decision needs:
96
-
97
- 1. Find APIs/operations through `spec.apis`/`spec.paths`; return method/path/operationId.
98
- 2. Narrow by `api`, path, or `authType`; inspect required inputs and selected fields,
99
- including `allOf` when present.
100
- 3. Inspect response fields only as needed; avoid whole operations/schema trees.
101
-
102
- Local refs expand; recursive/deep refs retain `$ref`. `op.auth.executable` means
103
- runtime support, not configured access; `op.security` gives scopes.
104
-
105
- ### Task map
106
-
107
- Use these API IDs to narrow discovery; inspect the operation's inputs before calling.
108
- Snippet names below have the `builtin/` prefix. Describe only the relevant snippet.
109
-
110
- | Task | API / starting point |
111
- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
112
- | Review runs, including successes | `operation/jobs/v1`: `searchJobExecutions`; `job-execution-review` snippet |
113
- | Inspect steps and exact log path | `operation/jobs/v1`: `getJobExecution`; `job-execution-inspect` snippet |
114
- | Investigate failures with detail reads | `failed-job-triage` snippet; [jobs](references/jobs.md) |
115
- | Start a job / stop an execution | `operation/jobs/v1`: `createJobExecution` / `deleteJobExecution`; confirm intent and active runs first |
116
- | Active/rollback versions, activation metadata | `dx/scripts/v1`: `getCodeVersions`; `code-version-inspect` snippet |
117
- | Activate/create/delete a code version | `dx/scripts/v1`: `updateCodeVersion` / `createCodeVersion` / `deleteCodeVersion` |
118
- | Site status, catalog, ordered cartridge path | `site/sites/v1`: `getSiteById`; `site-cartridge-inspect` snippet |
119
- | Change a site's custom cartridge path | `site/sites/v1`: `replaceSiteCustomCartridges`; preserve order and unrelated entries |
120
- | Basic product + optional category assignment | `create-product` snippet; [products](references/products.md) |
121
- | Campaign assignments and promotion details | `campaign-promotions` snippet; [promotions](references/promotions.md) |
122
-
123
- File content is WebDAV: `webdav_list` / `webdav_get` / `webdav_put`.
124
- Deploy local cartridge files with `cartridge_deploy`. Job schedules/definitions
125
- are not execution history; obtain expected schedules from Business Manager/user.
126
- Do not fall back to a terminal merely because there is no dedicated job/site tool.
127
-
128
- ### Tenant custom properties and APIs
129
-
130
- Bundled schemas omit tenant `c_*` definitions. Known custom fields can be sent
131
- directly in standard Admin bodies; schema retrieval is optional. SCAPI validates
132
- the payload. To discover tenant fields, search with `schemas: "live"` (narrow with
133
- `api`), or fetch the live schema with `scapi_schemas_list`: `includeSchemas: true`,
134
- `apiFamily`, `apiName`, `apiVersion`.
135
- Custom-property expansion defaults to true; disable with `expandCustomProperties: false`.
136
- `expandAll: true` retains full definitions; it is separate from custom-property
137
- expansion. Large contracts: fetch through `scapi_execute` and return only relevant
138
- fields ([example](references/custom-properties.md)). Requires `sfcc.scapi-schemas`.
139
- Use the same project/instance for schema lookup and writes.
140
-
141
- Live contracts found by `schemas: "live"` search, expanded `scapi_schemas_list`
142
- fetches, or Schemas API reads inside `scapi_execute` are cached for that tenant.
143
- `scapi_execute` then routes to them, replacing bundled versions; they never change
144
- the offline `spec`. If schema access fails, report it; use
145
- already-known fields or ask for missing details. The optional CLI equivalent is
146
- `b2c scapi schemas get`, which also expands custom properties by default.
147
-
148
- For custom endpoint contracts, search with `schemas: "live"` or use
149
- `scapi_schemas_list` with `apiFamily: "custom"`; check registration with
150
- `scapi_custom_apis_get_status` when needed. Custom endpoints found through live
151
- search are callable from `scapi_execute` for the same tenant. Otherwise fetch the
152
- live contract through `scapi.request` in the program before making declared calls. `AmOAuth2`
153
- and `ShopperToken` operations use their declared `c_*` scopes. [Custom API workflow](references/custom-apis.md).
154
-
155
81
  ## Authentication
156
82
 
157
- - `scapi.request()` and snippets using it authenticate automatically. Do not acquire
158
- or pass tokens first. For an explicitly requested token or external HTTP client,
159
- use `auth.accountManager()` / `auth.slas()` in `scapi_execute`:
160
- [token exports](references/tokens.md). These helpers are unavailable in search.
161
- - The operation's declared security selects the credential; there is no auth option.
162
- - Admin `AmOAuth2`: Account Manager credentials. Each request selects operation/tenant
163
- scopes and reuses suitable cached tokens; no upfront scope union.
164
- - Shopper `ShopperToken`: a SLAS guest shopper (`slasClientId`, plus `slasClientSecret`
165
- for private clients; Storefront Next `.env` supplies both). Requests need `siteId`
166
- (configured or `query.siteId`). The guest session is per site and persists across
167
- executions for the server session, so baskets carry over. SLAS scopes are fixed on
168
- the client, not requested per call; 401/403 diagnostics compare the token's scopes
169
- with the operation's. `sfcc.shopper-standard` satisfies only operations that list it.
170
- Public clients must allow redirect URI `http://localhost:3000/callback`.
171
- - Missing credentials: `config_inspect` with masking. `clientId` is Admin;
172
- `slasClientId` is Shopper. Configuration does not grant access.
173
- - Scope rejection: grant reported scopes in Account Manager; check extra configured
174
- scopes. Read/write alternatives are alternatives. Later failures do not undo writes.
175
- - Unsupported: registered-shopper-only operations (`RegisteredShopperToken`),
176
- trusted-system/agent on-behalf tokens, and SLAS itself (`shopper/auth/v1`).
177
- `auth.slas({flow: 'registered', ...})` exports a registered token for external clients.
178
- SLAS admin roles differ: `docs_read({query: "cli-slas"})` ([online](https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/slas.md)).
179
- - HTTP 401/403 retain `status`/`data` plus `diagnostic`; preserve these.
180
- A 403 alone does not prove missing scopes.
181
-
182
- For missing values or wrong targets, read [MCP configuration](skill://mcp/b2c-mcp-config/SKILL.md)
183
- (`skills_read` ID `mcp/b2c-mcp-config`). For external client/role/tenant-filter setup,
184
- use `docs_read({query: "guide-authentication"})`; official Admin authorization:
185
- `commerce-api/authorization-for-admin-apis`, scope definitions: `commerce-api/auth-z-scope-catalog`.
186
- For other access questions, search `docs_search` with the specific error and API.
187
- If docs are unavailable, use the [authentication guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/authentication.md).
188
- These are conditional setup references, not additional prerequisite reads.
189
-
190
- ## Compose and verify
191
-
192
- - Pass the execution `projectDirectory`; reuse resolved `organizationId`/`siteId`.
193
- Encode path IDs. `{organizationId}` placeholders resolve automatically.
194
- - Compose dependent calls with intermediate results and local helpers.
195
- Pause for unresolved intent or contracts.
196
- - Sequence dependent writes; batch independent reads at most four at a time.
197
- Await all requests. Map rejections to `{id, error: String(error)}`;
198
- raw `Promise.allSettled()` reasons lose Error details in JSON.
199
- - PUT can create or update: check existence and intent; read back writes.
200
- - Check `ok`/`status`: HTTP errors return; transport/auth/safety failures throw.
201
- Preserve completed writes and failed stages. Check writes before retrying;
202
- no program replay or automatic cleanup deletion.
203
- - Filter/page at the API, then project/aggregate in code. Include IDs, verification
204
- fields, errors, totals, and continuation inputs. Do not crop away missing data.
205
- - Limits: 20 calls, four outstanding, 30 seconds of active execution, 24 KB returned.
206
- Managed API/token calls are serialized within an execution. Narrow oversized
207
- discovery; reduce live pages/projections.
208
- - SDK safety applies per request, including POST searches. Use only authorized
209
- targeted exceptions. Confirmation uses client elicitation; see below. Code mode does not
210
- transfer binaries; use WebDAV tools for instance files, an external client for
211
- binary SCAPI endpoints.
212
- - `fetch` and `WebSocket` are disabled. Use `scapi.request()` inside programs;
213
- direct HTTP belongs in an external client, outside MCP Safety Mode. Do not use
214
- imports or other Node networking APIs to bypass this boundary.
215
-
216
- ## Confirmation and cancellation
217
-
218
- - A request requiring approval retains the running program and returns MCP
219
- `input_required`. Let the client handle elicitation and the protocol retry;
220
- never manufacture approval responses or modify opaque `requestState`.
221
- - Retries validate the original code, input, and target arguments, then resume
222
- the same execution. Repeated code is **not evaluated again**. Each request
223
- needs its own approval; a whole program is not a transaction.
224
- - Later managed calls wait for the pending decision. Earlier writes remain
225
- applied. Prompts identify the organization, operation, method/path, and execution
226
- ID. JSON previews are redacted and capped at five lines/400 characters; marked
227
- truncation does not limit approval, which covers the full request.
228
- Results include operation outcomes; `unknown` requires
229
- checking the affected records before a fresh attempt.
230
- - Decline/cancel terminates the entire execution, even if code catches errors.
231
- Explicitly stop work with `scapi_execute({action: "cancel", executionId, skillRead: true})`;
232
- omit code, input, project overrides, and protocol continuation state.
233
- - Approval has no server deadline; waiting does not consume the active runtime
234
- budget. At most four executions may be active per server, including pending
235
- approvals. Cancel unwanted work to free a slot. Server shutdown or disconnect
236
- releases retained workers; state does not survive a restart. Clients may impose
237
- their own timeout. Duplicate responses never replay code or send a request twice.
238
- - To change code/input/target, cancel unwanted retained work and start a fresh
239
- execution without continuation state. Cancellation does not roll back writes.
240
- Clients without form elicitation stop at confirmation-required requests.
241
-
242
- For safety levels, rule matching, configuration precedence, and confirmation
243
- semantics, read `docs_read({query: "guide-safety"})` when needed. If docs tools
244
- are unavailable, use the [Safety Mode guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/safety.md).
245
- This is an optional policy reference, not another prerequisite read.
246
-
247
- ## Reusable workflows
248
-
249
- Find workflows with `codemode.search(query)`; `codemode.describe(name)`
250
- returns source/inputSchema. Inspect before first use; `codemode.run(name, input)`
251
- composes inside execution with shared limits/auth/safety. `builtin/` ships with
252
- the MCP; `user/` persists locally. [Catalog](references/snippets.md).
253
-
254
- Reuse a snippet when its inputs and verification cover the task. Otherwise adapt
255
- its source or compose direct requests; do not omit requested fields to fit a
256
- snippet. Inputs are schema-validated before invocation. Pass variable values
257
- through the tool's `input` to `async (input)` when preparing reusable code.
258
- Discover/describe inside either code tool; run snippets only inside `scapi_execute`.
259
- Saving requires an explicit user request and a reviewed outcome; a completed
260
- execution may still contain HTTP errors or partial failures.
261
-
262
- - [Products](references/products.md): create, optionally assign a storefront category, verify both.
263
- - [Promotions](references/promotions.md): join assignments/details in bounded batches.
264
- - [Jobs](references/jobs.md): review runs, inspect steps/logs, investigate failures.
265
-
266
- For explicit save requests, see [saving](references/saving.md).
267
-
268
- No CLI code-mode equivalent. For missing settings such as promotion discounts,
269
- consider [XML archives](skill://b2c-cli/b2c-site-import-export/SKILL.md)
270
- (`docs_read({query: "cli-jobs"})`, [online](https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/jobs.md)).
271
- [Platform reference](https://developer.salesforce.com/docs/commerce/commerce-api/references).
272
- Configuration/access: `docs_read({query: "mcp-configuration"})` ([online](https://salesforcecommercecloud.github.io/b2c-developer-tooling/mcp/configuration.md)).
273
-
274
- Other MCP workflows and runbooks: [skill index](skill://mcp/b2c-mcp-server/SKILL.md#skill-index).
83
+ - Admin `AmOAuth2`: Account Manager `clientId`/secret. Shopper `ShopperToken`: SLAS guest (`slasClientId`, needs `siteId`).
84
+ - Op's declared security picks credential. No auth option.
85
+ - Missing creds: `config_inspect`. 401/403: keep `status`/`data`/`diagnostic`. 403 alone != missing scope.
86
+ - Unsupported: registered-shopper-only ops, SLAS itself (`shopper/auth/v1`).
87
+ - Detail: [authentication](references/authentication.md).
88
+
89
+ ## Read when needed (do not read all)
90
+
91
+ | Need | Read |
92
+ | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
93
+ | Pick API for a task (jobs, code versions, sites, products, promotions); live/custom schemas; `c_*` fields; `expand` | [discover](references/discover.md) |
94
+ | Compose multi-call program, verify, paging, limits | [compose-verify](references/compose-verify.md) |
95
+ | Approval, cancel, `input_required` | [confirmation](references/confirmation.md) |
96
+ | Auth, scopes, token export | [authentication](references/authentication.md), [tokens](references/tokens.md) |
97
+ | Snippets (`codemode.search/describe/run`, `builtin/`, `user/`) | [workflows](references/workflows.md) |
98
+ | Custom API | [custom-apis](references/custom-apis.md) |
@@ -0,0 +1,34 @@
1
+ # SCAPI authentication
2
+
3
+ - `scapi.request()` and snippets using it authenticate automatically. Do not acquire
4
+ or pass tokens first. For an explicitly requested token or external HTTP client,
5
+ use `auth.accountManager()` / `auth.slas()` in `scapi_execute`:
6
+ [token exports](tokens.md). These helpers are unavailable in search.
7
+ - The operation's declared security selects the credential; there is no auth option.
8
+ - Admin `AmOAuth2`: Account Manager credentials. Each request selects operation/tenant
9
+ scopes and reuses suitable cached tokens; no upfront scope union.
10
+ - Shopper `ShopperToken`: a SLAS guest shopper (`slasClientId`, plus `slasClientSecret`
11
+ for private clients; Storefront Next `.env` supplies both). Requests need `siteId`
12
+ (configured or `query.siteId`). The guest session is per site and persists across
13
+ executions for the server session, so baskets carry over. SLAS scopes are fixed on
14
+ the client, not requested per call; 401/403 diagnostics compare the token's scopes
15
+ with the operation's. `sfcc.shopper-standard` satisfies only operations that list it.
16
+ Public clients must allow redirect URI `http://localhost:3000/callback`.
17
+ - Missing credentials: `config_inspect` with masking. `clientId` is Admin;
18
+ `slasClientId` is Shopper. Configuration does not grant access.
19
+ - Scope rejection: grant reported scopes in Account Manager; check extra configured
20
+ scopes. Read/write alternatives are alternatives. Later failures do not undo writes.
21
+ - Unsupported: registered-shopper-only operations (`RegisteredShopperToken`),
22
+ trusted-system/agent on-behalf tokens, and SLAS itself (`shopper/auth/v1`).
23
+ `auth.slas({flow: 'registered', ...})` exports a registered token for external clients.
24
+ SLAS admin roles differ: `docs_read({query: "cli-slas"})` ([online](https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/slas.md)).
25
+ - HTTP 401/403 retain `status`/`data` plus `diagnostic`; preserve these.
26
+ A 403 alone does not prove missing scopes.
27
+
28
+ For missing values or wrong targets, read [MCP configuration](skill://mcp/b2c-mcp-config/SKILL.md)
29
+ (`skills_read` ID `mcp/b2c-mcp-config`). For external client/role/tenant-filter setup,
30
+ use `docs_read({query: "guide-authentication"})`; official Admin authorization:
31
+ `commerce-api/authorization-for-admin-apis`, scope definitions: `commerce-api/auth-z-scope-catalog`.
32
+ For other access questions, search `docs_search` with the specific error and API.
33
+ If docs are unavailable, use the [authentication guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/authentication.md).
34
+ These are conditional setup references, not additional prerequisite reads.
@@ -0,0 +1,25 @@
1
+ # Compose and verify
2
+
3
+ - Pass the execution `projectDirectory`; reuse resolved `organizationId`/`siteId`.
4
+ Encode path IDs. `{organizationId}` placeholders resolve automatically.
5
+ - Compose dependent calls with intermediate results and local helpers.
6
+ Pause for unresolved intent or contracts.
7
+ - Sequence dependent writes; batch independent reads at most four at a time.
8
+ Await all requests. Map rejections to `{id, error: String(error)}`;
9
+ raw `Promise.allSettled()` reasons lose Error details in JSON.
10
+ - PUT can create or update: check existence and intent; read back writes.
11
+ - Check `ok`/`status`: HTTP errors return; transport/auth/safety failures throw.
12
+ Preserve completed writes and failed stages. Check writes before retrying;
13
+ no program replay or automatic cleanup deletion.
14
+ - Filter/page at the API, then project/aggregate in code. Include IDs, verification
15
+ fields, errors, totals, and continuation inputs. Do not crop away missing data.
16
+ - Limits: 20 calls, four outstanding, 30 seconds of active execution, 24 KB returned.
17
+ Managed API/token calls are serialized within an execution. Narrow oversized
18
+ discovery; reduce live pages/projections.
19
+ - SDK safety applies per request, including POST searches. Use only authorized
20
+ targeted exceptions. Confirmation uses client elicitation; see below. Code mode does not
21
+ transfer binaries; use WebDAV tools for instance files, an external client for
22
+ binary SCAPI endpoints.
23
+ - `fetch` and `WebSocket` are disabled. Use `scapi.request()` inside programs;
24
+ direct HTTP belongs in an external client, outside MCP Safety Mode. Do not use
25
+ imports or other Node networking APIs to bypass this boundary.
@@ -0,0 +1,30 @@
1
+ # Confirmation and cancellation
2
+
3
+ - A request requiring approval retains the running program and returns MCP
4
+ `input_required`. Let the client handle elicitation and the protocol retry;
5
+ never manufacture approval responses or modify opaque `requestState`.
6
+ - Retries validate the original code, input, and target arguments, then resume
7
+ the same execution. Repeated code is **not evaluated again**. Each request
8
+ needs its own approval; a whole program is not a transaction.
9
+ - Later managed calls wait for the pending decision. Earlier writes remain
10
+ applied. Prompts identify the organization, operation, method/path, and execution
11
+ ID. JSON previews are redacted and capped at five lines/400 characters; marked
12
+ truncation does not limit approval, which covers the full request.
13
+ Results include operation outcomes; `unknown` requires
14
+ checking the affected records before a fresh attempt.
15
+ - Decline/cancel terminates the entire execution, even if code catches errors.
16
+ Explicitly stop work with `scapi_execute({action: "cancel", executionId, skillRead: true})`;
17
+ omit code, input, project overrides, and protocol continuation state.
18
+ - Approval has no server deadline; waiting does not consume the active runtime
19
+ budget. At most four executions may be active per server, including pending
20
+ approvals. Cancel unwanted work to free a slot. Server shutdown or disconnect
21
+ releases retained workers; state does not survive a restart. Clients may impose
22
+ their own timeout. Duplicate responses never replay code or send a request twice.
23
+ - To change code/input/target, cancel unwanted retained work and start a fresh
24
+ execution without continuation state. Cancellation does not roll back writes.
25
+ Clients without form elicitation stop at confirmation-required requests.
26
+
27
+ For safety levels, rule matching, configuration precedence, and confirmation
28
+ semantics, read `docs_read({query: "guide-safety"})` when needed. If docs tools
29
+ are unavailable, use the [Safety Mode guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/safety.md).
30
+ This is an optional policy reference, not another prerequisite read.
@@ -0,0 +1,94 @@
1
+ # SCAPI discovery, result limits and tenant schemas
2
+
3
+ Every operation carries `summary`, `description` and `tags` (plus parameters, security and responses), so
4
+ search the prose as well as `operationId` and path. Descriptions are long: return `op.summary` when listing
5
+ candidates, and read `op.description` only for the operations you are about to call.
6
+
7
+ `scapi_search` returns each operation as an outline by default: its own `summary`, `description` and `tags`, with
8
+ parameters, schemas and responses but without nested descriptions or examples. Pass `detail: "full"` when you need
9
+ property-level descriptions or example payloads for the operations you are about to call (`scapi_execute` always
10
+ sees full operations). Results are capped at 24 KB of JSON for both tools (`SCAPI_RESULT_TOO_LARGE`). A whole resolved operation is
11
+ typically 6-20 KB and some exceed the cap alone, so never return `op` or `spec.paths` entries unprojected: list
12
+ `{operationId, method, path, summary}`, then return only `parameters` or `requestBody` for the operations you will call.
13
+
14
+ The `spec` object has exactly three members; there is no `spec.schemas` and no need to probe it:
15
+
16
+ - `spec.apis`: array of `{id, apiFamily, apiName, apiVersion, status, origin?}` (`id` is e.g. `product/catalogs/v1`).
17
+ - `spec.paths`: `{[fullPath]: {[method]: operation}}`, where `fullPath` starts with the API id (`/product/catalogs/v1/organizations/{organizationId}/catalogs/{catalogId}`) and methods are lowercase. Operations carry `operationId`, `api`, `summary`, `description`, `tags`, `parameters`, `requestBody`, `responses`, `security` and `auth`.
18
+ - `spec.resolve(value, apiId)`: expands local `$ref`s in a fragment.
19
+
20
+ ## Discover
21
+
22
+ Discovery defaults to the bundled standard contracts offline; no credentials needed.
23
+ Pass `schemas: "live"` to search the configured tenant's Schemas API contracts
24
+ instead: tenant `c_*` properties, custom APIs, and APIs newer than the bundle.
25
+ Live search needs `sfcc.scapi-schemas`, uses the same project context as
26
+ `scapi_execute`, and caches per tenant for the server session (`refresh: true` refetches). Contracts that
27
+ failed to load are listed in `schemaFailures`. The result's `schemaSource` says which corpus was searched. If live
28
+ access fails (missing configuration, credentials or access), the search falls back to the bundled contracts,
29
+ reports `schemaSource: "bundled"` and explains why in `warnings`; tell the user when tenant `c_*` fields or custom
30
+ APIs matter, since the bundle has neither. Asking for a custom API (`custom/...`) never falls back. APIs with `origin: "local"` are
31
+ developer-supplied beta contracts (dw.json `scapi-schemas`, `SFCC_SCAPI_SCHEMAS` or `--scapi-schemas`). They replace the bundled and live versions in search and
32
+ execution. Schemas and responses can be huge.
33
+ Return only what the next decision needs:
34
+
35
+ 1. Find APIs/operations through `spec.apis`/`spec.paths`; return method/path/operationId.
36
+ 2. Narrow by `api` (a family, family/name or full id: `cdn`, `cdn/zones`, `cdn/zones/v1`), path, or `authType`; inspect required inputs and selected fields,
37
+ including `allOf` when present.
38
+ 3. Inspect response fields only as needed; avoid whole operations/schema trees.
39
+
40
+ Local refs expand; recursive/deep refs retain `$ref`. `op.auth.executable` means
41
+ runtime support, not configured access; `op.security` gives scopes.
42
+
43
+ ### Task map
44
+
45
+ Use these API IDs to narrow discovery; inspect the operation's inputs before calling.
46
+ Snippet names below have the `builtin/` prefix. Describe only the relevant snippet.
47
+
48
+ | Task | API / starting point |
49
+ | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
50
+ | Review runs, including successes | `operation/jobs/v1`: `searchJobExecutions`; `job-execution-review` snippet |
51
+ | Inspect steps and exact log path | `operation/jobs/v1`: `getJobExecution`; `job-execution-inspect` snippet |
52
+ | Investigate failures with detail reads | `failed-job-triage` snippet; [jobs](jobs.md) |
53
+ | Start a job / stop an execution | `operation/jobs/v1`: `createJobExecution` / `deleteJobExecution`; confirm intent and active runs first; bodies for system jobs: [jobs](jobs.md#start-a-job) |
54
+ | Active/rollback versions, activation metadata | `dx/scripts/v1`: `getCodeVersions`; `code-version-inspect` snippet |
55
+ | Activate/create/delete a code version | `dx/scripts/v1`: `updateCodeVersion` / `createCodeVersion` / `deleteCodeVersion` |
56
+ | Site status, catalog, ordered cartridge path | `site/sites/v1`: `getSiteById`; `site-cartridge-inspect` snippet |
57
+ | Change a site's custom cartridge path | `site/sites/v1`: `replaceSiteCustomCartridges`; preserve order and unrelated entries |
58
+ | Basic product + optional category assignment | `create-product` snippet; [products](products.md) |
59
+ | Campaign assignments and promotion details | `campaign-promotions` snippet; [promotions](promotions.md) |
60
+
61
+ File content is WebDAV: `webdav_list` / `webdav_get` / `webdav_put`.
62
+ Deploy local cartridge files with `cartridge_deploy`. Job schedules/definitions
63
+ are not execution history; obtain expected schedules from Business Manager/user.
64
+ Do not fall back to a terminal merely because there is no dedicated job/site tool.
65
+
66
+ ### Tenant custom properties and APIs
67
+
68
+ Bundled schemas omit tenant `c_*` definitions. Known custom fields can be sent
69
+ directly in standard Admin bodies; schema retrieval is optional. SCAPI validates
70
+ the payload. To discover tenant fields, search with `schemas: "live"` (narrow with
71
+ `api`), or fetch the live schema with `scapi_schemas_list`: `includeSchemas: true`,
72
+ `apiFamily`, `apiName`, `apiVersion`.
73
+ Custom-property expansion defaults to true; disable with `expandCustomProperties: false`.
74
+ `expandAll: true` returns the full contract (operation prose, examples, custom properties) instead of the
75
+ collapsed outline, which asks the Schemas API for only what it keeps. `include` selects Schemas API `expand`
76
+ sections directly (`summaries`, `descriptions`, `examples`, `external_docs`, `tags`, `titles`,
77
+ `custom_properties`, or `all`) when you want, say, only summaries. If live access fails, `scapi_schemas_list` returns
78
+ the bundled contract with `source: "bundled"` and a `warning`. Large contracts: fetch through `scapi_execute` and return only relevant
79
+ fields ([example](custom-properties.md)). Requires `sfcc.scapi-schemas`.
80
+ Use the same project/instance for schema lookup and writes.
81
+
82
+ Live contracts found by `schemas: "live"` search, expanded `scapi_schemas_list`
83
+ fetches, or Schemas API reads inside `scapi_execute` are cached for that tenant.
84
+ `scapi_execute` then routes to them, replacing bundled versions; they never change
85
+ the offline `spec`. If schema access fails, report it; use
86
+ already-known fields or ask for missing details. The optional CLI equivalent is
87
+ `b2c scapi schemas get`, which also expands custom properties by default.
88
+
89
+ For custom endpoint contracts, search with `schemas: "live"` or use
90
+ `scapi_schemas_list` with `apiFamily: "custom"`; check registration with
91
+ `scapi_custom_apis_get_status` when needed. Custom endpoints found through live
92
+ search are callable from `scapi_execute` for the same tenant. Otherwise fetch the
93
+ live contract through `scapi.request` in the program before making declared calls. `AmOAuth2`
94
+ and `ShopperToken` operations use their declared `c_*` scopes. [Custom API workflow](custom-apis.md).
@@ -28,3 +28,45 @@ failed-only search cannot establish health. Read the returned `logFilePath` with
28
28
  needs use `logs_*`. CLI fallback: `b2c job log JOB_ID EXECUTION_ID`.
29
29
  The returned log path is evidence to guide lookup, not
30
30
  permission to read an arbitrary local path. Do not infer root cause from ERROR alone.
31
+
32
+ ## Start a job
33
+
34
+ Code mode can start and wait for jobs (SCAPI only); no terminal is needed. Confirm the
35
+ intent, check for an active run of the same job (`builtin/job-execution-review` with
36
+ `jobId`), and never rerun a job just to inspect it.
37
+
38
+ `createJobExecution` is `POST /operation/jobs/v1/organizations/{organizationId}/jobs/{jobId}/executions`
39
+ (scope `sfcc.jobs.rw`). The body depends on the job:
40
+
41
+ | Job kind | Body |
42
+ | --------------------------------------------------------------------------- | ------------------------------------------- |
43
+ | Custom jobs / standard steps with parameters | `{"parameters":[{"name":"P","value":"v"}]}` |
44
+ | `sfcc-search-index-{product,content,active-data}-{full,incremental}-update` | `{"site_scope":["SiteId"]}` |
45
+
46
+ System jobs do not accept `parameters`, and the bundled spec only lists `parameters`,
47
+ so it is not authoritative for them. Fields are snake_case and `site_scope` is an array
48
+ of site IDs (not an object, not camelCase). Search-index rebuild example:
49
+
50
+ ```js
51
+ async () => {
52
+ const base =
53
+ '/operation/jobs/v1/organizations/{organizationId}/jobs/sfcc-search-index-product-full-update/executions';
54
+ const start = await scapi.request({method: 'POST', path: base, body: {site_scope: ['MySite']}});
55
+ if (!start.ok) return start;
56
+ let ex = start.data;
57
+ for (let i = 0; i < 20 && ['pending', 'running'].includes(ex.executionStatus); i++) {
58
+ await new Promise((r) => setTimeout(r, 3000));
59
+ const r = await scapi.request({method: 'GET', path: base + '/' + ex.id});
60
+ if (!r.ok) return r;
61
+ ex = r.data;
62
+ }
63
+ return {id: ex.id, executionStatus: ex.executionStatus, exitStatus: ex.exitStatus, logFilePath: ex.logFilePath};
64
+ };
65
+ ```
66
+
67
+ If it is still running, report the execution ID and check later with
68
+ `builtin/job-execution-inspect`. A `JobAlreadyRunningException` (400) means wait for the
69
+ active run. After an index rebuild, verify with a Shopper Search query; a new product
70
+ also needs to be online, orderable/in stock, and assigned to a category in the site catalog.
71
+ OCAPI equivalent for CLI use: same body at `POST /jobs/{job_id}/executions`
72
+ (`b2c job run ID --body '...'`).
@@ -0,0 +1,28 @@
1
+ # Reusable workflows
2
+
3
+ Find workflows with `codemode.search(query)`; `codemode.describe(name)`
4
+ returns source/inputSchema. Inspect before first use; `codemode.run(name, input)`
5
+ composes inside execution with shared limits/auth/safety. `builtin/` ships with
6
+ the MCP; `user/` persists locally. [Catalog](snippets.md).
7
+
8
+ Reuse a snippet when its inputs and verification cover the task. Otherwise adapt
9
+ its source or compose direct requests; do not omit requested fields to fit a
10
+ snippet. Inputs are schema-validated before invocation. Pass variable values
11
+ through the tool's `input` to `async (input)` when preparing reusable code.
12
+ Discover/describe inside either code tool; run snippets only inside `scapi_execute`.
13
+ Saving requires an explicit user request and a reviewed outcome; a completed
14
+ execution may still contain HTTP errors or partial failures.
15
+
16
+ - [Products](products.md): create, optionally assign a storefront category, verify both.
17
+ - [Promotions](promotions.md): join assignments/details in bounded batches.
18
+ - [Jobs](jobs.md): review runs, inspect steps/logs, investigate failures.
19
+
20
+ For explicit save requests, see [saving](saving.md).
21
+
22
+ No CLI code-mode equivalent. For missing settings such as promotion discounts,
23
+ consider [XML archives](skill://b2c-cli/b2c-site-import-export/SKILL.md)
24
+ (`docs_read({query: "cli-jobs"})`, [online](https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/jobs.md)).
25
+ [Platform reference](https://developer.salesforce.com/docs/commerce/commerce-api/references).
26
+ Configuration/access: `docs_read({query: "mcp-configuration"})` ([online](https://salesforcecommercecloud.github.io/b2c-developer-tooling/mcp/configuration.md)).
27
+
28
+ Other MCP workflows and runbooks: [skill index](skill://mcp/b2c-mcp-server/SKILL.md#skill-index).
@@ -19,6 +19,7 @@ Read only the skill that matches the task; each links its own references.
19
19
  | Production incident or unknown operational signal | `skill://b2c-ops/b2c-production-triage/SKILL.md` |
20
20
  | Failed or late jobs | `skill://b2c-ops/b2c-job-health/SKILL.md` |
21
21
  | Checkout or order failures | `skill://b2c-ops/b2c-checkout-triage/SKILL.md`, `skill://b2c-ops/b2c-order-failure-triage/SKILL.md` |
22
+ | Bots, scrapers or abusive traffic at the eCDN (WAF, firewall, rate limits) | `skill://b2c-ops/b2c-edge-traffic-triage/SKILL.md` |
22
23
  | Anything else | `skill://index` |
23
24
 
24
25
  Every skill and reference file is readable as an MCP resource
@@ -99,7 +100,9 @@ Use a skill's listed name or URI; do not derive names from the server name.
99
100
  Relative links resolve against the linking skill's directory.
100
101
  Skills cite documentation IDs as `b2c docs read <id>` or `docs_read({query: "<id>"})`;
101
102
  read them with `docs_read({query: "<id>"})` (no terminal needed). Online links
102
- point to the same pages as Markdown.
103
+ point to the same pages as Markdown. Doc IDs are lookup keys: when citing
104
+ sources to the user, link the doc's `url` from `docs_read`, unless they ask for
105
+ IDs or Markdown links (`sourceUrl`).
103
106
  Result `skillReferences` point to optional detail for observed conditions:
104
107
  read the URI, or pass its URI and `section` to `skills_read`. Skills are
105
108
  directory-agnostic.