Install AI Tools

B2C Commerce tools, documentation, and skills for your assistant.

Claude

Using Claude Desktop? See Claude Desktop (Cowork) setup.

Install the plugin Recommended

bash
claude plugin marketplace add SalesforceCommerceCloud/b2c-developer-tooling
claude plugin install b2c-dx-mcp@b2c-developer-tooling

Start a new Claude Code session. To install for the current project only, run it from your project directory with --scope project.

Manual MCP setup
bash
claude mcp add --transport stdio --scope user b2c-dx-mcp -- npx -y @salesforce/b2c-dx-mcp@latest

Start a new session. To configure the current project only, run it from your project directory with --scope project. See Claude Code MCP setup.

Codex/ChatGPT

Using the ChatGPT desktop app (ChatGPT Work)? See ChatGPT Work setup.

Install the plugin Recommended

bash
codex plugin marketplace add SalesforceCommerceCloud/b2c-developer-tooling
codex plugin add b2c-dx-mcp@b2c-developer-tooling

Start a new Codex session in your project. Codex plugins also work in ChatGPT Work.

Manual MCP setup
bash
codex mcp add b2c-dx-mcp -- npx -y @salesforce/b2c-dx-mcp@latest

Or add this to ~/.codex/config.toml (or $CODEX_HOME/config.toml if customized):

toml
[mcp_servers.b2c-dx-mcp]
command = "npx"
args = ["-y", "@salesforce/b2c-dx-mcp@latest"]

Start a new session. See Codex MCP configuration.

VS Code

Install the plugin Recommended

  1. Open the Command Palette (Cmd/Ctrl+Shift+P) and run Chat: Install Plugin from Source.
  2. Enter SalesforceCommerceCloud/b2c-developer-tooling.
  3. Select b2c-dx-mcp and follow the installation prompts.
  4. Start a new chat in GitHub Copilot.
Manual MCP setup

Add this to .vscode/mcp.json in your workspace:

json
{
  "servers": {
    "b2c-dx-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@salesforce/b2c-dx-mcp@latest"]
    }
  }
}

See VS Code MCP setup.

Copilot CLI setup

Cursor

Reload the MCP server in Cursor after installation.

Manual MCP setup

Add this to .cursor/mcp.json in your project:

json
{
  "mcpServers": {
    "b2c-dx-mcp": {
      "command": "npx",
      "args": ["-y", "@salesforce/b2c-dx-mcp@latest"]
    }
  }
}

For all projects, use ~/.cursor/mcp.json instead.

See Cursor's MCP documentation.

OpenCode

Add this to opencode.json in your project:

json
{
  "mcp": {
    "b2c-dx-mcp": {
      "type": "local",
      "command": ["npx", "-y", "@salesforce/b2c-dx-mcp@latest"],
      "enabled": true
    }
  }
}

Restart OpenCode. For all projects, use ~/.config/opencode/opencode.json. See OpenCode MCP setup.

Gemini

Run:

bash
gemini mcp add --scope user b2c-dx-mcp -- npx -y @salesforce/b2c-dx-mcp@latest

Start a new Gemini CLI session. To configure the current project only, run it from your project directory with --scope project. See Gemini CLI MCP setup.

No separate skills plugins needed.

Other clients and manual setup →
Skip to content
View as Markdown
View as Markdown

b2c_tooling_sdk.operations.jobs ​

Job execution operations for B2C Commerce.

Mirrors src/operations/jobs/index.ts. SDK consumers should call the SCAPI ops directly via the scapi_* free functions (or, for legacy code, the OCAPI free functions from run). Ordered import sets use the site-archive/WebDAV workflow.

The SCAPI ops are defined in scapi_ops with plain names (execute_job etc.) and re-exported here under scapi_* names, matching the TS executeJob as scapiExecuteJob aliasing.

Classes ​

JobExecutionError ​

python
class JobExecutionError(Exception)

Raised when a job execution fails.

Carries the raw OCAPI JobExecution so callers can read fields (exit_status, log_file_path, ...) for error reporting.

ExecuteJobOptions ​

python
class ExecuteJobOptions

Options for executing a job.

Fields

NameTypeDefault
parameterslist[JobExecutionParameter]field(default_factory=list)
bodydict[str, Any] | NoneNone
wait_for_runningboolTrue

