Install AI Tools

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

Claude

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.

Claude Desktop setup

Codex

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. This setup also works with the Codex IDE extension and the ChatGPT Work desktop app.

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.

ChatGPT online setup

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.config ​

Configuration loading utilities.

Mirrors src/config/index.ts. The preferred high-level API is resolve_config, which returns a rich ResolvedConfigImpl with validation predicates and auth-strategy factory methods.

Resolution priority (highest to lowest): explicit overrides, then configuration sources (dw.json, ~/.mobify, package.json). Later sources only fill in missing values. Hostname-mismatch protection prevents mixing credentials across instances.

To go straight from configuration to a usable client, use create_instance_from_config or ResolvedConfigImpl.create_b2c_instance.

Example:

python
from b2c_tooling_sdk.config import resolve_config
from b2c_tooling_sdk.config.types import NormalizedConfig

config = await resolve_config(
    NormalizedConfig(hostname="example.com", client_id="...")
)
if config.has_oauth_config():
    strategy = config.create_oauth()

Classes ​

ConfigCatalogFile ​

python
class ConfigCatalogFile

A dw.json file participating in the effective instance catalog.

Fields

NameType
locationstr
scopeLiteral['global', 'primary']
selectedbool

ConfigLoadResult ​

python
class ConfigLoadResult

Result of loading configuration from a single source.

Fields

NameTypeDefault
configNormalizedConfig
scopeLiteral['global'] | NoneNone
instance_cataloglist[ConfigCatalogFile] | NoneNone
locationstr | NoneNone

ConfigResolutionResult ​

python
class ConfigResolutionResult

Result of configuration resolution.

Fields

NameType
configNormalizedConfig
warningslist[ConfigWarning]
sourceslist[ConfigSourceInfo]

ConfigResolver ​

python
class ConfigResolver

Resolves configuration from multiple sources with consistent behaviour.

resolve method ​

python
async def resolve(overrides: NormalizedConfig | None = None, options: ResolveConfigOptions | None = None) -> ConfigResolutionResult

Resolve configuration from all sources, applying override precedence.

create_auth_credentials method ​

python
async def create_auth_credentials(overrides: NormalizedConfig | None = None, options: ResolveConfigOptions | None = None) -> AuthCredentials

Resolve config and return AuthCredentials for resolve_auth_strategy.

create_instance method ​

python
async def create_instance(overrides: NormalizedConfig | None = None, options: ResolveConfigOptions | None = None) -> B2CInstance

Resolve configuration and create a B2CInstance.

A convenience method combining resolve with instance creation. Any resolution warnings are logged.

Raises

  • ValueError — if no hostname is available in the resolved config.

ConfigSource ​

python
class ConfigSource(Protocol)

A configuration source that can contribute config values.

Implement this protocol to create custom configuration sources. The required surface is name and load. Sources may optionally implement the instance-management and credential-storage methods; consumers probe for them with getattr / hasattr at runtime.

Fields

NameType
namestr

load method ​

python
def load(options: ResolveConfigOptions) -> MaybePromise[ConfigLoadResult | None]

Load configuration from this source (may be sync or async).

ConfigSourceInfo ​

python
class ConfigSourceInfo

Information about a configuration source that participated in resolution.

Fields

NameTypeDefault
namestr
fieldslist[str]
scopeLiteral['global'] | NoneNone
locationstr | NoneNone
fields_ignoredlist[str] | NoneNone
instance_cataloglist[ConfigCatalogFile] | NoneNone

ConfigSourceRegistry ​

python
class ConfigSourceRegistry

Registry that collects ConfigSource instances for resolution.

Fields

NameTypeDescription
sizeintNumber of registered sources.

register method ​

python
def register(source: ConfigSource) -> None

Register a source (ignored if a source with the same name exists).

unregister method ​

python
def unregister(name: str) -> bool

Remove a source by name; returns True if one was removed.

get_sources method ​

python
def get_sources() -> list[ConfigSource]

Return a shallow copy of all registered sources.

clear method ​

python
def clear() -> None

Remove all registered sources (primarily useful for testing).

get_source_names method ​

python
def get_source_names() -> list[str]

Return the names of all registered sources.

ConfigWarning ​

python
class ConfigWarning

A warning generated during configuration resolution.

Fields

NameTypeDefault
codeConfigWarningCode
messagestr
detailsdict[str, Any] | NoneNone

CreateB2CInstanceOptions ​

python
class CreateB2CInstanceOptions

Options for constructing a B2C instance from resolved configuration.

Fields

NameTypeDefault
redirect_uristr | NoneNone
open_browserCallable[[str], Awaitable[None]] | NoneNone
oauth_strategyAuthStrategy | Callable[[], AuthStrategy] | NoneNone

CreateInstanceOptions ​

python
class CreateInstanceOptions

