@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":
|
|
2077
|
-
"digest": "sha256:
|
|
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":
|
|
2117
|
-
"digest": "sha256:
|
|
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
|
-
-
|
|
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
|
-
//
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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,
|
package/oclif.manifest.json
CHANGED
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
|
+
"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.
|
|
84
|
+
"@salesforce/b2c-tooling-sdk": "2.6.0"
|
|
85
85
|
},
|
|
86
86
|
"bundledDependencies": [
|
|
87
87
|
"@modelcontextprotocol/server",
|