WaitForJobOptions ​

python
class WaitForJobOptions

Options for waiting on a job.

Fields

NameTypeDefault
poll_interval_secondsfloat3
timeout_secondsfloat0
on_pollCallable[[WaitForJobPollInfo], None] | NoneNone
sleepCallable[[float], Awaitable[None]]asyncio.sleep

WaitForJobPollInfo ​

python
class WaitForJobPollInfo

Poll info passed to the on_poll callback during job waiting.

Fields

NameType
job_idstr
execution_idstr
elapsed_secondsint
statusstr

SearchJobExecutionsOptions ​

python
class SearchJobExecutionsOptions

Search options for job executions.

Fields

NameTypeDefault
job_idstr | NoneNone
statusstr | list[str] | NoneNone
countint25
startint0
sort_bystr'start_time'
sort_orderstr'desc'

JobExecutionSearchResult ​

python
class JobExecutionSearchResult

Search results for job executions (raw OCAPI hits).

Fields

NameType
totalint
countint
startint
hitslist[JobExecution]

ScapiJobStartError ​

python
class ScapiJobStartError(ScapiRequestError)

Raised when the SCAPI job-start POST is rejected with a response (non-2xx).

Carries the received HTTP status so callers can tell a request rejection (server refused before starting the job — safe to treat as "no job created") from an ambiguous failure. A network/timeout error during the POST does NOT produce this — it surfaces as a raw thrown error with no status, because the request may have reached the server.

ExecuteJobScapiOptions ​

python
class ExecuteJobScapiOptions

Options for execute_job (SCAPI).

Fields

NameTypeDefault
tenant_idstr
parameterslist[dict[str, Any]]field(default_factory=list)
bodydict[str, Any] | NoneNone
wait_for_runningboolTrue
sleepCallable[[float], Awaitable[None]]asyncio.sleep

SearchJobExecutionsScapiOptions ​

python
class SearchJobExecutionsScapiOptions

Options for search_job_executions (SCAPI).

Fields

NameTypeDefault
tenant_idstr
job_idstr | NoneNone
statusstr | list[str] | NoneNone
countint25
startint0
sort_bystr'start_time'
sort_orderstr'desc'

JobExecutionInfo ​

python
class JobExecutionInfo

Canonical, backend-agnostic job execution shape.

raw mirrors the TypeScript _raw field: the original backend payload, preserved for a lossless round-trip when mapping back to OCAPI.

Fields

NameTypeDefault
idstr
job_idstr
execution_statusJobCanonicalStatus
exit_statusJobExitStatus | NoneNone
start_timestr | NoneNone
end_timestr | NoneNone
durationint | NoneNone
step_executionslist[JobStepExecutionResult] | NoneNone
log_file_pathstr | NoneNone
is_log_file_existingbool | NoneNone
parameterslist[dict[str, str]] | NoneNone
rawAnyfield(default=None)

JobStepExecutionResult ​

python
class JobStepExecutionResult

Canonical, backend-agnostic step execution.

Fields

NameTypeDefault
idstr | NoneNone
step_idstr | NoneNone
execution_statusstr | NoneNone
exit_statusJobExitStatus | NoneNone
durationint | NoneNone

JobExecutionSearchResults ​

python
class JobExecutionSearchResults

Canonical search results over JobExecutionInfo.

Fields

NameType
totalint
limitint
offsetint
hitslist[JobExecutionInfo]

CanonicalJobExecutionError ​

python
class CanonicalJobExecutionError(Exception)

Raised by wait_for_job_execution when a job reaches a failure state.

Carries the canonical JobExecutionInfo so callers can read fields (exit_status.code, log_file_path, ...) without knowing which backend served the response.

SystemJobSpec ​

python
class SystemJobSpec

Declarative description of a system job to run.

Fields

NameTypeDefault
job_idstr
ocapi_bodydict[str, Any]
parameterslist[dict[str, str]]
fail_verbstr
deprecated_scopeslist[str] | NoneNone
waitboolTrue
wait_optionsWaitForJobOptions | NoneNone

SiteArchiveImportOptions ​

python
class SiteArchiveImportOptions

Options for site_archive_import.

Fields