Options for creating an instance in a dw.json-style source.

Flattens the TypeScript CreateInstanceOptions & ResolveConfigOptions intersection: it carries the instance name/config plus the subset of resolution fields a dw.json source needs to locate the target file.

Fields

NameTypeDefault
namestr
configNormalizedConfig
set_activeboolFalse
config_pathstr | NoneNone
project_directorystr | NoneNone
working_directorystr | NoneNone
default_config_pathstr | NoneNone

CreateOAuthOptions ​

python
class CreateOAuthOptions

Options for creating an OAuth auth strategy.

Fields

NameTypeDefault
allowed_methodslist[AuthMethod] | NoneNone
scopeslist[str] | NoneNone
redirect_uristr | NoneNone
open_browserCallable[[str], Awaitable[None]] | NoneNone

DwJsonSource ​

python
class DwJsonSource

Configuration source that loads from dw.json files.

load method ​

python
async def load(options: ResolveConfigOptions) -> ConfigLoadResult | None

Load configuration for the requested (or active/root) instance.

list_instances method ​

python
async def list_instances(options: ResolveConfigOptions | None = None) -> list[InstanceInfo]

List all instances across the effective dw.json files (deduped by name).

create_instance method ​

python
async def create_instance(options: CreateInstanceOptions) -> None

Create a new instance in dw.json.

remove_instance method ​

python
async def remove_instance(name: str, options: ResolveConfigOptions | None = None) -> None

Remove an instance from the dw.json file that contains it.

set_active_instance method ​

python
async def set_active_instance(name: str, options: ResolveConfigOptions | None = None) -> None

Set an instance active, clearing active flags in the other catalog files.

EnvSource ​

python
class EnvSource

Configuration source that reads CLI configuration environment variables.

Priority -10 (higher than dw.json at 0), matching CLI behaviour where env vars override file-based config.

load method ​

python
def load(options: ResolveConfigOptions) -> ConfigLoadResult | None

Load config from environment variables (synchronous).

InstanceInfo ​

python
class InstanceInfo

Information about a configured instance.

Fields

NameTypeDefault
namestr
sourcestr
hostnamestr | NoneNone
activebool | NoneNone
locationstr | NoneNone

InstanceManager ​

python
class InstanceManager

Aggregates instance-management operations across multiple config sources.

list_all_instances method ​

python
async def list_all_instances(options: ResolveConfigOptions | None = None) -> list[InstanceInfo]

List instances from every source that implements list_instances.

get_instance_sources method ​

python
def get_instance_sources() -> list[ConfigSource]

Return sources that can create instances.

get_credential_sources method ​

python
def get_credential_sources(field: str) -> list[ConfigSource]

Return sources that can store the given credential field.

create_instance method ​

python
async def create_instance(options: CreateInstanceOptions, target_source: str | None = None) -> None

Create an instance in the target source (or the first available one).

remove_instance method ​

python
async def remove_instance(name: str, options: ResolveConfigOptions | None = None) -> None

Remove an instance from whichever source contains it.

set_active_instance method ​

python
async def set_active_instance(name: str, options: ResolveConfigOptions | None = None) -> None

Set an instance active in whichever source contains it.

store_credential method ​

python
async def store_credential(instance_name: str, field: str, value: str, target_source: str | None = None, options: ResolveConfigOptions | None = None) -> None

Store a credential for an instance in the target credential source.

LibraryEntry ​

python
class LibraryEntry

A configured content library entry.

The simpler str form (an ID alone) is equivalent to LibraryEntry(id=..., site_library=False).

Fields

NameTypeDefault
idstr
site_libraryboolFalse

LoadDwJsonResult ​

python
class LoadDwJsonResult

The selected dw.json config plus the file path it came from.

Fields

NameType
configDwJsonConfig
pathstr

NormalizedConfig ​

python
class NormalizedConfig

Normalized B2C configuration with snake_case fields.

The canonical intermediate format that all configuration sources map to, regardless of their on-disk format (dw.json kebab/camelCase, env vars, etc.).

Fields

NameTypeDefault
hostnamestr | NoneNone
webdav_hostnamestr | NoneNone
code_versionstr | NoneNone
usernamestr | NoneNone
passwordstr | NoneNone
client_idstr | NoneNone
client_secretstr | NoneNone
scopeslist[str] | NoneNone
auth_methodslist[AuthMethod] | NoneNone
account_manager_hoststr | NoneNone
jwt_cert_pathstr | NoneNone
jwt_key_pathstr | NoneNone
jwt_passphrasestr | NoneNone
slas_client_idstr | NoneNone
slas_client_secretstr | NoneNone
site_idstr | NoneNone
short_codestr | NoneNone
tenant_idstr | NoneNone
sandbox_api_hoststr | NoneNone
realmstr | NoneNone
mrt_projectstr | NoneNone
mrt_environmentstr | NoneNone
mrt_api_keystr | NoneNone
mrt_originstr | NoneNone
auto_uploadbool | NoneNone
cartridgeslist[str] | NoneNone
import_set_excludelist[str] | NoneNone
content_librarystr | NoneNone
catalogslist[str] | NoneNone
librarieslist[str | LibraryEntry] | NoneNone
asset_querylist[str] | NoneNone
cip_hoststr | NoneNone
docs_categorieslist[str] | NoneNone
instance_namestr | NoneNone
project_directorystr | NoneNone
working_directorystr | NoneNone
certificatestr | NoneNone
certificate_passphrasestr | NoneNone
self_signedbool | NoneNone
api_backendLiteral['ocapi', 'scapi', 'auto'] | NoneNone

