@salesforce/b2c-dx-mcp 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -27
- package/content/page-designer.md +4 -4
- package/dist/commands/mcp.d.ts +12 -0
- package/dist/commands/mcp.js +16 -4
- package/dist/registry.d.ts +4 -4
- package/dist/registry.js +10 -10
- package/dist/services.d.ts +75 -1
- package/dist/services.js +124 -1
- package/dist/tools/adapter.d.ts +29 -21
- package/dist/tools/adapter.js +34 -24
- package/dist/tools/cartridges/index.d.ts +5 -3
- package/dist/tools/cartridges/index.js +55 -25
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/mrt/index.d.ts +2 -2
- package/dist/tools/mrt/index.js +29 -10
- package/dist/tools/page-designer-decorator/analyzer.d.ts +169 -0
- package/dist/tools/page-designer-decorator/analyzer.js +535 -0
- package/dist/tools/page-designer-decorator/index.d.ts +252 -0
- package/dist/tools/page-designer-decorator/index.js +597 -0
- package/dist/tools/page-designer-decorator/rules/1-mode-selection.d.ts +8 -0
- package/dist/tools/page-designer-decorator/rules/1-mode-selection.js +65 -0
- package/dist/tools/page-designer-decorator/rules/2a-auto-mode.d.ts +13 -0
- package/dist/tools/page-designer-decorator/rules/2a-auto-mode.js +87 -0
- package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.d.ts +4 -0
- package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.js +55 -0
- package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.d.ts +22 -0
- package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.js +109 -0
- package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.d.ts +21 -0
- package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.js +60 -0
- package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.d.ts +27 -0
- package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.js +68 -0
- package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.d.ts +4 -0
- package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.js +65 -0
- package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.d.ts +11 -0
- package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.js +92 -0
- package/dist/tools/page-designer-decorator/rules.d.ts +51 -0
- package/dist/tools/page-designer-decorator/rules.js +70 -0
- package/dist/tools/page-designer-decorator/templates/decorator-generator.d.ts +116 -0
- package/dist/tools/page-designer-decorator/templates/decorator-generator.js +350 -0
- package/dist/tools/pwav3/index.d.ts +2 -2
- package/dist/tools/pwav3/index.js +13 -13
- package/dist/tools/scapi/index.d.ts +10 -2
- package/dist/tools/scapi/index.js +5 -56
- package/dist/tools/scapi/scapi-custom-apis-status.d.ts +9 -0
- package/dist/tools/scapi/scapi-custom-apis-status.js +152 -0
- package/dist/tools/scapi/scapi-schemas-list.d.ts +12 -0
- package/dist/tools/scapi/scapi-schemas-list.js +248 -0
- package/dist/tools/storefrontnext/developer-guidelines.d.ts +2 -2
- package/dist/tools/storefrontnext/developer-guidelines.js +3 -3
- package/dist/tools/storefrontnext/index.d.ts +2 -2
- package/dist/tools/storefrontnext/index.js +13 -13
- package/oclif.manifest.json +13 -2
- package/package.json +10 -5
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Services } from '../../services.js';
|
|
2
|
+
import type { McpTool } from '../../utils/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the scapi_custom_apis_status tool.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors CLI: b2c scapi custom status. All flags supported; agent chooses what to use.
|
|
7
|
+
* See: https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/custom-apis.html#b2c-scapi-custom-status
|
|
8
|
+
*/
|
|
9
|
+
export declare function createScapiCustomApisStatusTool(loadServices: () => Services): McpTool;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* SCAPI Custom API Status tool.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors CLI: b2c scapi custom status. All CLI flags are supported; let the agent decide what to use.
|
|
10
|
+
* Returns raw endpoints from the API (no roll-up). Remote only.
|
|
11
|
+
*
|
|
12
|
+
* @module tools/scapi/scapi-custom-apis-status
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { createToolAdapter, jsonResult } from '../adapter.js';
|
|
16
|
+
import { getApiErrorMessage } from '@salesforce/b2c-tooling-sdk/clients';
|
|
17
|
+
import { getApiType } from '@salesforce/b2c-tooling-sdk/schemas';
|
|
18
|
+
// MCP-specific default columns (includes siteId since MCP returns raw endpoints per site)
|
|
19
|
+
const DEFAULT_COLUMNS = ['type', 'apiName', 'cartridgeName', 'endpointPath', 'httpMethod', 'status', 'siteId'];
|
|
20
|
+
function pickColumns(endpoint, columns) {
|
|
21
|
+
const out = {};
|
|
22
|
+
for (const key of columns) {
|
|
23
|
+
if (key in endpoint && endpoint[key] !== undefined) {
|
|
24
|
+
out[key] = endpoint[key];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
function buildColumnList(args) {
|
|
30
|
+
// If columns specified, use those; otherwise use defaults (saves tokens)
|
|
31
|
+
if (args.columns?.trim()) {
|
|
32
|
+
return args.columns
|
|
33
|
+
.split(',')
|
|
34
|
+
.map((c) => c.trim())
|
|
35
|
+
.filter(Boolean);
|
|
36
|
+
}
|
|
37
|
+
return [...DEFAULT_COLUMNS];
|
|
38
|
+
}
|
|
39
|
+
function buildResponse(withMeta, args, columnList, activeCodeVersion) {
|
|
40
|
+
// Always filter to requested columns (saves tokens by not returning unused fields)
|
|
41
|
+
const toOutput = (e) => pickColumns(e, columnList);
|
|
42
|
+
if (args.groupBy) {
|
|
43
|
+
const groups = {};
|
|
44
|
+
if (args.groupBy === 'type') {
|
|
45
|
+
for (const endpoint of withMeta) {
|
|
46
|
+
const type = endpoint.type ?? '-';
|
|
47
|
+
if (!groups[type])
|
|
48
|
+
groups[type] = [];
|
|
49
|
+
groups[type].push(toOutput(endpoint));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
for (const endpoint of withMeta) {
|
|
54
|
+
const site = endpoint.siteId ?? 'Global';
|
|
55
|
+
if (!groups[site])
|
|
56
|
+
groups[site] = [];
|
|
57
|
+
groups[site].push(toOutput(endpoint));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
groups,
|
|
62
|
+
total: withMeta.length,
|
|
63
|
+
activeCodeVersion,
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
message: withMeta.length === 0 ? 'No Custom API endpoints found.' : `Found ${withMeta.length} endpoint(s).`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
endpoints: withMeta.map((e) => toOutput(e)),
|
|
70
|
+
total: withMeta.length,
|
|
71
|
+
activeCodeVersion,
|
|
72
|
+
timestamp: new Date().toISOString(),
|
|
73
|
+
message: withMeta.length === 0 ? 'No Custom API endpoints found.' : `Found ${withMeta.length} endpoint(s).`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates the scapi_custom_apis_status tool.
|
|
78
|
+
*
|
|
79
|
+
* Mirrors CLI: b2c scapi custom status. All flags supported; agent chooses what to use.
|
|
80
|
+
* See: https://salesforcecommercecloud.github.io/b2c-developer-tooling/cli/custom-apis.html#b2c-scapi-custom-status
|
|
81
|
+
*/
|
|
82
|
+
export function createScapiCustomApisStatusTool(loadServices) {
|
|
83
|
+
return createToolAdapter({
|
|
84
|
+
name: 'scapi_custom_apis_status',
|
|
85
|
+
description: `List Custom SCAPI endpoint registration status (active/not_registered). Returns one row per endpoint per site. For schemas, use scapi_schemas_list with apiFamily: "custom".
|
|
86
|
+
|
|
87
|
+
Use cases: Check endpoint status, verify deployment, get per-site details. Use status: "active" to filter, groupBy: "site" to group, columns: "field1,field2" for specific fields, or omit columns for defaults.
|
|
88
|
+
|
|
89
|
+
Output: Default (7 fields): type,apiName,cartridgeName,endpointPath,httpMethod,status,siteId. All fields: type,apiName,apiVersion,cartridgeName,endpointPath,httpMethod,status,siteId,securityScheme,operationId,schemaFile,implementationScript,errorReason,id.
|
|
90
|
+
|
|
91
|
+
Requires OAuth (sfcc.custom-apis scope) and instance config (shortCode, tenantId). Returns remoteError on failure.
|
|
92
|
+
|
|
93
|
+
CLI: b2c scapi custom status`,
|
|
94
|
+
toolsets: ['PWAV3', 'SCAPI', 'STOREFRONTNEXT'],
|
|
95
|
+
isGA: false,
|
|
96
|
+
requiresInstance: false,
|
|
97
|
+
inputSchema: {
|
|
98
|
+
status: z.enum(['active', 'not_registered']).optional().describe('Filter by status. Omit for all.'),
|
|
99
|
+
groupBy: z.enum(['site', 'type']).optional().describe('Group by siteId or type (Admin/Shopper).'),
|
|
100
|
+
columns: z
|
|
101
|
+
.string()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('Comma-separated fields. Omit for defaults (7 fields). All fields: type,apiName,apiVersion,cartridgeName,endpointPath,httpMethod,status,siteId,securityScheme,operationId,schemaFile,implementationScript,errorReason,id'),
|
|
104
|
+
},
|
|
105
|
+
async execute(args, { services: svc }) {
|
|
106
|
+
let endpoints = [];
|
|
107
|
+
let activeCodeVersion;
|
|
108
|
+
let remoteError;
|
|
109
|
+
try {
|
|
110
|
+
const client = svc.getCustomApisClient();
|
|
111
|
+
const organizationId = svc.getOrganizationId();
|
|
112
|
+
// Call Custom APIs DX API: list endpoints for this org, optional status filter.
|
|
113
|
+
const { data, error, response } = await client.GET('/organizations/{organizationId}/endpoints', {
|
|
114
|
+
params: {
|
|
115
|
+
path: { organizationId },
|
|
116
|
+
query: args.status ? { status: args.status } : undefined,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
if (error) {
|
|
120
|
+
remoteError = `Failed to fetch remote endpoints: ${getApiErrorMessage(error, response)}`;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
endpoints = data?.data ?? [];
|
|
124
|
+
activeCodeVersion = data?.activeCodeVersion;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
// Network/config errors: capture message for remoteError and return below.
|
|
129
|
+
remoteError = error instanceof Error ? error.message : 'Unknown error fetching remote endpoints';
|
|
130
|
+
}
|
|
131
|
+
// On any remote failure, return early with error details (no endpoints).
|
|
132
|
+
if (remoteError) {
|
|
133
|
+
return {
|
|
134
|
+
total: 0,
|
|
135
|
+
activeCodeVersion,
|
|
136
|
+
remoteError,
|
|
137
|
+
timestamp: new Date().toISOString(),
|
|
138
|
+
message: `Failed to fetch Custom API endpoints: ${remoteError}. Check OAuth credentials and sfcc.custom-apis scope.`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// Add type to each endpoint (no roll-up)
|
|
142
|
+
const withMeta = endpoints.map((e) => ({
|
|
143
|
+
...e,
|
|
144
|
+
type: getApiType(e.securityScheme),
|
|
145
|
+
}));
|
|
146
|
+
const columnList = buildColumnList(args);
|
|
147
|
+
return buildResponse(withMeta, args, columnList, activeCodeVersion);
|
|
148
|
+
},
|
|
149
|
+
formatOutput: (output) => jsonResult(output),
|
|
150
|
+
}, loadServices);
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=scapi-custom-apis-status.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Services } from '../../services.js';
|
|
2
|
+
import type { McpTool } from '../../utils/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the scapi_schemas_list tool.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors CLI: b2c scapi schemas list (discovery) and b2c scapi schemas get (fetch).
|
|
7
|
+
* Lists or fetches SCAPI schema specifications; includes standard SCAPI and custom API as schema types.
|
|
8
|
+
*
|
|
9
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
10
|
+
* @returns MCP tool for listing/fetching SCAPI schemas
|
|
11
|
+
*/
|
|
12
|
+
export declare function createScapiSchemasListTool(loadServices: () => Services): McpTool;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* SCAPI Schemas List tool.
|
|
8
|
+
*
|
|
9
|
+
* Lists available SCAPI schemas with optional filtering by apiFamily, apiName, apiVersion, and status.
|
|
10
|
+
* Optionally fetches full OpenAPI schemas when includeSchemas=true is provided along with all three identifiers.
|
|
11
|
+
* Matches the CLI command: b2c scapi schemas list
|
|
12
|
+
*
|
|
13
|
+
* @module tools/scapi/scapi-schemas-list
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import { createToolAdapter, jsonResult } from '../adapter.js';
|
|
17
|
+
import { getApiErrorMessage } from '@salesforce/b2c-tooling-sdk/clients';
|
|
18
|
+
import { collapseOpenApiSchema } from '@salesforce/b2c-tooling-sdk/schemas';
|
|
19
|
+
/**
|
|
20
|
+
* Builds the base URL for a SCAPI API endpoint.
|
|
21
|
+
*
|
|
22
|
+
* Constructs the base URL for making SCAPI API calls based on the instance short code,
|
|
23
|
+
* API family, API name, and version.
|
|
24
|
+
*
|
|
25
|
+
* @param shortCode - SCAPI instance short code (e.g., "kv7kzm78")
|
|
26
|
+
* @param apiFamily - API family (e.g., "shopper", "checkout", "product")
|
|
27
|
+
* @param apiName - API name (e.g., "products", "baskets", "orders")
|
|
28
|
+
* @param apiVersion - API version (e.g., "v1", "v2")
|
|
29
|
+
* @returns Full base URL for the SCAPI API
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const url = buildScapiApiUrl("kv7kzm78", "shopper", "products", "v1");
|
|
34
|
+
* // Returns: "https://kv7kzm78.api.commercecloud.salesforce.com/shopper/products/v1"
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
function buildScapiApiUrl(shortCode, apiFamily, apiName, apiVersion) {
|
|
38
|
+
return `https://${shortCode}.api.commercecloud.salesforce.com/${apiFamily}/${apiName}/${apiVersion}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetches a specific schema from the SCAPI Schemas API.
|
|
42
|
+
*
|
|
43
|
+
* @param params - Fetch parameters
|
|
44
|
+
* @param params.client - SCAPI Schemas client
|
|
45
|
+
* @param params.organizationId - Organization ID
|
|
46
|
+
* @param params.args - Input arguments with API identifiers
|
|
47
|
+
* @param params.shortCode - Optional short code for building base URL
|
|
48
|
+
* @returns Schema fetch output
|
|
49
|
+
*/
|
|
50
|
+
async function fetchSpecificSchema(params) {
|
|
51
|
+
const { client, organizationId, args, shortCode } = params;
|
|
52
|
+
const { apiFamily, apiName, apiVersion, expandAll, status } = args;
|
|
53
|
+
// Warn if status filter was provided (it's ignored in fetch mode)
|
|
54
|
+
const warning = status
|
|
55
|
+
? `Note: 'status' filter is ignored when fetching a specific schema. The API endpoint for retrieving a specific schema (${apiFamily}/${apiName}/${apiVersion}) does not support status filtering - you're already specifying the exact version. Use discovery mode (omit one or more of apiFamily/apiName/apiVersion) to filter by status.`
|
|
56
|
+
: undefined;
|
|
57
|
+
const { data, error, response } = await client.GET('/organizations/{organizationId}/schemas/{apiFamily}/{apiName}/{apiVersion}', {
|
|
58
|
+
params: {
|
|
59
|
+
path: { organizationId, apiFamily: apiFamily, apiName: apiName, apiVersion: apiVersion },
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
if (error) {
|
|
63
|
+
throw new Error(`Failed to fetch schema for ${apiFamily}/${apiName}/${apiVersion}: ${getApiErrorMessage(error, response)}`);
|
|
64
|
+
}
|
|
65
|
+
// Apply collapsing unless expandAll is requested
|
|
66
|
+
const collapsed = !expandAll;
|
|
67
|
+
const processedSchema = collapsed
|
|
68
|
+
? collapseOpenApiSchema(data)
|
|
69
|
+
: data;
|
|
70
|
+
// Build base URL for the SCAPI API (where to call the API)
|
|
71
|
+
const baseUrl = shortCode && apiFamily && apiName && apiVersion
|
|
72
|
+
? buildScapiApiUrl(shortCode, apiFamily, apiName, apiVersion)
|
|
73
|
+
: undefined;
|
|
74
|
+
return {
|
|
75
|
+
apiFamily: apiFamily,
|
|
76
|
+
apiName: apiName,
|
|
77
|
+
apiVersion: apiVersion,
|
|
78
|
+
schema: processedSchema,
|
|
79
|
+
timestamp: new Date().toISOString(),
|
|
80
|
+
collapsed,
|
|
81
|
+
warning,
|
|
82
|
+
baseUrl,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Fetches and filters schemas list from the SCAPI Schemas API.
|
|
87
|
+
*
|
|
88
|
+
* @param params - Fetch parameters
|
|
89
|
+
* @param params.client - SCAPI Schemas client
|
|
90
|
+
* @param params.organizationId - Organization ID
|
|
91
|
+
* @param params.args - Input parameters
|
|
92
|
+
* @param params.shortCode - Optional short code for building base URLs
|
|
93
|
+
* @returns Discovery mode output
|
|
94
|
+
*/
|
|
95
|
+
async function fetchSchemasList(params) {
|
|
96
|
+
const { client, organizationId, args, shortCode } = params;
|
|
97
|
+
const { data, error, response } = await client.GET('/organizations/{organizationId}/schemas', {
|
|
98
|
+
params: {
|
|
99
|
+
path: { organizationId },
|
|
100
|
+
query: {
|
|
101
|
+
apiFamily: args.apiFamily,
|
|
102
|
+
apiName: args.apiName,
|
|
103
|
+
apiVersion: args.apiVersion,
|
|
104
|
+
status: args.status,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
if (error) {
|
|
109
|
+
throw new Error(`Failed to fetch SCAPI schemas: ${getApiErrorMessage(error, response)}`);
|
|
110
|
+
}
|
|
111
|
+
const schemas = data?.data ?? [];
|
|
112
|
+
const filteredSchemas = prepareSchemaListForConsumer(schemas, shortCode);
|
|
113
|
+
const discoveryMetadata = getAvailableFilters(schemas);
|
|
114
|
+
// Generate helpful message for empty results
|
|
115
|
+
const message = schemas.length === 0 ? generateEmptyResultMessage(args) : undefined;
|
|
116
|
+
return {
|
|
117
|
+
schemas: filteredSchemas,
|
|
118
|
+
total: data?.total ?? schemas.length,
|
|
119
|
+
timestamp: new Date().toISOString(),
|
|
120
|
+
...discoveryMetadata,
|
|
121
|
+
message,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Generates helpful message when no schemas are found.
|
|
126
|
+
*/
|
|
127
|
+
function generateEmptyResultMessage(args) {
|
|
128
|
+
const hasFilters = args.apiFamily || args.apiName || args.apiVersion || args.status;
|
|
129
|
+
if (hasFilters) {
|
|
130
|
+
const activeFilters = [];
|
|
131
|
+
if (args.apiFamily)
|
|
132
|
+
activeFilters.push(`apiFamily="${args.apiFamily}"`);
|
|
133
|
+
if (args.apiName)
|
|
134
|
+
activeFilters.push(`apiName="${args.apiName}"`);
|
|
135
|
+
if (args.apiVersion)
|
|
136
|
+
activeFilters.push(`apiVersion="${args.apiVersion}"`);
|
|
137
|
+
if (args.status)
|
|
138
|
+
activeFilters.push(`status="${args.status}"`);
|
|
139
|
+
return `No SCAPI schemas match the filters: ${activeFilters.join(', ')}. Try removing some filters or check the filter values. Use discovery mode without filters to see all available schemas.`;
|
|
140
|
+
}
|
|
141
|
+
return 'No SCAPI schemas available. This could indicate: (1) Invalid tenant ID or organization ID, (2) Missing OAuth scopes (requires sfcc.scapi-schemas), or (3) No schemas published for this organization. Verify your credentials and tenant configuration.';
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Prepares schema list for consumer: strips link, adds baseUrl when shortCode provided.
|
|
145
|
+
*/
|
|
146
|
+
function prepareSchemaListForConsumer(schemas, shortCode) {
|
|
147
|
+
return schemas.map((item) => {
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
149
|
+
const { link, ...rest } = item;
|
|
150
|
+
const baseUrl = shortCode && item.apiFamily && item.apiName && item.apiVersion
|
|
151
|
+
? buildScapiApiUrl(shortCode, item.apiFamily, item.apiName, item.apiVersion)
|
|
152
|
+
: undefined;
|
|
153
|
+
return { ...rest, baseUrl };
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Extracts unique filter values (apiFamily, apiName, apiVersion) from a schema list.
|
|
158
|
+
*/
|
|
159
|
+
function getAvailableFilters(schemas) {
|
|
160
|
+
if (schemas.length === 0) {
|
|
161
|
+
return {};
|
|
162
|
+
}
|
|
163
|
+
const availableApiFamilies = [
|
|
164
|
+
...new Set(schemas.map((s) => s.apiFamily).filter((v) => v !== undefined)),
|
|
165
|
+
].sort();
|
|
166
|
+
const availableApiNames = [
|
|
167
|
+
...new Set(schemas.map((s) => s.apiName).filter((v) => v !== undefined)),
|
|
168
|
+
].sort();
|
|
169
|
+
const availableVersions = [
|
|
170
|
+
...new Set(schemas.map((s) => s.apiVersion).filter((v) => v !== undefined)),
|
|
171
|
+
].sort();
|
|
172
|
+
return {
|
|
173
|
+
availableApiFamilies: availableApiFamilies.length > 0 ? availableApiFamilies : undefined,
|
|
174
|
+
availableApiNames: availableApiNames.length > 0 ? availableApiNames : undefined,
|
|
175
|
+
availableVersions: availableVersions.length > 0 ? availableVersions : undefined,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Creates the scapi_schemas_list tool.
|
|
180
|
+
*
|
|
181
|
+
* Mirrors CLI: b2c scapi schemas list (discovery) and b2c scapi schemas get (fetch).
|
|
182
|
+
* Lists or fetches SCAPI schema specifications; includes standard SCAPI and custom API as schema types.
|
|
183
|
+
*
|
|
184
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
185
|
+
* @returns MCP tool for listing/fetching SCAPI schemas
|
|
186
|
+
*/
|
|
187
|
+
export function createScapiSchemasListTool(loadServices) {
|
|
188
|
+
return createToolAdapter({
|
|
189
|
+
name: 'scapi_schemas_list',
|
|
190
|
+
description: `List or fetch SCAPI schema metadata and OpenAPI specs for standard SCAPI (Shop/Admin/Shopper) and custom APIs (apiFamily: "custom"). For endpoint registration status, use scapi_custom_apis_status.
|
|
191
|
+
|
|
192
|
+
**Modes:**
|
|
193
|
+
- **List (discovery):** Omit includeSchemas or any identifier. Returns metadata: schemas[], total, availableApiFamilies/Names/Versions.
|
|
194
|
+
- **Fetch:** Set includeSchemas=true + all three: apiFamily, apiName, apiVersion. Returns full OpenAPI schema (collapsed by default; set expandAll=true for full).
|
|
195
|
+
|
|
196
|
+
**Rules:** includeSchemas requires all three identifiers. status only works in list mode (use "current" for active schemas, "deprecated" for phased-out schemas). Custom APIs use apiFamily: "custom".
|
|
197
|
+
|
|
198
|
+
**Requirements:** OAuth with sfcc.scapi-schemas scope.`,
|
|
199
|
+
toolsets: ['PWAV3', 'SCAPI', 'STOREFRONTNEXT'],
|
|
200
|
+
isGA: false,
|
|
201
|
+
requiresInstance: false, // SCAPI uses OAuth directly, doesn't need B2CInstance (hostname)
|
|
202
|
+
inputSchema: {
|
|
203
|
+
apiFamily: z.string().optional().describe('API family (e.g., "checkout", "product", "custom").'),
|
|
204
|
+
apiName: z.string().optional().describe('API name (e.g., "shopper-baskets", "shopper-products").'),
|
|
205
|
+
apiVersion: z.string().optional().describe('API version (e.g., "v1", "v2").'),
|
|
206
|
+
status: z
|
|
207
|
+
.enum(['current', 'deprecated'])
|
|
208
|
+
.optional()
|
|
209
|
+
.describe('Filter by status (list mode only). Omit to return all schemas.'),
|
|
210
|
+
includeSchemas: z
|
|
211
|
+
.boolean()
|
|
212
|
+
.default(false)
|
|
213
|
+
.describe('Fetch full OpenAPI schema. Requires apiFamily+apiName+apiVersion. Default: false.'),
|
|
214
|
+
expandAll: z
|
|
215
|
+
.boolean()
|
|
216
|
+
.default(false)
|
|
217
|
+
.describe('Return full uncompressed schema. Only when includeSchemas=true. Default: false.'),
|
|
218
|
+
},
|
|
219
|
+
async execute(args, { services: svc }) {
|
|
220
|
+
// Get client and organization ID
|
|
221
|
+
const client = svc.getScapiSchemasClient();
|
|
222
|
+
const organizationId = svc.getOrganizationId();
|
|
223
|
+
// Get shortCode for building base URLs (optional)
|
|
224
|
+
let shortCode;
|
|
225
|
+
try {
|
|
226
|
+
shortCode = svc.getShortCode();
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Continue without shortCode if not available
|
|
230
|
+
}
|
|
231
|
+
// Determine operation mode
|
|
232
|
+
const hasAllIdentifiers = Boolean(args.apiFamily && args.apiName && args.apiVersion);
|
|
233
|
+
const isFetchMode = hasAllIdentifiers && args.includeSchemas;
|
|
234
|
+
// Validate includeSchemas flag
|
|
235
|
+
if (args.includeSchemas && !hasAllIdentifiers) {
|
|
236
|
+
throw new Error('includeSchemas=true requires all three identifiers: apiFamily, apiName, and apiVersion. ' +
|
|
237
|
+
'Please provide all three to fetch a specific schema, or omit includeSchemas to discover available schemas.');
|
|
238
|
+
}
|
|
239
|
+
// Execute appropriate mode
|
|
240
|
+
if (isFetchMode) {
|
|
241
|
+
return fetchSpecificSchema({ client, organizationId, args, shortCode });
|
|
242
|
+
}
|
|
243
|
+
return fetchSchemasList({ client, organizationId, args, shortCode });
|
|
244
|
+
},
|
|
245
|
+
formatOutput: (output) => jsonResult(output),
|
|
246
|
+
}, loadServices);
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=scapi-schemas-list.js.map
|
|
@@ -3,7 +3,7 @@ import type { Services } from '../../services.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates the developer guidelines tool for Storefront Next.
|
|
5
5
|
*
|
|
6
|
-
* @param
|
|
6
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
7
7
|
* @returns The configured MCP tool
|
|
8
8
|
*/
|
|
9
|
-
export declare function createDeveloperGuidelinesTool(
|
|
9
|
+
export declare function createDeveloperGuidelinesTool(loadServices: () => Services): McpTool;
|
|
@@ -77,10 +77,10 @@ const DEFAULT_SECTIONS = ['quick-reference', 'data-fetching', 'components', 'tes
|
|
|
77
77
|
/**
|
|
78
78
|
* Creates the developer guidelines tool for Storefront Next.
|
|
79
79
|
*
|
|
80
|
-
* @param
|
|
80
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
81
81
|
* @returns The configured MCP tool
|
|
82
82
|
*/
|
|
83
|
-
export function createDeveloperGuidelinesTool(
|
|
83
|
+
export function createDeveloperGuidelinesTool(loadServices) {
|
|
84
84
|
return createToolAdapter({
|
|
85
85
|
name: 'storefront_next_development_guidelines',
|
|
86
86
|
description: 'ESSENTIAL FIRST STEP for Storefront Next development. Returns critical architecture rules, coding standards, and best practices. ' +
|
|
@@ -135,6 +135,6 @@ export function createDeveloperGuidelinesTool(services) {
|
|
|
135
135
|
return fullContentInstruction + combinedContent + footerInstruction;
|
|
136
136
|
},
|
|
137
137
|
formatOutput: (output) => textResult(output),
|
|
138
|
-
},
|
|
138
|
+
}, loadServices);
|
|
139
139
|
}
|
|
140
140
|
//# sourceMappingURL=developer-guidelines.js.map
|
|
@@ -7,7 +7,7 @@ import type { Services } from '../../services.js';
|
|
|
7
7
|
* toolsets: ["MRT", "PWAV3", "STOREFRONTNEXT"] and will
|
|
8
8
|
* automatically appear in STOREFRONTNEXT.
|
|
9
9
|
*
|
|
10
|
-
* @param
|
|
10
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
11
11
|
* @returns Array of MCP tools
|
|
12
12
|
*/
|
|
13
|
-
export declare function createStorefrontNextTools(
|
|
13
|
+
export declare function createStorefrontNextTools(loadServices: () => Services): McpTool[];
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
* - `storefront_next_figma_to_component_workflow` - Convert Figma to components
|
|
17
17
|
* - `storefront_next_generate_component` - Generate new components
|
|
18
18
|
* - `storefront_next_map_tokens_to_theme` - Map design tokens
|
|
19
|
-
* - `storefront_next_design_decorator` - Apply design decorators
|
|
20
19
|
* - `storefront_next_generate_page_designer_metadata` - Generate Page Designer metadata
|
|
21
20
|
*
|
|
22
21
|
* @module tools/storefrontnext
|
|
@@ -24,6 +23,7 @@
|
|
|
24
23
|
import { z } from 'zod';
|
|
25
24
|
import { createToolAdapter, jsonResult } from '../adapter.js';
|
|
26
25
|
import { createDeveloperGuidelinesTool } from './developer-guidelines.js';
|
|
26
|
+
import { createPageDesignerDecoratorTool } from '../page-designer-decorator/index.js';
|
|
27
27
|
/**
|
|
28
28
|
* Creates a placeholder tool for Storefront Next development.
|
|
29
29
|
*
|
|
@@ -32,10 +32,10 @@ import { createDeveloperGuidelinesTool } from './developer-guidelines.js';
|
|
|
32
32
|
*
|
|
33
33
|
* @param name - Tool name
|
|
34
34
|
* @param description - Tool description
|
|
35
|
-
* @param
|
|
35
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
36
36
|
* @returns The configured MCP tool
|
|
37
37
|
*/
|
|
38
|
-
function createPlaceholderTool(name, description,
|
|
38
|
+
function createPlaceholderTool(name, description, loadServices) {
|
|
39
39
|
return createToolAdapter({
|
|
40
40
|
name,
|
|
41
41
|
description: `[PLACEHOLDER] ${description}`,
|
|
@@ -57,7 +57,7 @@ function createPlaceholderTool(name, description, services) {
|
|
|
57
57
|
};
|
|
58
58
|
},
|
|
59
59
|
formatOutput: (output) => jsonResult(output),
|
|
60
|
-
},
|
|
60
|
+
}, loadServices);
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
63
|
* Creates all tools for the STOREFRONTNEXT toolset.
|
|
@@ -66,18 +66,18 @@ function createPlaceholderTool(name, description, services) {
|
|
|
66
66
|
* toolsets: ["MRT", "PWAV3", "STOREFRONTNEXT"] and will
|
|
67
67
|
* automatically appear in STOREFRONTNEXT.
|
|
68
68
|
*
|
|
69
|
-
* @param
|
|
69
|
+
* @param loadServices - Function that loads configuration and returns Services instance
|
|
70
70
|
* @returns Array of MCP tools
|
|
71
71
|
*/
|
|
72
|
-
export function createStorefrontNextTools(
|
|
72
|
+
export function createStorefrontNextTools(loadServices) {
|
|
73
73
|
return [
|
|
74
|
-
createDeveloperGuidelinesTool(
|
|
75
|
-
|
|
76
|
-
createPlaceholderTool('
|
|
77
|
-
createPlaceholderTool('
|
|
78
|
-
createPlaceholderTool('
|
|
79
|
-
createPlaceholderTool('
|
|
80
|
-
createPlaceholderTool('storefront_next_generate_page_designer_metadata', 'Generate Page Designer metadata for Storefront Next components',
|
|
74
|
+
createDeveloperGuidelinesTool(loadServices),
|
|
75
|
+
createPageDesignerDecoratorTool(loadServices),
|
|
76
|
+
createPlaceholderTool('storefront_next_site_theming', 'Configure and manage site theming for Storefront Next', loadServices),
|
|
77
|
+
createPlaceholderTool('storefront_next_figma_to_component_workflow', 'Convert Figma designs to Storefront Next components', loadServices),
|
|
78
|
+
createPlaceholderTool('storefront_next_generate_component', 'Generate a new Storefront Next component', loadServices),
|
|
79
|
+
createPlaceholderTool('storefront_next_map_tokens_to_theme', 'Map design tokens to Storefront Next theme configuration', loadServices),
|
|
80
|
+
createPlaceholderTool('storefront_next_generate_page_designer_metadata', 'Generate Page Designer metadata for Storefront Next components', loadServices),
|
|
81
81
|
];
|
|
82
82
|
}
|
|
83
83
|
//# sourceMappingURL=index.js.map
|
package/oclif.manifest.json
CHANGED
|
@@ -54,12 +54,23 @@
|
|
|
54
54
|
"type": "boolean"
|
|
55
55
|
},
|
|
56
56
|
"json": {
|
|
57
|
-
"description": "Output
|
|
57
|
+
"description": "Output result as JSON",
|
|
58
58
|
"helpGroup": "GLOBAL",
|
|
59
59
|
"name": "json",
|
|
60
60
|
"allowNo": false,
|
|
61
61
|
"type": "boolean"
|
|
62
62
|
},
|
|
63
|
+
"jsonl": {
|
|
64
|
+
"aliases": [
|
|
65
|
+
"json-logs"
|
|
66
|
+
],
|
|
67
|
+
"description": "Output log messages as JSON lines",
|
|
68
|
+
"env": "SFCC_JSON_LOGS",
|
|
69
|
+
"helpGroup": "GLOBAL",
|
|
70
|
+
"name": "jsonl",
|
|
71
|
+
"allowNo": false,
|
|
72
|
+
"type": "boolean"
|
|
73
|
+
},
|
|
63
74
|
"lang": {
|
|
64
75
|
"char": "L",
|
|
65
76
|
"description": "Language for messages (e.g., en, de). Also respects LANGUAGE env var.",
|
|
@@ -373,5 +384,5 @@
|
|
|
373
384
|
"enableJsonFlag": false
|
|
374
385
|
}
|
|
375
386
|
},
|
|
376
|
-
"version": "0.
|
|
387
|
+
"version": "0.4.0"
|
|
377
388
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/b2c-dx-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "MCP server for B2C Commerce Cloud developer experience tools",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"license": "MIT",
|
|
@@ -75,8 +75,11 @@
|
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@modelcontextprotocol/sdk": "1.26.0",
|
|
77
77
|
"@oclif/core": "4.8.0",
|
|
78
|
+
"glob": "13.0.0",
|
|
79
|
+
"ts-morph": "^27.0.0",
|
|
80
|
+
"yaml": "2.8.1",
|
|
78
81
|
"zod": "3.25.76",
|
|
79
|
-
"@salesforce/b2c-tooling-sdk": "0.
|
|
82
|
+
"@salesforce/b2c-tooling-sdk": "0.5.0"
|
|
80
83
|
},
|
|
81
84
|
"devDependencies": {
|
|
82
85
|
"@eslint/compat": "^1",
|
|
@@ -86,8 +89,9 @@
|
|
|
86
89
|
"@salesforce/dev-config": "^4.3.2",
|
|
87
90
|
"@types/chai": "^4",
|
|
88
91
|
"@types/mocha": "^10",
|
|
89
|
-
"@types/node": "^22
|
|
92
|
+
"@types/node": "^22",
|
|
90
93
|
"@types/sinon": "^21.0.0",
|
|
94
|
+
"c8": "^10.1.3",
|
|
91
95
|
"chai": "^4",
|
|
92
96
|
"eslint": "^9",
|
|
93
97
|
"eslint-config-oclif": "^6",
|
|
@@ -118,9 +122,10 @@
|
|
|
118
122
|
"inspect": "mcp-inspector node bin/run.js --toolsets all --allow-non-ga-tools",
|
|
119
123
|
"inspect:dev": "mcp-inspector node --conditions development bin/dev.js --toolsets all --allow-non-ga-tools",
|
|
120
124
|
"pretest": "tsc --noEmit -p test",
|
|
121
|
-
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
125
|
+
"test": "c8 mocha --forbid-only \"test/**/*.test.ts\"",
|
|
126
|
+
"test:ci": "c8 mocha --forbid-only --reporter json --reporter-option output=test-results.json \"test/**/*.test.ts\"",
|
|
122
127
|
"test:agent": "mocha --forbid-only --reporter min \"test/**/*.test.ts\"",
|
|
123
|
-
"
|
|
128
|
+
"coverage": "c8 report",
|
|
124
129
|
"posttest": "pnpm run lint"
|
|
125
130
|
}
|
|
126
131
|
}
|