NameTypeDefault
keep_archiveboolFalse
waitboolTrue
wait_optionsWaitForJobOptions | NoneNone
pathslist[str] | NoneNone
max_bytesint | NoneNone
on_oversizeCallable[[dict[str, int]], None] | NoneNone
archive_namestr | NoneNone

SiteArchiveImportResult ​

python
class SiteArchiveImportResult

Result of a site archive import.

Fields

NameType
executionJobExecution
archive_filenamestr
archive_keptbool

SiteArchiveImportSplitOptions ​

python
class SiteArchiveImportSplitOptions

Options for site_archive_import_split.

Fields

NameTypeDefault
max_bytesint190 * 1024 * 1024
keep_archiveboolFalse
wait_optionsWaitForJobOptions | NoneNone
archive_namestr | NoneNone
on_planCallable[[SplitImportPlanInfo], None] | NoneNone
on_partCallable[[SplitImportPartInfo], None] | NoneNone

SplitImportPlanInfo ​

python
class SplitImportPlanInfo

Summary of the computed split plan.

Fields

NameType
part_countint
xml_part_countint
asset_part_countint
max_bytesint

SplitImportPartInfo ​

python
class SplitImportPartInfo

Per-part progress info.

Fields

NameType
indexint
totalint
kindstr
filenamestr
file_countint
bytesint

SiteArchiveExportOptions ​

python
class SiteArchiveExportOptions

Options for site archive export.

Fields

NameTypeDefault
wait_optionsWaitForJobOptions | NoneNone
keep_archiveboolFalse
extract_zipboolTrue

SiteArchiveExportResult ​

python
class SiteArchiveExportResult

Result of a site archive export.

Fields

NameType
executionJobExecution
archive_filenamestr

ExportDataUnitsConfiguration ​

python
class ExportDataUnitsConfiguration

Data units configuration for an export (all fields optional).

Fields

NameTypeDefault
catalog_static_resourcesdict[str, bool] | NoneNone
catalogsdict[str, bool] | NoneNone
customer_listsdict[str, bool] | NoneNone
inventory_listsdict[str, bool] | NoneNone
library_static_resourcesdict[str, bool] | NoneNone
librariesdict[str, bool] | NoneNone
price_booksdict[str, bool] | NoneNone
sitesdict[str, Any] | NoneNone
global_datadict[str, Any] | NoneNone

ExportSitesConfiguration ​

python
class ExportSitesConfiguration

Configuration for a single site in an export (all fields optional).

Fields

NameTypeDefault
ab_testsbool | NoneNone
active_data_feedsbool | NoneNone
allbool | NoneNone
cache_settingsbool | NoneNone
campaigns_and_promotionsbool | NoneNone
commerce_feature_statesbool | NoneNone
contentbool | NoneNone
couponsbool | NoneNone
custom_objectsbool | NoneNone
customer_cdn_settingsbool | NoneNone
customer_groupsbool | NoneNone
distributed_commerce_extensionsbool | NoneNone
dynamic_file_resourcesbool | NoneNone
gift_certificatesbool | NoneNone
ocapi_settingsbool | NoneNone
payment_methodsbool | NoneNone
payment_processorsbool | NoneNone
redirect_urlsbool | NoneNone
search_settingsbool | NoneNone
shippingbool | NoneNone
site_descriptorbool | NoneNone
site_preferencesbool | NoneNone
sitemap_settingsbool | NoneNone
slotsbool | NoneNone
sorting_rulesbool | NoneNone
source_codesbool | NoneNone
static_dynamic_alias_mappingsbool | NoneNone
storesbool | NoneNone
taxbool | NoneNone
url_rulesbool | NoneNone

ExportGlobalDataConfiguration ​

python
class ExportGlobalDataConfiguration

Configuration for global data in an export (all fields optional).

Fields

