- name
- b2c-config
- description
- Configure B2C CLI/MCP authentication, instances, and project defaults; troubleshoot missing credentials, wrong targets, or configuration precedence. Routine inspection can use config_inspect or b2c setup inspect directly.
# B2C Config Skill
For routine inspection, call `config_inspect` or `b2c setup inspect` directly;
no skill read is required. Keep secrets redacted; manually reading `dw.json` is usually unnecessary. Read the relevant section
here when configuring sources or diagnosing unexpected/missing values.
| Task | CLI | MCP | Preference / difference | Fallback |
| ------------------------------------ | ---------------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| Inspect resolved configuration | `b2c setup inspect` | `config_inspect` | Either; same resolver, redacted by default. MCP accepts per-call project/instance overrides. | Inspect source files only for edits or unresolved issues. |
| Change configuration or authenticate | `b2c setup set`, `b2c setup`, `b2c auth` | No configuration-writing equivalent | CLI; inspect command help for the requested operation. | Edit the intended configuration source. |
If `b2c` is unavailable, use `npx @salesforce/b2c-cli`.
## How the CLI Discovers Configuration
The CLI **automatically detects** instance hostname, credentials, tenant ID, MRT API key, and other settings from multiple sources. **You usually do not need to pass `--server`, `--client-id`, `--client-secret`, `--username`, `--password`, `--tenant-id`, `--short-code`, or `--api-key` as flags** — the CLI picks them up from the environment or config files.
Sources, in resolution order (highest priority first):
1. **CLI flags and environment variables** — explicit values always win. Shell variables win over the env file; toolkit variables (`SFCC_*`, `MRT_*`) in the project's `.env` (or the file selected with `--dotenv-file` / `SFCC_DOTENV_FILE`) come next.
2. **Plugin sources (high priority)** — custom configuration plugins (e.g., secret managers).
3. **`dw.json`** — selected by `--config` / `SFCC_CONFIG`, the env file, the project-local file, or the shared global `dw.json`. Supports a single instance or a `configs[]` array with `active: true` / `-i <name>` selection.
4. **Storefront Next variables** — fallbacks that only fill fields missing from the selected `dw.json` entry (see below).
5. **`~/.mobify`** — home-directory file (MRT API key only).
6. **Plugin sources (low priority)**.
7. **`package.json`** under the `b2c` key — non-sensitive project defaults (e.g., `shortCode`, `clientId`, `mrtProject`). Sensitive fields like `clientSecret`/`password` are intentionally **not** allowed here.
Hostname protection applies between sources: if an env file's `SFCC_SERVER` differs from the selected `dw.json` entry's hostname, that whole entry is skipped (`HOSTNAME_MISMATCH` warning). If no source sets a tenant ID and the hostname is a sandbox hostname (`abcd-001.dx.commercecloud.salesforce.com`), the tenant ID is derived (`abcd_001`); a conflicting configured tenant ID produces a `TENANT_MISMATCH` warning. Conversely, if no source sets a hostname and the tenant ID is a sandbox tenant (`abcd_001`, including a Storefront Next `f_ecom_abcd_001` organization ID), the hostname is derived (`abcd-001.dx.commercecloud.salesforce.com`).
Use `--dotenv-file .env.staging` (or `SFCC_DOTENV_FILE`) to use another env file instead of `.env`; it replaces `.env` rather than layering on it. `--dotenv-file ""` uses no env file, and `--config ""` uses no `dw.json`.
For unexpected values, inspect resolved configuration and sources with `config_inspect` or `b2c setup inspect`.
### Storefront Next Environment Compatibility
The resolver accepts these Storefront Next variables as fallbacks, so a project
can reuse its existing B2C Commerce and SLAS configuration. The `PUBLIC__app__*`
and `COMMERCE_API_SLAS_SECRET` variables rank below `dw.json`: with `-i stg`,
stg's own tenant, short code, site, and SLAS client are kept and these only fill gaps.
| Storefront Next variable | Resolved field | Default toolkit variable |
| -------------------------------------------- | ------------------ | ------------------------- |
| `PUBLIC__app__commerce__api__clientId` | `slasClientId` | `SFCC_SLAS_CLIENT_ID` |
| `PUBLIC__app__commerce__api__organizationId` | `tenantId` | `SFCC_TENANT_ID` |
| `PUBLIC__app__commerce__api__shortCode` | `shortCode` | `SFCC_SHORTCODE` |
| `COMMERCE_API_SLAS_SECRET` | `slasClientSecret` | `SFCC_SLAS_CLIENT_SECRET` |
| `PUBLIC__app__defaultSiteId` | `siteId` | `SFCC_SITE_ID` |
| `MRT_PROJECT` | `mrtProject` | `MRT_PROJECT` |
| `MRT_TARGET` | `mrtEnvironment` | `MRT_ENVIRONMENT` |
Explicit flags, default toolkit variables, and the selected `dw.json` entry win over these fallbacks. `MRT_PROJECT` and `MRT_TARGET` are toolkit variables and keep toolkit priority.
### Shared Global Default
Use a shared fallback when the same `dw.json`-format file should work across the CLI, MCP server, and B2C DX VS Code extension:
```bash
b2c setup default-config set /path/to/dw.json
b2c setup default-config get
b2c setup default-config unset
```
The configuration-file selection order is: explicit `--config`; process `SFCC_CONFIG`; env file `SFCC_CONFIG`; project-local `dw.json`; global default. The global file never replaces an explicit or project-local choice. An explicit path (`--config` / `SFCC_CONFIG`) is used on its own, without the global file; `setup inspect` notes when the global default is skipped.
A discovered project `dw.json` and the global `dw.json` form one instance catalog. `-i <name>` searches the primary file first and then the global file, with same-name primary entries shadowing global entries. Each selected instance is complete—its fields are not merged with a matching entry in the other file. Instance list/remove/set-active operate across both files; create writes to the primary file when present and otherwise to the global `dw.json`.
Without `-i`, an active primary instance wins. A root-level primary configuration with no `active` field is its implicit default; set its root to `active: false` to opt it out and allow an active/default global instance to be selected. `b2c setup inspect` shows both files in its Sources section and marks the selected file.
### MCP Project Context
For MCP installation or tool selection, use `mcp/b2c-mcp-server` when
available or the [MCP configuration guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/mcp/configuration.md) (`b2c docs read mcp-configuration`).
These are client launch settings; `config_inspect` reports B2C values and sources,
not enabled toolsets or client filters. Project `.env` does not select MCP tools.
Local MCP project tools accept `projectDirectory`. Tools that resolve B2C/MRT configuration accept the same flat `projectDirectory`, `configPath`, and `instanceName` arguments. This override is especially important for plugin installs, where the MCP process working directory may be the plugin directory rather than the open project. For each configuration-aware call, the MCP server:
1. Parses `.env` from `projectDirectory`.
2. Applies all supported B2C/MRT environment variables from that file.
3. Selects a `dw.json`-format configuration file in this order: per-call `configPath`; startup `--config` / `SFCC_CONFIG`; project `.env` `SFCC_CONFIG`; `${projectDirectory}/dw.json`; shared global default. An explicit path is used without the shared global default. Storefront Next variables from the project `.env` only fill gaps below `dw.json`.
4. Resolves relative per-call `configPath` and project `.env` `SFCC_CONFIG` values from `projectDirectory`.
5. Selects `instanceName`, when supplied, from the primary file first and then the shared global `dw.json`, without changing either file.
6. Continues through the normal tooling configuration sources, including registered plugin sources, MRT credentials, and `package.json`.
7. Resolves specialized paths such as `cartridgeDirectory`, `buildDirectory`, and `outputDirectory` from the same root when relative.
Project `.env` values are scoped to that MCP call so one project's environment does not leak into another.
Each project/config-aware result includes an authoritative, compact `resolution` block. It reports the selected project, configuration file, instance, hostname, and specialized directories without relying on paths embedded in tool descriptions. Session and watch start calls retain it, and their list tools expose it for later follow-up calls. The MCP `config_inspect` tool additionally returns the full source graph and uses the same SDK resolver and registered CLI plugin configuration sources as `b2c setup inspect`. Use `projectDirectory`, `configPath`, and/or `instanceName` to compare the intended project, file, and instance.
### `dw.json` Key Casing
Field names in `dw.json` accept **both camelCase and kebab-case** — they're equivalent. For example:
| Either form works |
| ------------------------------------------------------------------------- |
| `clientId` ≡ `client-id` |
| `clientSecret` ≡ `client-secret` |
| `codeVersion` ≡ `code-version` |
| `tenantId` ≡ `tenant-id` |
| `shortCode` ≡ `short-code` ≡ `scapi-shortcode` |
| `webdavHostname` ≡ `webdav-hostname` ≡ `webdav-server` ≡ `secureHostname` |
| `certificatePassphrase` ≡ `certificate-passphrase` ≡ `passphrase` |
Legacy aliases like `server` (for `hostname`) are also still supported. If a value isn't being picked up, casing is rarely the cause — check spelling, then run `b2c setup inspect` to see what the CLI actually parsed.
A JSON Schema for `dw.json` is published at `https://salesforcecommercecloud.github.io/b2c-developer-tooling/schemas/dw.schema.json` (the B2C DX VS Code extension applies it automatically). Add it as `"$schema"` in a `dw.json` for editor validation and completion.
For the full field reference, see the [Configuration guide](https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/configuration.md) (`b2c docs read guide-configuration`).
## Authentication
Most commands that interact with a B2C Commerce instance require authentication. The CLI supports several methods:
- **Client credentials (API client):** Configure `clientId` and `clientSecret` in dw.json or environment variables. This is the default for automated/CI use.
- **Browser-based (implicit OAuth):** Use `--user-auth` on any OAuth-enabled command to authenticate interactively via the browser. This opens Account Manager in your default browser for login.
- **Basic auth:** Configure `username` and `password` for WebDAV operations.
- **Stateful sessions:** Use `b2c auth login` for persistent browser-based login sessions or `b2c auth client` for persistent client authentication. Later commands reuse the valid saved session when no other client is configured.
### `--user-auth` Flag
Many commands support `--user-auth` to use browser-based OAuth instead of client credentials. As of B2C Commerce release 26.8, SCAPI Admin APIs do not support this flow; migrated commands use OCAPI in `auto` mode, while explicit SCAPI reports an actionable authentication error before making an API request. User auth remains useful when:
- You don't have a `clientSecret` configured
- You need user-level permissions (e.g., Account Manager admin roles)
- You're working interactively
```bash
# Interactive browser-based auth for any OAuth command
b2c sandbox list --user-auth
b2c scapi schemas list --user-auth
b2c auth token --user-auth
```
Coding agents can also use `--user-auth` — the browser flow works in any environment where a browser can be opened. The flag is exclusive with `--auth-methods`.
**Running behind a proxy:** If `localhost:8080` isn't reachable by the browser (e.g., running in a container or behind a reverse proxy), set `SFCC_REDIRECT_URI` to the proxy URL. The local OAuth server still listens on the default port (or `SFCC_OAUTH_LOCAL_PORT`), but the redirect URI sent to Account Manager will use your proxy URL. Add the proxy URL to the API client's redirect URLs in Account Manager.
## Tenant ID and Organization ID
B2C Commerce uses two related identifiers:
- **Tenant ID** — the short form (e.g., `zzxy_prd` or `zzxy-prd`)
- **Organization ID** — the SCAPI form with `f_ecom_` prefix (e.g., `f_ecom_zzxy_prd`)
The CLI automatically normalizes and translates between these formats. You can provide either form in configuration or flags — the CLI handles the conversion. It also extracts tenant IDs from hostnames (e.g., `zzxy-prd.dx.commercecloud.salesforce.com` resolves to `zzxy_prd`).
In dw.json or environment variables, use the `tenantId` config key. The CLI will add the `f_ecom_` prefix when making SCAPI calls.
## Inspecting Configuration
Use `b2c setup inspect` to view the resolved configuration and understand where each value comes from. Use `b2c setup instance` commands to manage named instance configurations.
> **Note:** `b2c setup config` works as an alias for `b2c setup inspect`.
### When to Use
Use `b2c setup inspect` when you need to:
- Verify which configuration file is being used
- Check if environment variables are being read correctly
- Debug authentication failures by confirming credentials are loaded
- Understand credential source priority (dw.json vs env vars vs plugins)
- Identify hostname mismatch protection issues
- Verify MRT API key is loaded from ~/.mobify
### View Current Configuration
```bash
# Display resolved configuration (sensitive values masked by default)
b2c setup inspect
# View configuration for a specific instance from dw.json
b2c setup inspect -i staging
# View configuration with a specific config file
b2c setup inspect --config /path/to/dw.json
```
### Debug Sensitive Values
```bash
# Reveal secrets only when the user explicitly requests their values
b2c setup inspect --unmask
```
### JSON Output for Scripting
```bash
# Output as JSON for parsing in scripts
b2c setup inspect --json
# Pretty-print with jq
b2c setup inspect --json | jq '.config'
# Check which sources are loaded
b2c setup inspect --json | jq '.sources'
```
## Changing One Value
Use `b2c setup set`, `get`, and `unset` to change a single value. They pick the
file for you: the `dw.json` entry or project `.env` that already supplies the
value, otherwise the selected instance's `dw.json` entry. They refuse, without
writing, when the value comes from the shell environment, `~/.mobify`, or
another read-only source, or when no instance is selected.
```bash
b2c setup set scapi-schemas=./scapi-schemas
b2c setup set code-version version2 -i staging
Ver no GitHub