ResolveConfigOptions ​

python
class ResolveConfigOptions

Options for configuration resolution.

Fields

NameTypeDefault
instancestr | NoneNone
config_pathstr | NoneNone
default_config_pathstr | NoneNone
project_directorystr | NoneNone
working_directorystr | NoneNone
hostname_protectionbool | NoneNone
client_id_protectionbool | NoneNone
cloud_originstr | NoneNone
credentials_filestr | NoneNone
account_manager_hoststr | NoneNone
sources_beforelist[ConfigSource] | NoneNone
sources_afterlist[ConfigSource] | NoneNone
replace_default_sourcesboolFalse

ResolvedConfigImpl ​

python
class ResolvedConfigImpl

Resolved configuration with validation and auth-strategy factories.

has_b2c_instance_config method ​

python
def has_b2c_instance_config() -> bool

Whether a B2C instance can be created (requires a hostname).

has_mrt_config method ​

python
def has_mrt_config() -> bool

Whether MRT credentials are available (requires an MRT API key).

has_oauth_config method ​

python
def has_oauth_config() -> bool

Whether OAuth can be used (requires a client id).

has_basic_auth_config method ​

python
def has_basic_auth_config() -> bool

Whether basic auth can be used (requires username and password).

create_b2c_instance method ​

python
def create_b2c_instance(options: CreateB2CInstanceOptions | None = None) -> B2CInstance

Create a B2CInstance from the resolved config.

Raises

  • ValueError — if no hostname is available (see has_b2c_instance_config).

create_basic_auth method ​

python
def create_basic_auth() -> AuthStrategy

Create a BasicAuthStrategy from the resolved credentials.

create_oauth method ​

python
def create_oauth(options: CreateOAuthOptions | None = None) -> AuthStrategy

Create an OAuth strategy, merging any additional scopes over config scopes.

create_mrt_auth method ​

python
def create_mrt_auth() -> AuthStrategy

Create an ApiKeyStrategy for MRT (Authorization header).

create_webdav_auth method ​

python
def create_webdav_auth() -> AuthStrategy

Create the best available WebDAV auth strategy (basic preferred, else OAuth).

Functions ​

add_instance ​

python
def add_instance(instance: DwJsonConfig, *, path: str | None = None, project_directory: str | None = None, working_directory: str | None = None, set_active: bool = False) -> None

Add a new named instance to dw.json, creating the file if needed.

Raises

  • ValueError — if the instance has no name or the name already exists.

create_config_resolver ​

python
def create_config_resolver() -> ConfigResolver

Create a ConfigResolver with the default sources.

create_instance_from_config ​

python
def create_instance_from_config(config: NormalizedConfig, options: CreateB2CInstanceOptions | None = None) -> B2CInstance

Create a B2CInstance from a NormalizedConfig.

Single source of truth for instance creation from resolved configuration — used by both ResolvedConfigImpl.create_b2c_instance and consumers such as CLI commands. TLS options are included only when a certificate or self-signed mode is configured. When options supplies a redirect_uri or open_browser, they are injected into the OAuth config for browser flows.

Raises

  • ValueError — if config has no hostname.

create_instance_manager ​

python
def create_instance_manager(sources: list[ConfigSource]) -> InstanceManager

Create an InstanceManager with the given sources.

find_dw_json ​

python
def find_dw_json(project_directory: str | None = None) -> str | None

Find dw.json by searching upward from project_directory (defaults to cwd).

get_b2c_config_directory ​

python
def get_b2c_config_directory(*, config_directory: str | None = None, environment: dict[str, str] | None = None, home_directory: str | None = None, platform: str | None = None) -> str

Resolve the shared oclif-compatible B2C configuration directory.

get_b2c_settings_path ​

python
def get_b2c_settings_path(*, config_directory: str | None = None, environment: dict[str, str] | None = None, home_directory: str | None = None, platform: str | None = None) -> str

Resolve the shared settings.json path.

is_sensitive_config_field ​

python
def is_sensitive_config_field(field: str) -> bool

Return True when a field name holds a secret that should be masked.