NameTypeDefault
access_rolesbool | NoneNone
allbool | NoneNone
csc_settingsbool | NoneNone
csrf_whitelistsbool | NoneNone
custom_preference_groupsbool | NoneNone
custom_quota_settingsbool | NoneNone
custom_typesbool | NoneNone
geolocationsbool | NoneNone
global_custom_objectsbool | NoneNone
job_schedulesbool | NoneNone
job_schedules_deprecatedbool | NoneNone
localesbool | NoneNone
meta_databool | NoneNone
oauth_providersbool | NoneNone
ocapi_settingsbool | NoneNone
page_meta_tagsbool | NoneNone
preferencesbool | NoneNone
price_adjustment_limitsbool | NoneNone
servicesbool | NoneNone
sorting_rulesbool | NoneNone
static_resourcesbool | NoneNone
system_type_definitionsbool | NoneNone
usersbool | NoneNone
webdav_client_permissionsbool | NoneNone

ImportSetStateError ​

python
class ImportSetStateError(Exception)

Thrown when WebDAV lock or receipt state cannot be safely read or written.

DiscoverImportSetOptions ​

python
class DiscoverImportSetOptions

Options for discovering import-set items.

Fields

NameTypeDefault
include_cartridge_metadataboolTrue
cartridge_rootstr | NoneNone
exclude_directorieslist[str] | NoneNone

ImportSetItem ​

python
class ImportSetItem

A local archive in an import set.

Fields

NameTypeDefault
idstr
targetstr
kindstr
notestr | NoneNone

ImportSetReceipt ​

python
class ImportSetReceipt

Durable directory receipt created after an import completes successfully.

Fields

NameTypeDefault
set_idstr
item_idstr
receipt_pathstr
versionint1

ImportSetItemResult ​

python
class ImportSetItemResult(ImportSetItem)

Result for one item in an import set.

Fields

NameTypeDefault
statusstr'pending'
receiptImportSetReceipt | NoneNone
import_resultSiteArchiveImportResult | NoneNone

ImportSetResult ​

python
class ImportSetResult

Result of planning or applying an import set.

Fields

NameType
set_idstr
directorystr
dry_runbool
run_idstr
itemslist[ImportSetItemResult]
importedint
skippedint
pendingint

ImportSetEvent ​

python
class ImportSetEvent

Structured lifecycle event delivered while planning and applying an import set.

The type field selects the variant; only the fields relevant to that variant are populated (mirrors the TS discriminated union).

Fields

NameTypeDefault
typestr
set_idstr | NoneNone
totalint | NoneNone
pendingint | NoneNone
skippedint | NoneNone
dry_runbool | NoneNone
run_idstr | NoneNone
ownerImportSetLockOwner | NoneNone
age_secondsfloat | NoneNone
forcedbool | NoneNone
itemImportSetItem | NoneNone
receiptImportSetReceipt | NoneNone
indexint | NoneNone
receipt_pathstr | NoneNone

ImportSetLockOwner ​

python
class ImportSetLockOwner

Owner information stored inside the WebDAV lock directory.

Fields

NameTypeDefault
set_idstr
run_idstr
created_atstr
heartbeat_atstr
ownerstr | NoneNone
versionint1

SiteArchiveImportSetOptions ​

python
class SiteArchiveImportSetOptions

Options for site_archive_import_set.

Fields

NameTypeDefault
set_idstr | NoneNone
dry_runboolFalse
keep_archiveboolFalse
include_cartridge_metadataboolTrue
cartridge_rootstr | NoneNone
exclude_directorieslist[str] | NoneNone
state_rootstr | NoneNone
stale_lock_secondsint | NoneNone
lock_poll_interval_secondsint | NoneNone
heartbeat_interval_secondsint | NoneNone
break_lockboolFalse
ownerstr | NoneNone
wait_optionsAnyNone
on_eventCallable[[ImportSetEvent], None] | NoneNone
import_archive_ImportArchiveFn | NoneNone
sleep_SleepFnfield(default=asyncio.sleep)

ExportableUnits ​

python
class ExportableUnits

IDs discovered on an instance, grouped by data-unit category.

Each list is sorted alphabetically. A category that could not be read (e.g. missing OCAPI permission) is returned as an empty list with a matching entry in warnings.

Fields

NameTypeDefault
siteslist[str]field(default_factory=list)
catalogslist[str]field(default_factory=list)
inventory_listslist[str]field(default_factory=list)
warningslist[str]field(default_factory=list)

Functions ​

execute_job ​

python
async def execute_job(instance: B2CInstance, job_id: str, options: ExecuteJobOptions | None = None) -> JobExecution

