@salesforce/b2c-dx-mcp 3.4.0 → 3.5.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.
@@ -2073,8 +2073,8 @@
2073
2073
  },
2074
2074
  {
2075
2075
  "path": "references/discover.md",
2076
- "bytes": 8497,
2077
- "digest": "sha256:b621643189beba4489a38587a7cbf3304e69139f048a962740d294fb0885a0d6"
2076
+ "bytes": 9083,
2077
+ "digest": "sha256:d11d646cd9c08b617e6043bb51d7e4dbdbb026af15ba11a951bbe3168eadcc9f"
2078
2078
  },
2079
2079
  {
2080
2080
  "path": "references/jobs.md",
@@ -2113,8 +2113,8 @@
2113
2113
  },
2114
2114
  {
2115
2115
  "path": "SKILL.md",
2116
- "bytes": 5929,
2117
- "digest": "sha256:c192bf8e28d9b975686386e167e15aee926a7aad723a4304d9a372ccbe1e7c72"
2116
+ "bytes": 6549,
2117
+ "digest": "sha256:671e0b5337b0a1794587115771fa7fa27d5db9b6974ab293998622c1e4766812"
2118
2118
  }
2119
2119
  ],
2120
2120
  "featured": true
@@ -19,7 +19,11 @@ declare const spec: {
19
19
  apis: Array<{id: string; apiFamily: string; apiName: string; apiVersion: string; status: string}>; // id: 'product/catalogs/v1'
20
20
  paths: Record<string, Record<string, Operation>>; // fullPath -> lowercase method -> op
21
21
  resolve(value: unknown, apiId: string): unknown; // expand local $ref
22
+ // ranked fuzzy search over summary/description/tags/operationId/path; newest API version only
23
+ search(query: string, o?: {limit?: number}): Promise<Array<Match>>; // limit default 10, max 50
22
24
  };
25
+ // spec.paths[m.path][m.method] is the full op; otherVersions = older versions with the same op
26
+ type Match = {api: string; method: string; path: string; operationId?: string; summary?: string; score: number; otherVersions?: string[]};
23
27
  // fullPath = '/' + api id + path, e.g. '/product/catalogs/v1/organizations/{organizationId}/catalogs/{catalogId}'