load_dw_json ​

python
def load_dw_json(*, instance: str | None = None, path: str | None = None, project_directory: str | None = None, working_directory: str | None = None) -> LoadDwJsonResult | None

Load configuration from a dw.json file (no upward directory search).

Keys are normalized to camelCase and the appropriate instance is selected. Returns None if no file is found or the named instance is absent. Raises on invalid JSON.

load_full_dw_json ​

python
def load_full_dw_json(*, path: str | None = None, project_directory: str | None = None, working_directory: str | None = None) -> LoadFullDwJsonResult | None

Load the raw multi-config dw.json without selecting an instance.

Returns None if the file does not exist. Raises on invalid JSON.

mask_config_value ​

python
def mask_config_value(value: str) -> str

Mask a secret, showing the first 4 chars when long enough to aid identification.

Matches the SDK logger convention (<first4>...REDACTED); values of 10 or fewer characters are fully redacted.

merge_project_environment ​

python
def merge_project_environment(project_environment: dict[str, str] | None = None, ambient_environment: dict[str, str] | None = None) -> dict[str, str]

Merge project variables with the ambient environment (ambient wins).

normalize_config_keys ​

python
def normalize_config_keys(raw: dict[str, Any]) -> dict[str, Any]

Normalize config keys to their canonical camelCase form.

Resolution order per key: alias table, then kebab->camelCase conversion. The first value wins when multiple keys resolve to the same canonical name. None values are dropped (mirrors the TS undefined skip) so absent keys never shadow a later alias for the same canonical name.

read_b2c_settings ​

python
def read_b2c_settings(*, config_directory: str | None = None, environment: dict[str, str] | None = None, home_directory: str | None = None, platform: str | None = None) -> dict[str, Any]

Read shared B2C settings. Missing or invalid files are treated as unset.

A relative defaultConfigPath is resolved against the settings directory; a non-string/empty value is dropped with a warning.

read_project_environment ​

python
def read_project_environment(project_directory: str | None = None) -> dict[str, str] | None

Read all variables from a project's .env file, or None if absent.

redact_config_values ​

python
def redact_config_values(values: NormalizedConfig, *, unmask: bool = False) -> dict[str, Any]

Return a dict of config values with sensitive fields masked.

Fields whose value is None are omitted. When unmask is True secrets are shown verbatim.

remove_instance ​

python
def remove_instance(name: str, *, path: str | None = None, project_directory: str | None = None, working_directory: str | None = None) -> None

Remove a named instance from dw.json.

Raises

  • FileNotFoundError — if no dw.json exists.
  • ValueError — when removing the root instance or a missing instance.

resolve_config ​

python
async def resolve_config(overrides: NormalizedConfig | None = None, options: ResolveConfigOptions | None = None) -> ResolvedConfigImpl

Resolve configuration and return a rich ResolvedConfigImpl.

Resolution priority (highest to lowest): explicit overrides, sources_before, default sources (dw.json, ~/.mobify, package.json), sources_after, and globally-registered sources. Set options.replace_default_sources to omit the defaults.

resolve_library_entries ​

python
def resolve_library_entries(libraries: list[str | LibraryEntry] | None) -> list[LibraryEntry]

Normalize a libraries value to LibraryEntry objects.

Bare strings become LibraryEntry(id=..., site_library=False). Returns an empty list when the input is None.

save_dw_json ​

python
def save_dw_json(config: DwJsonMultiConfig, file_path: str) -> None

Save a dw.json to disk (2-space indent + trailing newline).

set_active_instance ​

python
def set_active_instance(name: str, *, path: str | None = None, project_directory: str | None = None, working_directory: str | None = None) -> None

Set a named instance as the active default.

Raises

  • FileNotFoundError — if no dw.json exists.
  • ValueError — if the instance is not found.

write_b2c_settings ​

python
def write_b2c_settings(settings: dict[str, Any], *, config_directory: str | None = None, environment: dict[str, str] | None = None, home_directory: str | None = None, platform: str | None = None) -> None

Write shared B2C settings atomically (mode 0o600, trailing newline).

Attributes ​

B2C_SETTINGS_FILENAME ​

python
B2C_SETTINGS_FILENAME = 'settings.json'

SENSITIVE_CONFIG_FIELDS ​

python
SENSITIVE_CONFIG_FIELDS: frozenset[str] = frozenset({'certificate_passphrase', 'client_secret', 'jwt_passphrase', 'mrt_api_key', 'password', 'slas_client_secret'})

DwJsonConfig ​

python
DwJsonConfig = dict[str, Any]

DwJsonMultiConfig ​

python
DwJsonMultiConfig = dict[str, Any]

ResolvedB2CConfig ​

python
ResolvedB2CConfig = ResolvedConfigImpl

global_config_source_registry ​

python
global_config_source_registry = ConfigSourceRegistry()