Execute a job on a B2C Commerce instance (OCAPI).

Starts a job execution and returns immediately with the execution details. Use wait_for_job to wait for completion.

Raises

  • RuntimeError — if the job is already running (when wait_for_running is False) or the job cannot be executed.
  • OcapiDeprecatedError — when OCAPI is deprecated for the instance.

get_job_execution ​

python
async def get_job_execution(instance: B2CInstance, job_id: str, execution_id: str) -> JobExecution

Get the current status of a job execution (OCAPI).

Raises

  • RuntimeError — if the execution is not found.
  • OcapiDeprecatedError — when OCAPI is deprecated for the instance.

wait_for_job ​

python
async def wait_for_job(instance: B2CInstance, job_id: str, execution_id: str, options: WaitForJobOptions | None = None) -> JobExecution

Wait for a job execution to complete (OCAPI).

Polls the job status until it reaches a terminal state (finished or aborted).

Raises

  • JobExecutionError — if the job fails (status ERROR or aborted).
  • RuntimeError — if the timeout is exceeded.

search_job_executions ​

python
async def search_job_executions(instance: B2CInstance, options: SearchJobExecutionsOptions | None = None) -> JobExecutionSearchResult

Search for job executions (OCAPI).

Raises

  • RuntimeError — if the search request fails.
  • OcapiDeprecatedError — when OCAPI is deprecated for the instance.

find_running_job_execution ​

python
async def find_running_job_execution(instance: B2CInstance, job_id: str) -> JobExecution | None

Find a currently running job execution, or None if none found.

Raises

  • RuntimeError — if the underlying search request fails.

get_job_log ​

python
async def get_job_log(instance: B2CInstance, execution: JobExecution) -> str

Get the log file content for a job execution over WebDAV.

Raises

  • RuntimeError — if the log file path is missing or the file does not exist.

get_job_error_message ​

python
def get_job_error_message(execution: JobExecution) -> str | None

Extract the error message from a failed job execution.

Looks for the last step execution with exit_status.code == 'ERROR' and returns its message, or None when none is found.

scapi_execute_job ​

python
async def scapi_execute_job(client: ScapiJobsClient, job_id: str, options: ExecuteJobScapiOptions) -> JobExecutionInfo

Execute a job (SCAPI). Requires the rw scope (no ro fallback for writes).

If the job is already running and wait_for_running is not False, polls until the prior run reaches a terminal state, then retries.

Raises

  • ScapiJobStartError — when the server rejects the start with a response.
  • RuntimeError — when the job is already running and wait_for_running is False.

scapi_get_job_execution ​

python
async def scapi_get_job_execution(client: ScapiJobsClient, job_id: str, execution_id: str, tenant_id: str) -> JobExecutionInfo

Get a job execution by ID (SCAPI).

Raises

scapi_search_job_executions ​

python
async def scapi_search_job_executions(client: ScapiJobsClient, options: SearchJobExecutionsScapiOptions) -> JobExecutionSearchResults

Search for job executions (SCAPI).

Raises

scapi_delete_job_execution ​

python
async def scapi_delete_job_execution(client: ScapiJobsClient, job_id: str, execution_id: str, tenant_id: str) -> None

Delete a job execution (SCAPI).

Raises

scapi_get_job_log ​

python
async def scapi_get_job_log(instance: B2CInstance, execution: JobExecutionInfo) -> str

Retrieve a job's log file content over WebDAV.

Both backends (SCAPI and OCAPI) expose log_file_path under /Sites/LOGS/...; WebDAV is shared.

Raises

  • RuntimeError — if the log file path is missing or the file does not exist.

wait_for_job_execution ​

python
async def wait_for_job_execution(get_execution: Callable[[str, str], Awaitable[JobExecutionInfo]], job_id: str, execution_id: str, options: WaitForJobOptions | None = None) -> JobExecutionInfo

Poll get_execution(job_id, execution_id) until a terminal state.

Returns: the final JobExecutionInfo.

Raises

map_ocapi_execution ​

python
def map_ocapi_execution(ocapi: JobExecution) -> JobExecutionInfo

Map a raw OCAPI JobExecution into the canonical shape.

map_ocapi_search_result ​

python
def map_ocapi_search_result(result: JobExecutionSearchResult) -> JobExecutionSearchResults

