diff --git a/packages/b2c-dx-mcp/README.md b/packages/b2c-dx-mcp/README.md
index 45b1d0be..7a16462a 100644
--- a/packages/b2c-dx-mcp/README.md
+++ b/packages/b2c-dx-mcp/README.md
@@ -71,6 +71,86 @@ Override auto-discovery by specifying toolsets explicitly:
"args": ["--working-directory", "${workspaceFolder}", "--toolsets", "CARTRIDGES,MRT", "--allow-non-ga-tools"]
```
+### Prompting Tips and Examples
+
+AI assistants (like Cursor, Claude Desktop) automatically decide which MCP tools to use based on your prompts. To get the best results, use clear, specific prompts that describe what you want to accomplish.
+
+> ⚠️ **IMPORTANT**: **Explicitly mention "Use the MCP tool"** in your prompts for reliable tool usage. While AI assistants (like Cursor's Composer) can automatically select MCP tools based on context, explicit instructions ensure the assistant prioritizes MCP tools over general knowledge, especially when multiple approaches are possible. This is particularly important for getting project-specific, up-to-date information rather than generic responses.
+
+#### Best Practices
+
+1. **Always explicitly request MCP tool usage** (see warning above): Start prompts with "Use the MCP tool to..." or include "Use the MCP tool" in your request.
+2. **Be specific about your goal**: Instead of "help me with Storefront Next", say "Use the MCP tool to show me how to build a product detail page with authentication"
+3. **Mention the tool or domain explicitly**: Reference the framework (Storefront Next, PWA Kit), operation (deploy, discover), or domain (SCAPI, cartridges)
+4. **Use natural language**: Describe what you want to achieve, not the tool name
+5. **Provide context**: Mention your project type, what you're building, or what you need to learn
+6. **Ask for guidelines first**: When starting a new project or learning a framework, ask for development guidelines before writing code
+
+#### Examples by Tool Category
+
+##### Storefront Next Development Guidelines
+
+The `storefront_next_development_guidelines` tool provides critical architecture rules and best practices. **Use this tool first** when starting new Storefront Next development or when you need architecture guidance.
+
+**Good prompts:**
+- ✅ "I'm new to Storefront Next. Use the MCP tool to show me the critical rules I need to know."
+- ✅ "I need to build a product detail page. Use the MCP tool to show me best practices for data fetching and component patterns."
+- ✅ "I need to build a checkout form with authentication and validation. Use the MCP tool to show me how to handle form submissions, authentication, and internationalized error messages."
+- ✅ "Use the MCP tool to show me the data fetching patterns for Storefront Next."
+- ✅ "Show me all available Storefront Next development guidelines."
+
+**Available sections:**
+- `quick-reference` - Critical rules and architecture principles (default)
+- `data-fetching` - Data loading patterns with loaders
+- `state-management` - Client-side state management
+- `auth` - Authentication and session management
+- `components` - Component patterns and best practices
+- `styling` - Tailwind CSS 4, Shadcn/ui, styling guidelines
+- `page-designer` - Page Designer integration
+- `performance` - Performance optimization
+- `testing` - Testing strategies
+- `i18n` - Internationalization patterns
+- `config` - Configuration management
+- `extensions` - Extension development
+- `pitfalls` - Common pitfalls
+
+##### PWA Kit Development
+
+**Good prompts:**
+- ✅ "I'm starting a new PWA Kit project. Use the MCP tool to get the development guidelines."
+- ✅ "Use the MCP tool to create a new product listing page component in my PWA Kit project."
+- ✅ "Use the MCP tool to recommend React hooks for fetching product data in PWA Kit."
+- ✅ "Use the MCP tool to explore the SCAPI Shop API endpoints available for my PWA Kit storefront."
+
+##### SCAPI Discovery
+
+**Good prompts:**
+- ✅ "Use the MCP tool to discover what SCAPI endpoints are available for product data."
+- ✅ "Use the MCP tool to discover custom SCAPI APIs in my B2C instance."
+- ✅ "Use the MCP tool to show me all available SCAPI endpoints and their capabilities."
+- ✅ "Use the MCP tool to scaffold a new custom SCAPI API for order management."
+
+##### Cartridge Deployment
+
+**Good prompts:**
+- ✅ "Use the MCP tool to deploy my cartridges to the sandbox instance."
+- ✅ "Use the MCP tool to deploy only the app_storefront_base cartridge to production."
+- ✅ "Use the MCP tool to deploy cartridges from the ./cartridges directory and reload the code version."
+
+##### MRT Bundle Operations
+
+**Good prompts:**
+- ✅ "Use the MCP tool to build and push my Storefront Next bundle to staging."
+- ✅ "Use the MCP tool to push the bundle from ./build directory to Managed Runtime."
+- ✅ "Use the MCP tool to deploy my PWA Kit bundle to production with a deployment message."
+
+#### Tips for Better Results
+
+- **Start with guidelines**: When learning a new framework, ask for development guidelines first using "Use the MCP tool to get..."
+- **Combine related topics**: Ask for multiple related sections (e.g., "data fetching and components") in one request
+- **Provide project context**: Mention your project type (Storefront Next, PWA Kit, cartridges) for better tool selection
+- **Specify operations clearly**: For deployment operations, mention the target (sandbox, staging, production) and what to deploy
+
### Configuration
Credentials can be provided via **config files** (recommended), **environment variables**, or **flags**. Priority: Flags > Env vars > Config files.
@@ -205,13 +285,13 @@ Storefront Next development tools for building modern storefronts.
| Tool | Description |
|------|-------------|
-| `sfnext_development_guidelines` | Get Storefront Next development guidelines and best practices |
-| `sfnext_site_theming` | Configure and manage site theming for Storefront Next |
-| `sfnext_figma_to_component_workflow` | Convert Figma designs to Storefront Next components |
-| `sfnext_generate_component` | Generate a new Storefront Next component |
-| `sfnext_map_tokens_to_theme` | Map design tokens to Storefront Next theme configuration |
-| `sfnext_design_decorator` | Apply design decorators to Storefront Next components |
-| `sfnext_generate_page_designer_metadata` | Generate Page Designer metadata for Storefront Next components |
+| `storefront_next_development_guidelines` | Get Storefront Next development guidelines and best practices |
+| `storefront_next_site_theming` | Configure and manage site theming for Storefront Next |
+| `storefront_next_figma_to_component_workflow` | Convert Figma designs to Storefront Next components |
+| `storefront_next_generate_component` | Generate a new Storefront Next component |
+| `storefront_next_map_tokens_to_theme` | Map design tokens to Storefront Next theme configuration |
+| `storefront_next_design_decorator` | Apply design decorators to Storefront Next components |
+| `storefront_next_generate_page_designer_metadata` | Generate Page Designer metadata for Storefront Next components |
| `scapi_discovery` | Discover available SCAPI endpoints and capabilities |
| `scapi_custom_api_discovery` | Discover custom SCAPI API endpoints |
| `mrt_bundle_push` | Build, push bundle (optionally deploy) |
@@ -287,7 +367,7 @@ npx mcp-inspector --cli node bin/dev.js --toolsets all --allow-non-ga-tools --me
# Call a specific tool
npx mcp-inspector --cli node bin/dev.js --toolsets all --allow-non-ga-tools \
--method tools/call \
- --tool-name sfnext_design_decorator
+ --tool-name storefront_next_design_decorator
```
#### 2. IDE Integration
diff --git a/packages/b2c-dx-mcp/content/auth.md b/packages/b2c-dx-mcp/content/auth.md
new file mode 100644
index 00000000..b962df2f
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/auth.md
@@ -0,0 +1,62 @@
+# Authentication & Session Management
+
+## Architecture
+
+Split-cookie architecture with server/client contexts:
+
+- **Server middleware** (`auth.server.ts`): Manages SLAS tokens, writes cookies
+- **Client middleware** (`auth.client.ts`): Reads cookies, maintains cache
+- **React Context** (`AuthProvider`): Provides auth state to components
+
+## Cookie Design
+
+| Cookie Name | Purpose | User Type | Expiry | HttpOnly |
+|-------------|---------|-----------|--------|----------|
+| `cc-nx-g` | Guest refresh token | Guest | 30 days | No |
+| `cc-nx` | Registered refresh token | Registered | 90 days | No |
+| `cc-at` | Access token | Both | 30 min | No |
+| `usid` | User session ID | Both | Matches refresh | No |
+| `customerId` | Customer ID | Registered | Matches refresh | No |
+
+**Key Points**:
+
+- Only ONE refresh token exists (guest OR registered, never both)
+- User type derived from which refresh token exists
+- Cookies auto-namespaced with `siteId`
+- Tokens auto-refresh when expired
+
+## Usage in Loaders/Actions
+
+```typescript
+import { getAuth } from '@/middlewares/auth.server';
+
+export function loader({ context }: LoaderFunctionArgs) {
+ const auth = getAuth(context);
+
+ // Access auth properties
+ const accessToken = auth.access_token;
+ const customerId = auth.customer_id;
+ const isGuest = auth.userType === 'guest';
+ const isRegistered = auth.userType === 'registered';
+
+ return { isGuest, customerId };
+}
+```
+
+## Usage in Components
+
+```typescript
+import { useAuth } from '@/providers/auth';
+
+export function MyComponent() {
+ const auth = useAuth();
+
+ if (auth?.userType === 'guest') {
+ return ;
+ }
+
+ return
Welcome, customer {auth?.customer_id}
;
+}
+```
+
+**Reference:** See README-AUTH.md for complete authentication documentation.
diff --git a/packages/b2c-dx-mcp/content/components.md b/packages/b2c-dx-mcp/content/components.md
new file mode 100644
index 00000000..d2dfe1a5
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/components.md
@@ -0,0 +1,123 @@
+# Component Patterns
+
+## Use the `createPage` HOC
+
+The `createPage` higher-order component standardizes page patterns with built-in Suspense and page key handling:
+
+```typescript
+import { use } from 'react';
+import { createPage } from '@/components/create-page';
+
+// Define your view component
+function ProductView({
+ product,
+ category
+}: {
+ product: Promise;
+ category?: Promise
+}) {
+ const productData = use(product);
+ const categoryData = category ? use(category) : null;
+
+ return (
+
+ );
+}
+
+// ⚠️ OK - Single Suspense boundary (less granular)
+export default createPage({
+ component: ProductView,
+ fallback:
+});
+```
+
+## File Organization
+
+```
+src/components/product-tile/
+├── index.tsx # Component
+├── index.test.tsx # Tests
+└── stories/
+ ├── index.stories.tsx # Storybook stories
+ └── __snapshots__/ # Storybook snapshots (optional)
+ └── product-tile-snapshot.tsx.snap
+
+# Skeleton components are separate components
+src/components/product-skeleton/
+├── index.tsx
+├── index.test.tsx
+└── stories/
+ └── index.stories.tsx
+```
+
+## Styling
+
+**Tailwind CSS 4** is the only styling approach allowed. Use utility classes directly in components.
+
+**Key rules:**
+
+- ✅ Use Tailwind utility classes
+- ✅ Use `cn()` utility for conditional classes
+- ❌ NO inline styles, NO CSS modules, NO separate CSS files
+
+**See `styling` section for:** Tailwind CSS 4, Shadcn/ui components, icons, responsive design, theme configuration, dark mode, best practices
+
+## Best Practices
+
+1. **Extract view components** - Separate data handling from presentation
+2. **Type safety** - Define proper TypeScript interfaces
+3. **Consistent fallbacks** - Reusable skeleton components
+4. **Colocate tests** - Keep tests next to components
+5. **Story coverage** - Create stories for all reusable components
+6. **Tailwind utilities only** - Use Tailwind CSS classes, avoid inline styles or CSS modules
diff --git a/packages/b2c-dx-mcp/content/config.md b/packages/b2c-dx-mcp/content/config.md
new file mode 100644
index 00000000..5b45328f
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/config.md
@@ -0,0 +1,180 @@
+# Configuration Management
+
+## Overview
+
+All configuration is centralized in `config.server.ts` with environment variable overrides via `.env` files. The configuration system provides type-safe access to app settings with automatic parsing and validation.
+
+## Required Variables
+
+Copy `.env.default` to `.env` and set these required Commerce Cloud credentials:
+
+```bash
+PUBLIC__app__commerce__api__clientId=your-client-id
+PUBLIC__app__commerce__api__organizationId=your-org-id
+PUBLIC__app__commerce__api__siteId=your-site-id
+PUBLIC__app__commerce__api__shortCode=your-short-code
+PUBLIC__app__defaultSiteId=your-site-id
+PUBLIC__app__commerce__sites='[{"id":"your-site-id","defaultLocale":"en-US","defaultCurrency":"USD","supportedLocales":[{"id":"en-US","preferredCurrency":"USD"}],"supportedCurrencies":["USD"]}]'
+```
+
+**Note:** The `commerce.sites` array defines your site configuration including locales, currencies, and supported options. See `.env.default` for a complete example with multiple locales and currencies.
+
+## Adding Configuration
+
+1. **Define type in `src/config/schema.ts`**:
+
+```typescript
+export type Config = {
+ app: {
+ myFeature: {
+ enabled: boolean;
+ maxItems: number;
+ };
+ };
+};
+```
+
+2. **Add defaults in `config.server.ts`**:
+
+```typescript
+export default defineConfig({
+ app: {
+ myFeature: {
+ enabled: false,
+ maxItems: 10,
+ },
+ },
+});
+```
+
+3. **Override via environment variables**:
+
+```bash
+PUBLIC__app__myFeature__enabled=true
+PUBLIC__app__myFeature__maxItems=20
+```
+
+## Usage Patterns
+
+**In React Components**:
+
+```typescript
+import { useConfig } from '@/config';
+
+export function MyComponent() {
+ const config = useConfig();
+
+ if (config.myFeature.enabled) {
+ const maxItems = config.myFeature.maxItems;
+ // Your feature code
+ }
+}
+```
+
+**In Server Loaders/Actions**:
+
+```typescript
+import { getConfig } from '@/config';
+
+export function loader({ context }: LoaderFunctionArgs) {
+ const config = getConfig(context);
+
+ if (config.myFeature.enabled) {
+ // Your loader code
+ }
+}
+```
+
+**In Client Loaders**:
+
+```typescript
+import { getConfig } from '@/config';
+
+export function clientLoader() {
+ const config = getConfig(); // No context needed - uses window.__APP_CONFIG__
+
+ if (config.myFeature.enabled) {
+ // Your loader code
+ }
+}
+```
+
+**Note:** `getConfig()` and `useConfig()` return `AppConfig` which is the `app` section of the full `Config` type. So you access properties directly (e.g., `config.myFeature.enabled`) without the `app` prefix.
+
+## Environment Variable Rules
+
+Use the `PUBLIC__` prefix with double underscores (`__`) to set any config path:
+
+```bash
+# Environment variable → Config path (in Config type) → Access via getConfig()/useConfig()
+PUBLIC__app__commerce__sites='[...]' → config.app.commerce.sites → config.commerce.sites
+PUBLIC__app__defaultSiteId=RefArchGlobal → config.app.defaultSiteId → config.defaultSiteId
+PUBLIC__app__myFeature__enabled=true → config.app.myFeature.enabled → config.myFeature.enabled
+```
+
+**Multi-site Configuration Example:**
+
+```bash
+PUBLIC__app__commerce__sites='[
+ {
+ "id": "RefArchGlobal",
+ "defaultLocale": "en-US",
+ "defaultCurrency": "USD",
+ "supportedLocales": [
+ {"id": "en-US", "preferredCurrency": "USD"},
+ {"id": "de-DE", "preferredCurrency": "EUR"}
+ ],
+ "supportedCurrencies": ["USD", "EUR"]
+ }
+]'
+```
+
+**Accessing Site Configuration:**
+
+```typescript
+const config = getConfig(context);
+const currentSite = config.commerce.sites[0]; // Get first site
+const locale = currentSite.defaultLocale; // "en-US"
+const currency = currentSite.defaultCurrency; // "USD"
+```
+
+Values are automatically parsed (numbers, booleans, JSON arrays/objects).
+
+Rules:
+1. **`PUBLIC__` prefix**: Exposed to browser (client-safe values)
+2. **No prefix**: Server-only (secrets, never exposed)
+3. **`__` separator**: Navigate nested paths (`PUBLIC__app__commerce__sites`)
+4. **Case-insensitive**: All casings work (normalized to match `config.server.ts`)
+5. **Auto-parsing**: Strings, numbers, booleans, JSON arrays/objects
+6. **Validation**: Paths must exist in `config.server.ts` (prevents typos)
+7. **Depth limit**: Maximum 10 levels deep (use JSON values for deeper nesting)
+8. **Path precedence**: More specific paths override less specific ones
+9. **Protected paths**: `app__engagement` cannot be overridden via environment variables
+10. **MRT limits**: Variable names max 512 characters, total PUBLIC__ values max 32KB
+
+**Note:** Site configuration (locales, currencies) is now managed via `PUBLIC__app__commerce__sites` array instead of individual `PUBLIC__app__site__locale` variables. This enables multi-site support.
+
+**Setting nested objects with JSON:**
+
+```bash
+# Instead of multiple variables:
+PUBLIC__app__myFeature__option1=value1
+PUBLIC__app__myFeature__option2=value2
+
+# Use a single JSON value:
+PUBLIC__app__myFeature='{"option1":"value1","option2":"value2","nested":{"enabled":true}}'
+```
+
+## Security
+
+```bash
+# ✅ Safe for client (PUBLIC__ prefix)
+PUBLIC__app__commerce__api__clientId=abc123
+
+# ✅ Server-only (no prefix)
+COMMERCE_API_SLAS_SECRET=your-secret
+```
+
+Read server-only secrets directly from `process.env` - never add to config.
+
+**Reference:** See src/config/README.md for complete configuration documentation.
diff --git a/packages/b2c-dx-mcp/content/data-fetching.md b/packages/b2c-dx-mcp/content/data-fetching.md
new file mode 100644
index 00000000..111e5889
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/data-fetching.md
@@ -0,0 +1,323 @@
+# Data Fetching Patterns
+
+## Loader Functions
+
+**IMPORTANT**: This project **mandates server-only data loading**. Every UI route must only export a `loader` function.
+
+### Critical Rule: Synchronous Loaders for Streaming
+
+**IMPORTANT**: Loaders should be **synchronous functions that return objects containing promises**, NOT async functions. This enables non-blocking page transitions and streaming SSR.
+
+```typescript
+// ✅ CORRECT - Synchronous loader returning promises
+export function loader({ context }: LoaderFunctionArgs): ProductPageData {
+ const clients = createApiClients(context);
+ return {
+ product: clients.shopperProducts.getProduct({...}), // Promise - streams
+ reviews: clients.shopperProducts.getReviews({...}), // Promise - streams
+ };
+}
+
+// ❌ AVOID - Async loader blocks page transitions
+export async function loader({ context }: LoaderFunctionArgs): Promise {
+ const product = await clients.shopperProducts.getProduct({...}); // Blocks!
+ return { product };
+}
+```
+
+**Why this matters:**
+- Async loaders with `await` **block the entire page transition** until all data resolves
+- Synchronous loaders returning promises allow React to **stream data progressively**
+- Each promise resolves independently, enabling granular Suspense boundaries
+- Users see content as it becomes available, not all at once
+
+**Behavior**:
+- Initial load: Runs on server (SSR)
+- Navigation: Runs on server (XHR/fetch to server)
+- SCAPI requests always on MRT
+
+## Data Loading Strategies
+
+### Pattern 1: Awaited Data (Blocking)
+
+```typescript
+// ⚠️ BLOCKS rendering until all data is ready
+export async function loader({ params, context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+ return {
+ product: await clients.shopperProducts.getProduct({
+ params: { path: { id: params.productId } }
+ }).then(({ data }) => data)
+ };
+}
+```
+
+**Use when:** Critical data must be available before rendering (SEO, above-the-fold content)
+
+### Pattern 2: Deferred Data (Streaming)
+
+```typescript
+// ✅ RECOMMENDED - Streams data progressively
+export function loader({ params, context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+ return {
+ // Return promises directly - they'll stream to client
+ product: clients.shopperProducts.getProduct({
+ params: { path: { id: params.productId } }
+ }).then(({ data }) => data),
+
+ reviews: clients.shopperProducts.getReviews({
+ params: { path: { id: params.productId } }
+ }).then(({ data }) => data)
+ };
+}
+```
+
+**Use when:** Non-critical data can load after initial render
+
+### Pattern 3: Mixed Strategy
+
+```typescript
+// ✅ BEST OF BOTH - Critical data awaited, rest streamed
+export async function loader({ params, context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+
+ // Await critical data
+ const product = await clients.shopperProducts.getProduct({
+ params: { path: { id: params.productId } }
+ }).then(({ data }) => data);
+
+ return {
+ product, // Resolved
+ reviews: clients.shopperProducts.getReviews({
+ params: { path: { id: params.productId } }
+ }).then(({ data }) => data), // Streamed
+ recommendations: clients.shopperProducts.getRecommendations({
+ params: { path: { id: params.productId } }
+ }).then(({ data }) => data) // Streamed
+ };
+}
+```
+
+## Action Functions
+
+Handle mutations (form submissions, cart updates):
+
+```typescript
+import {data, redirect} from 'react-router';
+
+export async function action({request, context}: ActionFunctionArgs) {
+ const formData = await request.formData();
+ const productId = formData.get('productId') as string;
+
+ const clients = createApiClients(context);
+
+ try {
+ await clients.shopperBasketsV2.addItemToBasket({
+ params: {
+ path: {basketId},
+ body: {productId, quantity: 1},
+ },
+ });
+
+ return data({success: true});
+ } catch (error) {
+ return data({success: false, error: error.message}, {status: 400});
+ }
+}
+```
+
+## Interactive Data Fetching: useScapiFetcher
+
+For on-demand, user-triggered data fetching (after page load), use the `useScapiFetcher` hook instead of loaders.
+
+### `loader` vs `useScapiFetcher`
+
+| Aspect | `loader` | `useScapiFetcher` |
+|--------|----------|-------------------|
+| **When it runs** | Route navigation (page load) | On-demand (user interaction) |
+| **Triggered by** | URL change | Component code (useEffect, button click) |
+| **Data availability** | Before/during component render (streamed) | After component mounts |
+| **Execution context** | Server (MRT) | Triggers server route |
+| **Use case** | Initial page data | Dynamic, interactive fetching |
+
+### How `useScapiFetcher` Works
+
+```text
+Component calls useScapiFetcher()
+ ↓
+Hook builds URL: /resource/api/client/{encoded-params}
+ ↓
+fetcher.load() or fetcher.submit()
+ ↓
+resource.api.client.$resource.ts loader/action runs ON SERVER
+ ↓
+createApiClients(context) makes SCAPI call (server-side)
+ ↓
+JSON response returned to component
+```
+
+**Important:** Even though you call `useScapiFetcher` from the browser, the actual SCAPI requests still happen **on the server** through the resource route, keeping credentials secure.
+
+### Example: Search Suggestions
+
+```typescript
+import { useScapiFetcher } from '@/hooks/use-scapi-fetcher';
+import { useMemo, useCallback } from 'react';
+
+export function useSearchSuggestions({ q, limit, currency }) {
+ // Prepare SCAPI parameters
+ const parameters = useMemo(
+ () => ({
+ params: {
+ query: { q, limit, currency }
+ }
+ }),
+ [q, limit, currency]
+ );
+
+ // Hook automatically routes to server
+ const fetcher = useScapiFetcher(
+ 'shopperSearch', // SCAPI client
+ 'getSearchSuggestions', // Method name
+ parameters // Parameters
+ );
+
+ const refetch = useCallback(async () => {
+ await fetcher.load(); // Triggers server request
+ }, [fetcher]);
+
+ return {
+ data: fetcher.data,
+ isLoading: fetcher.state === 'loading',
+ refetch
+ };
+}
+```
+
+### When to Use Each Approach
+
+| Scenario | Use |
+|----------|-----|
+| Load product data when visiting `/product/123` | `loader` |
+| Load checkout data | `loader` |
+| Search suggestions as user types | `useScapiFetcher` |
+| Update customer profile in modal | `useScapiFetcher` |
+| Load recommendations after page loads | `useScapiFetcher` |
+| Fetch bonus products when modal opens | `useScapiFetcher` |
+| Infinite scroll / Load more | `useScapiFetcher` |
+
+### Timeline Comparison
+
+```text
+┌─────────────────────────────────────────────────────────────────┐
+│ loader (Server) │
+├─────────────────────────────────────────────────────────────────┤
+│ User clicks link → Server loader() → Stream data → Page render │
+│ │
+│ Timeline: [navigate] → [server fetch] → [stream to client] │
+│ │
+│ Data available: Streamed during render via Suspense │
+└─────────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────────┐
+│ useScapiFetcher │
+├─────────────────────────────────────────────────────────────────┤
+│ Page loads → Component mounts → User types → fetcher.load() │
+│ │
+│ Timeline: [render] → [user action] → [fetch] → [re-render] │
+│ │
+│ Data available: AFTER user action, component re-renders │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+## API Client Usage
+
+Always use `createApiClients(context)`:
+
+```typescript
+import { createApiClients } from '@/lib/api-clients';
+
+export function loader({ context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+
+ // All SCAPI clients with full type safety:
+ clients.shopperProducts.getProduct({...});
+ clients.shopperCustomers.getCustomer({...});
+ clients.shopperBasketsV2.getBasket({...});
+ clients.shopperSearch.productSearch({...});
+ clients.shopperOrders.getOrder({...});
+}
+```
+
+## Parallel vs Sequential
+
+```typescript
+// ✅ GOOD - Parallel requests
+export function loader({ context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+
+ return {
+ product: clients.shopperProducts.getProduct({...}),
+ reviews: clients.shopperProducts.getReviews({...}),
+ recommendations: clients.shopperProducts.getRecommendations({...})
+ };
+ // All three requests start simultaneously
+}
+
+// ❌ BAD - Sequential requests
+export async function loader({ context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+
+ const product = await clients.shopperProducts.getProduct({...});
+ const reviews = await clients.shopperProducts.getReviews({...});
+ const recommendations = await clients.shopperProducts.getRecommendations({...});
+
+ return { product, reviews, recommendations };
+ // Each request waits for the previous to complete
+}
+```
+
+## Understanding Data Flow
+
+### Initial Page Load (SSR)
+
+```text
+Browser → MRT Server
+ ↓
+ loader() runs on server
+ ↓
+ SCAPI requests on MRT
+ ↓
+ HTML response → Browser
+```
+
+**Key characteristics:**
+- The `loader()` runs on the server
+- SCAPI requests happen server-side (direct in production, proxied in dev)
+- Full HTML is returned to browser
+- Client hydrates the HTML
+
+### Subsequent Navigation (SPA)
+
+All routes use server `loader` for both SSR and SPA navigation:
+
+```text
+User clicks link → React Router intercepts
+ ↓
+ Browser makes fetch() to server
+ ↓
+ MRT Server receives request
+ ↓
+ Same loader() runs on server
+ ↓
+ SCAPI requests on MRT
+ ↓
+ JSON response → Browser
+ ↓
+ React updates DOM
+```
+
+**Key Point:** The loader function code is identical for both SSR and SPA navigation. The only difference is the response format (HTML vs JSON). This is why SCAPI credentials stay secure and MRT orchestration works consistently.
+
+**Reference:** See README-DATA.md for complete data fetching documentation.
diff --git a/packages/b2c-dx-mcp/content/extensions.md b/packages/b2c-dx-mcp/content/extensions.md
new file mode 100644
index 00000000..f656d31c
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/extensions.md
@@ -0,0 +1,80 @@
+# Extension Development
+
+## Structure
+
+```
+src/extensions/my-extension/
+├── plugin-config.json # Plugin configuration
+├── components/ # Extension components
+├── routes/ # Extension routes
+├── locales/ # Extension translations
+└── providers/ # Extension providers
+```
+
+## Plugin Configuration
+
+**Insert component into plugin point**:
+
+```json
+{
+ "components": [
+ {
+ "pluginId": "header.before.cart",
+ "path": "extensions/my-extension/components/badge.tsx",
+ "order": 0
+ }
+ ],
+ "contextProviders": [
+ {
+ "path": "extensions/my-extension/providers/my-provider.tsx",
+ "order": 0
+ }
+ ]
+}
+```
+
+## Extension Routes
+
+Files in `routes/` auto-register:
+
+```typescript
+// src/extensions/my-extension/routes/my-route.tsx
+export function loader() {
+ return { message: 'Hello' };
+}
+
+export default function MyRoute() {
+ const { message } = useLoaderData();
+ return
{message}
;
+}
+```
+
+## Extension Translations
+
+Auto-namespaced as `extPascalCase`:
+
+```
+src/extensions/my-extension/locales/
+├── en-US/translations.json
+└── it-IT/translations.json
+```
+
+```typescript
+const {t} = useTranslation('extMyExtension');
+t('welcome');
+```
+
+## Integration Markers
+
+```typescript
+// Single line
+/** @sfdc-extension-line SFDC_EXT_MY_FEATURE */
+import myFeature from '@extensions/my-feature';
+
+// Block
+{/* @sfdc-extension-block-start SFDC_EXT_MY_FEATURE */}
+My Feature
+{/* @sfdc-extension-block-end SFDC_EXT_MY_FEATURE */}
+```
+
+For full documentation, read: src/extensions/README.md
diff --git a/packages/b2c-dx-mcp/content/i18n.md b/packages/b2c-dx-mcp/content/i18n.md
new file mode 100644
index 00000000..ec0f4253
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/i18n.md
@@ -0,0 +1,121 @@
+# Internationalization (i18n)
+
+## Overview
+
+- **Server instance**: Has access to all translations for all languages
+- **Client instance**: Dynamically imports translations as JavaScript chunks
+- **Dual API**: `useTranslation()` for components, `getTranslation()` for everything else
+
+## Adding Translations
+
+**In `src/locales/{language}/translations.json`**:
+
+```json
+{
+ "product": {
+ "title": "Product Details",
+ "addToCart": "Add to Cart",
+ "greeting": "Hello, {{name}}!",
+ "itemCount": {
+ "zero": "No items",
+ "one": "{{count}} item",
+ "other": "{{count}} items"
+ }
+ }
+}
+```
+
+## Usage
+
+**2. Use in React components:**
+
+```typescript
+import { useTranslation } from 'react-i18next';
+
+export function ProductCard() {
+ const { t } = useTranslation('product');
+
+ return (
+
+
{t('title')}
+
+
{t('greeting', { name: 'John' })}
+
{t('itemCount', { count: 5 })}
+
+ );
+}
+```
+
+**3. Use in non-component code:**
+
+```typescript
+import { getTranslation } from '@/lib/i18next';
+
+// Client-side or utilities
+const { t } = getTranslation();
+const message = t('product:addToCart');
+
+// Server-side (loaders/actions)
+export function loader(args: LoaderFunctionArgs) {
+ const { t } = getTranslation(args.context);
+ return { title: t('product:title') };
+}
+```
+
+## Validation Schemas with Translations
+
+**CRITICAL**: Use factory pattern for Zod schemas to avoid race conditions:
+
+```typescript
+// ❌ WRONG - Module-level schema (race condition)
+export const schema = z.object({
+ email: z.string().email(t('validation:emailInvalid'))
+});
+
+// ✅ CORRECT - Factory function
+import type { TFunction } from 'i18next';
+
+export const createSchema = (t: TFunction) => {
+ return z.object({
+ email: z.string().email(t('validation:emailInvalid'))
+ });
+};
+
+// Usage in component
+import { useMemo } from 'react';
+import { useTranslation } from 'react-i18next';
+
+function MyForm() {
+ const { t } = useTranslation();
+ const schema = useMemo(() => createSchema(t), [t]);
+
+ const form = useForm({ resolver: zodResolver(schema) });
+}
+```
+
+## Language Switching
+
+```typescript
+import LocaleSwitcher from '@/components/locale-switcher';
+
+export function Footer() {
+ return ;
+}
+```
+
+## Extension Translations
+
+Extensions use `extPascalCase` namespace:
+
+```
+src/extensions/my-extension/locales/
+├── en-US/translations.json
+└── it-IT/translations.json
+```
+
+```typescript
+const {t} = useTranslation('extMyExtension');
+t('welcome');
+```
+
+**Reference:** See README-I18N.md for complete internationalization documentation.
diff --git a/packages/b2c-dx-mcp/content/page-designer.md b/packages/b2c-dx-mcp/content/page-designer.md
new file mode 100644
index 00000000..022f523a
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/page-designer.md
@@ -0,0 +1,86 @@
+# Page Designer Integration
+
+## Overview
+
+Page Designer is Commerce Cloud's visual editor in Business Manager: merchants build and edit storefront pages (home, category, etc.) without code. The app gets page structure (regions, components, attributes) from the **Shopper Experience API** and renders it via a **component registry** and ``.
+
+## Concepts
+
+| Concept | Role |
+|--------|------|
+| **Page** | Fetched in route loaders via `fetchPageFromLoader(args, { pageId })`. |
+| **Region** | Named area on a page; rendered with ``. |
+| **Component** | Content block (hero, grid, carousel, etc.) with a `typeId` and attributes; registered in `@/lib/registry`. |
+| **Registry** | Static registry in `@/lib/static-registry.ts` is **auto-generated** by the staticRegistry Vite plugin — do not edit by hand. |
+
+## Which pages use Page Designer
+
+Only **content pages** that merchants edit in Business Manager use Page Designer; cart, checkout, account, and auth do not.
+
+| Uses Page Designer | Does not |
+|--------------------|----------|
+| Home (`pageId: 'homepage'`), Category/PLP (`plp`), Search (`search`), Product/PDP (`pdp`) | Cart, Checkout, Account, Order confirmation, Auth |
+
+To add a new content page: define a page type and ID in Commerce Cloud, then in your route use `fetchPageFromLoader(args, { pageId })` and `collectComponentDataPromises(args, pagePromise)`, and render `` for each region.
+
+## Getting started
+
+### Route (new Page Designer page)
+
+- **In the loader**: call `fetchPageFromLoader(args, { pageId: '...' })` and `collectComponentDataPromises(args, pagePromise)`; return `page` and `componentData` (keep loaders synchronous; return promises for streaming).
+- **In the layout**: for each region, render `` with optional `fallbackElement` and `errorElement` for Suspense/error boundaries.
+- **On the route module**: add `@PageType({ name, description, supportedAspectTypes })` and `@RegionDefinition([{ id, name, description, maxComponents }])` so Business Manager knows the page type and regions. Example routes: home (`_app._index.tsx`), category/PLP (`_app.category.$categoryId.tsx`).
+
+### Component (new Page Designer component)
+
+- **Add a metadata class** with `@Component('typeId', { name, description })` and `@AttributeDefinition()` (and optionally `@AttributeDefinition({ type: 'image' })`, `type: 'url'`, etc.) for each prop you want editable in Page Designer. Use `@RegionDefinition([...])` if the component has nested regions (e.g. a grid with slots).
+- **Implement the React component** so it accepts those props (and strips Page Designer–only props like `component`, `page`, `componentData`, `designMetadata` before spreading to the DOM). If the component needs server data (e.g. products for a carousel), export a `loader({ componentData, context })` and optionally a `fallback` component; the registry calls the loader during `collectComponentDataPromises` and passes resolved data as the `data` prop.
+- **Use the MCP tool `storefront_next_design_decorator`** to generate decorators instead of writing them by hand. Example components: `components/hero/index.tsx`, `components/content-card/index.tsx`, `components/product-carousel/index.tsx`.
+
+### After changes
+
+- **Rebuild the app** so the static registry (`lib/static-registry.ts`) is regenerated by the staticRegistry Vite plugin. Do not edit the static registry by hand.
+
+### Design mode
+
+- **Edit** and **Preview** mode are detected from the request via `isDesignModeActive(request)` and `isPreviewModeActive(request)` from `@salesforce/storefront-next-runtime/design/mode`. The root layout exposes `pageDesignerMode` in loader data (`'EDIT' | 'PREVIEW' | undefined`) so the tree can adapt (e.g. show outlines, disable interactions) when running inside Page Designer.
+
+
+## MCP tools (recommended)
+
+Use the **B2C DX MCP server** for Page Designer work instead of hand-writing decorators and metadata. Configure the B2C DX MCP server in your IDE (e.g. in MCP settings) so these tools are available.
+
+### 1. `storefront_next_design_decorator` (STOREFRONTNEXT toolset)
+
+Adds Page Designer decorators to an existing React component so it can be used in Business Manager. The tool analyzes the component, picks suitable props, infers types (e.g. `*Url`/`*Link` → url, `*Image` → image, `is*`/`show*` → boolean), and generates `@Component('typeId', { name, description })`, `@AttributeDefinition()` on a metadata class, and optionally `@RegionDefinition([...])` for nested regions. It skips complex or UI-only props (e.g. className, style, callbacks).
+
+- **Auto mode** (fast): Ask in your IDE: *"Add Page Designer support to [ComponentName] with autoMode"*. The tool runs in one turn with no prompts.
+- **Interactive mode** (control): Ask *"Add Page Designer support to [ComponentName]"* and answer questions about typeId, which props to expose, types, and optional nested regions.
+
+### 2. `storefront_next_generate_page_designer_metadata` (STOREFRONTNEXT toolset)
+
+Generates Page Designer metadata JSON from decorated components, page types, and aspects. Writes files under the cartridge experience folder (e.g. `cartridges/app_storefrontnext_base/cartridge/experience/`). Use after adding or changing decorators so Business Manager has up-to-date component and page-type definitions.
+
+- **Full scan**: Run with no file list to process the whole project.
+- **Incremental**: Pass specific file paths to regenerate only those components.
+- **Dry run**: Use `dryRun: true` to see what would be generated without writing files.
+
+### 3. `cartridge_deploy` (CARTRIDGES toolset)
+
+Packages the cartridge, uploads it to Commerce Cloud via WebDAV, and unpacks it on the server. Requires Commerce Cloud credentials (e.g. `dw.json` or explicit config). Use after generating metadata so the new/updated metadata is available in Business Manager.
+
+### Typical workflow
+
+1. **`storefront_next_design_decorator`** — Add decorators to the component (use autoMode for a quick first pass).
+2. **`storefront_next_generate_page_designer_metadata`** — Generate metadata JSON so the component and regions appear in Page Designer.
+3. **`cartridge_deploy`** — Deploy to Commerce Cloud so merchants can use the component in Business Manager.
+
+## Best Practices
+
+1. **Keep loaders synchronous**: Return promises for Page Designer pages to enable streaming
+2. **Use registry for components**: Register all Page Designer components with proper `typeId`
+3. **Handle design mode**: Adapt UI when `pageDesignerMode` is `'EDIT'` or `'PREVIEW'`
+4. **Rebuild after registry changes**: Static registry is generated at build time
+5. **Use MCP tools**: Leverage `storefront_next_design_decorator` and `storefront_next_generate_page_designer_metadata` for faster development
+
+**Reference:** See README.md for complete Page Designer documentation and MCP tool setup.
diff --git a/packages/b2c-dx-mcp/content/performance.md b/packages/b2c-dx-mcp/content/performance.md
new file mode 100644
index 00000000..bc5e378d
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/performance.md
@@ -0,0 +1,80 @@
+# Performance Optimization
+
+## Bundle Size Limits
+
+The application enforces strict bundle size limits defined in `package.json` under the `bundlesize` configuration. Refer to `package.json` for the complete list of limits.
+
+**Check bundle size:**
+
+```bash
+pnpm bundlesize:test # Verify limits
+pnpm bundlesize:analyze # Analyze composition
+```
+
+## Built-in Metrics
+
+Enable in `config.server.ts`:
+
+```typescript
+{
+ performance: {
+ metrics: {
+ serverPerformanceMetricsEnabled: true,
+ clientPerformanceMetricsEnabled: true,
+ serverTimingHeaderEnabled: false // Debug only
+ }
+ }
+}
+```
+
+Tracks:
+
+- SSR operations and rendering time
+- SCAPI API calls with parallelization
+- Authentication operations
+- Client-side navigations
+
+## Best Practices
+
+### 1. Parallel Data Fetching
+
+**Key principle:** Return all promises simultaneously in loaders to enable parallel requests. Avoid sequential `await` calls.
+
+**Reference:** See `data-fetching` section for detailed parallel vs sequential patterns and code examples.
+
+### 2. Image Optimization
+
+Use the `DynamicImage` component with WebP format:
+
+```typescript
+import { DynamicImage } from '@/components/dynamic-image';
+
+
+```
+
+### 3. Progressive Streaming
+
+**Key principle:** Use synchronous loaders returning promises to enable progressive streaming. Await only critical data, stream the rest.
+
+**Reference:** See `data-fetching` section for detailed streaming patterns including mixed strategies (awaited + streamed).
+
+### 4. Lighthouse Audits
+
+Monitor performance metrics:
+
+- Preload critical CSS
+- Use WebP images by default
+- Lazy load below-the-fold content
+- Optimize font loading
+
+```bash
+pnpm lighthouse:ci # Run Lighthouse CI
+```
+
+**Reference:** See README-PERFORMANCE.md for complete performance optimization documentation.
diff --git a/packages/b2c-dx-mcp/content/pitfalls.md b/packages/b2c-dx-mcp/content/pitfalls.md
new file mode 100644
index 00000000..916a45be
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/pitfalls.md
@@ -0,0 +1,141 @@
+# Common Pitfalls
+
+## 1. Using Client Loaders/Actions
+
+```typescript
+// ❌ NEVER USE - Client loaders are not permitted
+export function clientLoader() { ... }
+
+// ❌ NEVER USE - Client actions are not permitted
+export function clientAction() { ... }
+
+// ✅ REQUIRED - Server-only data loading
+export function loader({ context }: LoaderFunctionArgs) {
+ const clients = createApiClients(context);
+ return { product: clients.shopperProducts.getProduct({...}) };
+}
+
+// ✅ REQUIRED - Server-only actions
+export async function action({ request, context }: ActionFunctionArgs) {
+ const clients = createApiClients(context);
+ // Handle mutation on server
+}
+```
+
+**Decision tree:**
+
+```text
+Need data for page render?
+└─ Use server `loader`
+
+Need to handle mutations (form submissions, cart updates)?
+└─ Use server `action`
+
+Need on-demand fetching after page load?
+└─ Use `useScapiFetcher` (search, modals, infinite scroll)
+```
+
+**Key Point:** ALL SCAPI requests happen on the server:
+- `loader`: Runs on server, SCAPI direct (prod) or proxied (dev)
+- `action`: Runs on server, handles mutations securely
+- `useScapiFetcher`: Triggers server route that calls SCAPI
+
+## 2. Module-Level i18n in Schemas
+
+```typescript
+// ❌ RACE CONDITION
+const schema = z.object({
+ email: z.string().email(t('error')),
+});
+
+// ✅ FACTORY PATTERN
+export const createSchema = (t: TFunction) => {
+ return z.object({
+ email: z.string().email(t('error')),
+ });
+};
+```
+
+## 3. Using Async Loaders (Blocks Page Transitions)
+
+```typescript
+// ❌ BLOCKS PAGE TRANSITIONS - Async loader with await
+export async function loader({ context }: LoaderFunctionArgs) {
+ const product = await fetchProduct(); // Blocks!
+ const reviews = await fetchReviews(); // Blocks!
+ return { product, reviews };
+}
+
+// ✅ NON-BLOCKING - Synchronous loader returning promises
+export function loader({ context }: LoaderFunctionArgs): PageData {
+ return {
+ product: fetchProduct(), // Streams progressively
+ reviews: fetchReviews(), // Streams progressively
+ };
+}
+```
+
+**Key insight:** Defining loaders as `async` and using `await` causes the entire page transition to block until all data resolves. Use synchronous loaders returning promises for streaming.
+
+**Reference:** See `data-fetching` section for comprehensive loader patterns including mixed strategies (awaited + streamed).
+
+## 4. Modifying shadcn/ui
+
+```typescript
+// ❌ NEVER modify src/components/ui/
+
+// ✅ Create wrapper
+import { Button } from '@/components/ui/button';
+export function MyButton(props) {
+ return ;
+}
+```
+
+## 5. Missing Namespace in i18n
+
+```typescript
+// ❌ MISSING NAMESPACE
+const {t} = useTranslation();
+t('title'); // Won't work
+
+// ✅ USE NAMESPACE
+const {t} = useTranslation('product');
+t('title'); // Works
+```
+
+## 6. Not Using Context in Server Loaders
+
+```typescript
+// ❌ MISSING CONTEXT
+export function loader() {
+ const config = getConfig(); // Wrong!
+}
+
+// ✅ PASS CONTEXT
+export function loader({ context }: LoaderFunctionArgs) {
+ const config = getConfig(context); // Correct
+}
+```
+
+## 7. Forgetting to Namespace i18n Keys
+
+```typescript
+// ❌ MISSING NAMESPACE
+const { t } = useTranslation();
+t('title'); // Won't work without namespace
+
+// ✅ USE NAMESPACE
+const { t } = useTranslation('product');
+t('title'); // Works
+
+// OR
+const { t } = getTranslation();
+t('product:title'); // Works
+```
+
+## 8. Using JavaScript Files
+
+```text
+❌ .js, .jsx, .mjs, .cjs files are BLOCKED
+✅ Use .ts, .tsx files only
+```
diff --git a/packages/b2c-dx-mcp/content/quick-reference.md b/packages/b2c-dx-mcp/content/quick-reference.md
new file mode 100644
index 00000000..d5feb071
--- /dev/null
+++ b/packages/b2c-dx-mcp/content/quick-reference.md
@@ -0,0 +1,226 @@
+# Storefront Next - Development Guidelines (Quick Reference)
+
+⚠️ **READ THESE CRITICAL RULES BEFORE WRITING ANY CODE** ⚠️
+
+## 🏗️ Architecture Overview
+
+**Server-rendered SPA** built on React Server Components:
+- **React Router 7** in framework mode
+- **Managed Runtime (MRT)** as data orchestration layer
+- **All SCAPI requests execute on MRT server** (both SSR and client-side navigation)
+
+**Key Point**: Client-side routing does NOT mean client-side data fetching. Loaders always run on the server.
+
+---
+
+## 🚨 Non-Negotiable Rules
+
+### 1. Server-Only Data Loading
+
+✅ **REQUIRED**: Use server `loader` for all SCAPI data fetching
+
+```typescript
+export function loader({ context }: LoaderFunctionArgs): PageData {
+ const clients = createApiClients(context);
+ return {
+ product: clients.shopperProducts.getProduct({...}), // Promise - streams
+ reviews: clients.shopperProducts.getReviews({...}), // Promise - streams
+ };
+}
+```
+
+**Why?** Keeps SCAPI requests on MRT server for security, performance, and bundle size.
+
+### 2. Synchronous Loaders (Not Async)
+
+✅ **CRITICAL**: Loaders must be **synchronous functions that return promises**, NOT async functions.
+
+```typescript
+// ✅ CORRECT - Enables streaming
+export function loader({ context }: LoaderFunctionArgs): PageData {
+ const clients = createApiClients(context);
+ return {
+ product: clients.shopperProducts.getProduct({...}), // Promise - streams
+ };
+}
+
+// ❌ AVOID - Blocks page transitions
+export async function loader({ context }: LoaderFunctionArgs) {
+ const product = await clients.shopperProducts.getProduct({...}); // Blocks!
+ return { product };
+}
+```
+
+**Why?** Async loaders block page transitions. Synchronous loaders enable progressive streaming.
+
+### 3. TypeScript-Only
+
+✅ **REQUIRED**: Use `.ts` and `.tsx` file extensions
+❌ **BLOCKED**: `.js`, `.jsx`, `.mjs`, `.cjs` files are forbidden by ESLint
+
+### 4. Use createPage() HOC
+
+✅ **RECOMMENDED**: Use `createPage()` for standardized page patterns
+
+```typescript
+import { createPage } from '@/components/create-page';
+
+const ProductPage = createPage({
+ component: ProductView,
+ fallback:
+});
+
+export default ProductPage;
+```
+
+### 5. Tailwind CSS 4 Only
+
+✅ **REQUIRED**: Use Tailwind utility classes only
+❌ **BLOCKED**: No inline styles (`style={{...}}`), no CSS modules, no separate CSS files
+
+```typescript
+// ✅ CORRECT - Tailwind utilities
+