24
28
  interface Operation {
25
29
  api: string;
@@ -53,7 +57,7 @@ declare const scapi: {
53
57
  ## Rules
54
58
 
55
59
  - 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.
60
+ - Start with `await spec.search('task words')`; it matches prose (`summary`, `description`, `tags`) and tolerates typos. Regex over `spec.paths` to narrow or enumerate.
57
61
  - `scapi_search` default `detail:"outline"` drops nested descriptions/examples. `detail:"full"` restores. Execute sees full.
58
62
  - 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
63
  - `scapi.request` auths itself. Never fetch tokens first. Path `{organizationId}` auto-fills.
@@ -62,7 +66,10 @@ declare const scapi: {
62
66
  - Write needing approval pauses for client elicitation. Decline = whole run ends. Never fake approval.
63
67
 
64
68
  ```js
65
- // list candidates by prose
69
+ // rank candidates by prose (await it)
70
+ async () => spec.search('apply coupon to basket', {limit: 8});
71
+
72
+ // enumerate with a filter
66
73
  async () =>
67
74
  Object.entries(spec.paths)
68
75
  .flatMap(([path, methods]) =>
@@ -1,7 +1,8 @@
1
1
  # SCAPI discovery, result limits and tenant schemas
2
2
 
3
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
4
+ search the prose as well as `operationId` and path. `await spec.search(query, {limit})` does this for you: it ranks
5
+ operations across all of those fields, tolerates typos, and is the quickest way to find an unfamiliar API. Descriptions are long: return `op.summary` when listing
5
6
  candidates, and read `op.description` only for the operations you are about to call.
6
7
 
7
8
  `scapi_search` returns each operation as an outline by default: its own `summary`, `description` and `tags`, with
@@ -11,11 +12,15 @@ sees full operations). Results are capped at 24 KB of JSON for both tools (`SCAP
11
12
  typically 6-20 KB and some exceed the cap alone, so never return `op` or `spec.paths` entries unprojected: list
12
13
  `{operationId, method, path, summary}`, then return only `parameters` or `requestBody` for the operations you will call.
13
14
 
14
- The `spec` object has exactly three members; there is no `spec.schemas` and no need to probe it:
15
+ The `spec` object has exactly four members; there is no `spec.schemas` and no need to probe it:
15
16
 
16
17
  - `spec.apis`: array of `{id, apiFamily, apiName, apiVersion, status, origin?}` (`id` is e.g. `product/catalogs/v1`).
17
18
  - `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
19
  - `spec.resolve(value, apiId)`: expands local `$ref`s in a fragment.
20
+ - `spec.search(query, {limit})`: resolves to ranked `{api, method, path, operationId, summary, score, otherVersions?}`
21
+ matches (default 10, at most 50). `spec.paths[match.path][match.method]` is the operation. Versions of one API
22
+ collapse into the newest, with older ones in `otherVersions`. It searches the same contracts as `spec.paths`, so
23
+ `api`, `authType` and `schemas: "live"` apply.
19
24
 
20
25
  ## Discover
21
26
 
@@ -32,7 +37,7 @@ developer-supplied beta contracts (dw.json `scapi-schemas`, `SFCC_SCAPI_SCHEMAS`
32
37
  execution. Schemas and responses can be huge.
33
38
  Return only what the next decision needs:
34
39
 
35
- 1. Find APIs/operations through `spec.apis`/`spec.paths`; return method/path/operationId.
40
+ 1. Find operations with `spec.search`, or enumerate `spec.apis`/`spec.paths`; return method/path/operationId.
36
41
  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
42
  including `allOf` when present.
38
43
  3. Inspect response fields only as needed; avoid whole operations/schema trees.
@@ -26,7 +26,7 @@ function requireScapiSkill(read) {
26
26
  if (read !== true)
27
27
  throw new Error(SCAPI_SKILL_REQUIRED);
28
28
  }
29
- const searchDescription = `Requires reading skill://mcp/b2c-mcp-scapi/SKILL.md first. Search SCAPI Admin/Shopper OpenAPI contracts by running JavaScript over \`spec\` (only spec.apis, spec.paths[fullPath][method] and spec.resolve exist), to find the operationId, path, inputs and scopes for a Commerce API task when no dedicated tool fits. Use cip_* for analytics and webdav_* for files. Searches the bundled contracts by default (offline, no credentials); schemas:"live" fetches the current contracts from the configured instance instead, including tenant c_* fields, custom APIs and APIs newer than the bundle (falls back to the bundled contracts with a warning when live access fails). Operations carry summary, description and tags: match on those, not only operationId. Results are capped at 24 KB: operations are an outline by default (no nested descriptions or examples; detail:"full" restores them), and you should still return fields such as operationId, method, path and summary, not whole operations.`;
29
+ const searchDescription = `Requires reading skill://mcp/b2c-mcp-scapi/SKILL.md first. Search SCAPI Admin/Shopper OpenAPI contracts by running JavaScript over \`spec\` (only spec.apis, spec.paths[fullPath][method], spec.resolve and spec.search exist), to find the operationId, path, inputs and scopes for a Commerce API task when no dedicated tool fits. Use cip_* for analytics and webdav_* for files. Searches the bundled contracts by default (offline, no credentials); schemas:"live" fetches the current contracts from the configured instance instead, including tenant c_* fields, custom APIs and APIs newer than the bundle (falls back to the bundled contracts with a warning when live access fails). Start with await spec.search("words for the task"): it ranks operations across summary, description, tags, operationId and path, tolerates typos, and returns {api, method, path, operationId, summary} that index spec.paths. Use regex filters over spec.paths to narrow further. Results are capped at 24 KB: operations are an outline by default (no nested descriptions or examples; detail:"full" restores them), and you should still return fields such as operationId, method, path and summary, not whole operations.`;
30
30
  const executeDescription = `Requires reading skill://mcp/b2c-mcp-scapi/SKILL.md first. Run any SCAPI Admin or Shopper API operation (reads, writes, searches and actions) through scapi.request() in JavaScript. Covers most developer, merchant and administrator tasks: catalogs, products, pricing, promotions, orders, customers, inventory, sites, jobs, code versions, observability, and storefront flows such as baskets. Use it whenever no more specific tool fits. Find operations with scapi_search first. Auth is automatic; Shopper calls run as a per-site guest whose basket persists. Operations are governed by Safety Mode and may ask the user for confirmation.`;
31
31
  function codeResult(data, resolution) {
32
32
  const result = resolution ? attachResolution(jsonResult(data, 0), resolution, 0) : jsonResult(data, 0);
@@ -249,6 +249,9 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
249
249
  services.getEnvironmentVariable(name),
250
250
  ]));
251
251
  return await registry.start(input, context, async (execution) => {
252
+ // Live contracts discovered for this tenant replace bundled ones, and local ones replace both;
253
+ // the user owns their accuracy. The same set backs spec in the program and request matching.
254
+ const documents = mergeScapiSchemas(loadScapiSchemas(), tenant ? schemaCache.get(tenant) : [], localDocuments);
252
255
  let managedRequest;
253
256
  const request = async (options, signal) => {
254
257
  if (!shortCode || !tenantId)
@@ -265,9 +268,7 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
265
268
  slasClientId: config.values.slasClientId,
266
269
  slasClientSecret: config.values.slasClientSecret,
267
270
  }),
268
- // Live contracts discovered for this tenant replace bundled ones, and local ones replace both;
269
- // the user owns their accuracy.
270
- documents: mergeScapiSchemas(loadScapiSchemas(), tenant ? schemaCache.get(tenant) : [], localDocuments),
271
+ documents,
271
272
  onSchema(document, full) {
272
273
  // Keep full tenant contracts (custom properties and prose) from being replaced by lighter fetches.
273
274
  if (tenant && (full || document.entry.apiFamily === 'custom'))
@@ -283,6 +284,7 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
283
284
  try {
284
285
  const result = await runScapiCode({
285
286
  code: input.code,
287
+ documents,
286
288
  request: (options, signal) => execution.runCall('request', options, () => request(options, signal)),
287
289
  auth: (operation, options, signal) => execution.runCall('auth', undefined, () => auth(operation, options, signal)),
288
290
  organizationId: tenantId ? toOrganizationId(tenantId) : undefined,
@@ -493,5 +493,5 @@
493
493
  "enableJsonFlag": false
494
494
  }
495
495
  },
496
- "version": "3.4.0"
496
+ "version": "3.5.0"
497
497
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@salesforce/b2c-dx-mcp",
3
3
  "description": "MCP server for B2C Commerce developer experience tools",
4
- "version": "3.4.0",
4
+ "version": "3.5.0",
5
5
  "author": "Salesforce",
6
6
  "license": "Apache-2.0",
7
7
  "repository": "SalesforceCommerceCloud/b2c-developer-tooling",
@@ -81,7 +81,7 @@
81
81
  "yaml": "2.9.0",
82
82
  "zod": "4.5.4",
83
83
  "@salesforce/b2c-agent-plugins": "1.12.0",
84
- "@salesforce/b2c-tooling-sdk": "2.5.0"
84
+ "@salesforce/b2c-tooling-sdk": "2.6.0"
85
85
  },
86
86
  "bundledDependencies": [
87
87
  "@modelcontextprotocol/server",