Map a raw OCAPI search result into the canonical shape.

map_canonical_to_ocapi_execution ​

python
def map_canonical_to_ocapi_execution(canonical: JobExecutionInfo) -> JobExecution

Map a canonical JobExecutionInfo back into the raw OCAPI shape.

The reverse of map_ocapi_execution. Prefers the original OCAPI payload when present in raw (lossless round-trip for the OCAPI path); otherwise projects the canonical fields.

site_archive_import ​

python
async def site_archive_import(instance: B2CInstance, target: str | bytes | Mapping[str, Any] | RemoteArchiveTarget, options: SiteArchiveImportOptions | None = None, **overrides: Any) -> SiteArchiveImportResult

Import a site archive to a B2C Commerce instance.

Supports importing from a local directory (zipped automatically), a local zip file, a bytes buffer containing zip data, or a filename already on the instance (via a RemoteArchiveTarget or a mapping with a remote_filename key).

Options may be passed as a SiteArchiveImportOptions object or as keyword overrides (e.g. wait_options=...).

Raises

site_archive_import_split ​

python
async def site_archive_import_split(instance: B2CInstance, directory: str, options: SiteArchiveImportSplitOptions | None = None, **overrides: Any) -> list[SiteArchiveImportResult]

Import a large site archive by splitting it into multiple size-bounded parts, imported sequentially. Order-sensitive XML/metadata is imported first; static assets are deferred to subsequent parts.

Raises

  • ValueError — if a single file or data unit cannot fit under max_bytes.
  • JobExecutionError — if any part's import job fails.

site_archive_export ​

python
async def site_archive_export(instance: B2CInstance, data_units: Mapping[str, Any] | ExportDataUnitsConfiguration, options: SiteArchiveExportOptions | None = None, **overrides: Any) -> SiteArchiveExportResult

Export a site archive from a B2C Commerce instance.

Raises

site_archive_export_to_buffer ​

python
async def site_archive_export_to_buffer(instance: B2CInstance, data_units: Mapping[str, Any] | ExportDataUnitsConfiguration, options: SiteArchiveExportOptions | None = None, **overrides: Any) -> SiteArchiveExportToBufferResult

Export a site archive and download it into memory (.data bytes).

site_archive_export_to_path ​

python
async def site_archive_export_to_path(instance: B2CInstance, data_units: Mapping[str, Any] | ExportDataUnitsConfiguration, output_path: str, options: SiteArchiveExportOptions | None = None, **overrides: Any) -> SiteArchiveExportToPathResult

Export a site archive, download it, and save it to a local path.

When output_path ends in .zip (or extract_zip is False) the archive is written as a zip file; otherwise it is extracted into the directory at output_path.

discover_import_set ​

python
async def discover_import_set(directory: str, options: DiscoverImportSetOptions | None = None) -> list[ImportSetItem]

Discover import items from cartridge metadata/ directories followed by the explicit import-set directory.

A cartridge metadata directory that resembles a site archive is one item; otherwise its immediate child directories and zip archives are items.

Raises

  • ValueError — when no items are found or an item ID collides.

site_archive_import_set ​

python
async def site_archive_import_set(instance: B2CInstance, directory: str, options: SiteArchiveImportSetOptions | None = None) -> ImportSetResult

Apply an ordered set of site archives exactly until a verified receipt directory exists for each item.

A missing or invalid receipt always leaves the item pending. The operation never logs or writes output; callers consume structured progress through SiteArchiveImportSetOptions.on_event.

discover_exportable_units ​

python
async def discover_exportable_units(instance: B2CInstance) -> ExportableUnits

Discover the data units that can be exported from an instance.

Each category is read independently: a failure in one records a warning and leaves that list empty rather than failing the whole discovery.

Parameters

NameTypeDescription
instanceB2CInstanceB2C instance to query.

Returns: Discovered IDs grouped by category, with per-category warnings.

Attributes ​

JobExecution ​

python
JobExecution = dict[str, Any]

JobStepExecution ​

python
JobStepExecution = dict[str, Any]

JobExecutionStatus ​

python
JobExecutionStatus = str

JobExecutionParameter ​

python
JobExecutionParameter = dict[str, Any]