# WebCake Storefront (npm · webcake-storefront-mcp)

Build pages and manage products, orders, and content on the WebCake/StoreCake storefront builder.

- Trust score: 57/100 (low)
- Change this week: +12
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `store.toolvn.io.vn`: 36/100, [markdown](https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/store.md), [page](https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/store)
- npm · `webcake-storefront-mcp`: 57/100 (this document), [markdown](https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/webcake-storefront-mcp.md), [page](https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/webcake-storefront-mcp)

## Channel facts

- Registry: `npm`
- Package: `webcake-storefront-mcp`
- Version: `1.31.8`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 70/100
  - No malware found by supply-chain analysis.
  - CVE check failed: a known high-severity CVE affects sharp 0.34.5, a direct dependency. A fixed version is available.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (157 of 161), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 35 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 41/100
  - AI-judged instruction clarity (poor).
  - Context-footprint check failed: tool/resource definitions use about 16012 tokens (~118/item across 135 items; 135 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 99% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add vuluu2k-webcake-storefront-mcp -- npx -y webcake-storefront-mcp
```

### Codex

```bash
codex mcp add vuluu2k-webcake-storefront-mcp -- npx -y webcake-storefront-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "vuluu2k-webcake-storefront-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "webcake-storefront-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add vuluu2k-webcake-storefront-mcp --command npx --arg -y --arg webcake-storefront-mcp
```

### Hermes

```yaml
mcp_servers:
  vuluu2k-webcake-storefront-mcp:
    command: "npx"
    args: ["-y", "webcake-storefront-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "vuluu2k-webcake-storefront-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "webcake-storefront-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 57, +37)

- [security regression] GHSA-f88m-g3jw-g9cj affects this package: high
- [security regression] Provenance: unverified → fail
- [security regression] Known CVEs: unverified → fail
- [security improvement] Install scripts: unverified → pass
- [security improvement] Malware scan: unverified → pass
- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] Schema quality: unverified → poor
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Stability: unverified → 0.23
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional] Licence: MIT

### 2026-08-01 (score 20, −7)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-31 (score 27, +2)

- [security regression] Malware scan: pass → unverified
- [functional regression] Security disclosure: unverified → fail
- [functional regression] Dependency health: partial → unverified
- [functional improvement] Tool coverage: unverified → 100

### 2026-07-29 (score 25, −20)

- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Security disclosure: fail → unverified
- [functional improvement] Dependency health: unverified → partial
- [functional] First check of Schema quality: unverified

### 2026-07-27 (score 45)

First indexed and scored.

## MCP tools (135)

### `get_intake_guide` (~90 tokens)

Get the INTAKE questionnaire + build flow to run BEFORE creating a new site/store/page. Call this at the start of any fresh build: ask the user this one short batch (plain words, with defaults), restate the plan, get a yes, THEN build. Skip only for tiny edits, data questions, or when the user already gave the brief / says 'just do it'.

### `get_current_context` (~39 tokens)

Show current connection context: which site_id, API URL, session, and account info. Call this first to confirm you're working on the right site

### `list_my_sites` (~58 tokens)

List all sites accessible by the current account. Use this to find a site_id before switching

Input parameters:

- `limit` (number): Items per page
- `page` (number): Page number
- `term` (string): Search by site name

### `create_site` (~290 tokens)

Create a brand-new storefront site for the current account, then (by default) switch to it
and return an EMPTY, CLEAN site (no sample products/categories) ready for element composition.
The backend auto-seeds off-theme sample products + categories (and a sample blog); by default
this tool DELETES that seed right after creating the site (keep the non-deletable default "All"
category) so you start from a blank, on-theme store. Pass keep_seed:true to keep the sample data.
The site has NO pages — after this, compose a homepage from elements: get_build_guide →
new_section/new_element → build_page (type:'main', is_homepage:true).
Note: free accounts are limited to 4 sites (creation fails with a quota error past that).

Input parameters:

- `keep_seed` (boolean): Keep the backend's sample products/categories/blog instead of auto-deleting them. Default false = start from a clean, empty site.
- `name` (string, required): Display name of the new site, e.g. 'My Coffee Shop'
- `slug` (string, required): URL-safe site slug (lowercase letters, digits, hyphens), e.g. 'my-coffee-shop'. Becomes the preview subdomain and must be unique.
- `switch_to` (boolean): Switch the session to the new site after creating it (saved for next session). Default true.

### `switch_site` (~69 tokens)

Switch to a different site by site_id. All subsequent tool calls will target the new site.
The choice is saved to local database — next session will auto-connect to this site.
Use list_my_sites first to find the site_id

Input parameters:

- `site_id` (string, required): The site ID to switch to

### `update_auth` (~99 tokens)

Update authentication credentials. All values are saved to local database — next session auto-restores them.
Get token and session_id from browser DevTools → Network tab → copy from any API request headers

Input parameters:

- `api_url` (string): API base URL (e.g. https://api.storecake.io)
- `session_id` (string): Session ID (from x-session-id header)
- `token` (string): JWT Bearer token (from Authorization header)

### `toggle_confirm_mode` (~221 tokens)

Toggle update confirmation mode. Controls whether update tools ask for user confirmation before saving.
\- "always_confirm" (default): Shows diff first, requires user approval before saving. Safer.
\- "auto_apply": Applies changes immediately without preview. Faster but riskier.
Current mode is saved to database and persists across sessions.

Call this tool when the user says things like:
→ "tự động xác nhận" / "auto confirm" / "không cần hỏi" / "don't ask" / "apply directly" → mode: "auto_apply"
→ "hỏi trước khi lưu" / "luôn hỏi" / "always ask" / "confirm before saving" / "xác nhận trước" → mode: "always_confirm"

Input parameters:

- `mode` (string, required): Set to "always_confirm" (safe) or "auto_apply" (fast). Map user intent: "tự động"/"auto"/"không cần hỏi" → auto_apply, "hỏi lại"/"confirm"/"luôn hỏi" → always_confirm

### `list_cms_files` (~26 tokens)

List all CMS files (HTTP functions, cron jobs, ...) for the site

### `create_cms_file` (~61 tokens)

Create a new CMS file. Types: "http_function", "jobs_config", "default"

Input parameters:

- `content` (string, required): Code content (JavaScript or JSON)
- `name` (string, required): File name
- `type` (string): File type

### `update_cms_file` (~49 tokens)

Update the code content of an existing CMS file

Input parameters:

- `content` (string, required): New code content
- `id` (string, required): CMS file ID
- `name` (string): Rename file

### `get_http_function` (~148 tokens)

Get the main HTTP function file. Choose the right mode for your task:
\- overview=true: function names + line ranges only, NO code body. Use for: browsing, understanding structure, finding which function to read.
\- overview=false (DEFAULT): full code + collection schemas. Use for: writing new features, refactoring, understanding full context.
Tip: for small fixes, use overview first then get_http_function_snippet to read just that function.
Add include_guide=true on first call to get the coding guide

Input parameters:

- `include_guide` (boolean): Include coding guide (only needed once)
- `overview` (boolean): true=function list only, false=full code (default)

### `get_http_function_snippet` (~52 tokens)

Read specific function(s) by name. Much more token-efficient than reading the full file

Input parameters:

- `function_names` (array, required): Function names (e.g. ['get_Products', 'post_CreateOrder'])

### `edit_http_function` (~174 tokens)

Edit the HTTP function file by function name — best for targeted changes (fix a bug, rename, add one function).
For writing multiple new functions or major refactors, use update_http_function with full content instead.
Actions:
\- "replace_function": replace an ENTIRE function by name with new code. Server finds function boundaries automatically.
\- "add": append new function code at end of file.
\- "remove": remove a function by name.
\- "update_imports": replace the import block (lines before first export).
Returns updated function list after edit.

Input parameters:

- `action` (string, required): Edit action
- `code` (string): New function code (for replace_function and add) or new import block (for update_imports)
- `function_name` (string): Target function name (for replace_function and remove)

### `update_http_function` (~77 tokens)

Write the FULL HTTP function file content. Best for: writing new features, major refactors, or changes that touch multiple functions.
For small targeted edits (fix one function, add one function), use edit_http_function instead.
After update, auto-deploys to the bundle service

Input parameters:

- `content` (string, required): Full JS code content

### `run_function` (~73 tokens)

Run a deployed HTTP function. function_name excludes method prefix.
Example: "get_Products" → function_name="Products", method="GET"

Input parameters:

- `function_name` (string, required): Function name without method prefix (e.g. 'Products')
- `method` (string): HTTP method
- `params` (object): Parameters

### `debug_function` (~57 tokens)

Run JS code in debug mode (without deploying). Returns execution result and console logs

Input parameters:

- `content` (string, required): JS code to debug
- `function_name` (string, required): Function name to run
- `params` (object): Test parameters

### `save_file_version` (~54 tokens)

Save a version snapshot of a CMS file for rollback

Input parameters:

- `cms_file_id` (string, required): CMS file ID
- `content` (string, required): Content to save
- `is_public` (boolean): Mark as public version

### `get_file_versions` (~65 tokens)

View version history of a CMS file. Each version includes its saved content — to restore, pass that content back to update_http_function (the http_function file) or update_cms_file, or use restore_file_version.

Input parameters:

- `cms_file_id` (string, required): CMS file ID

### `restore_file_version` (~100 tokens)

Roll a CMS file back to a saved version in one step: reads the version's content and writes it back to the file. Omit version_id to restore the most recent snapshot. Tip: save_file_version on the current content first if you want an undo point.

Input parameters:

- `cms_file_id` (string, required): CMS file ID to restore
- `version_id` (string): Which version to restore (from get_file_versions). Omit = latest snapshot.

### `toggle_debug_render` (~30 tokens)

Toggle debug render mode for a CMS file

Input parameters:

- `cms_file_id` (string, required): CMS file ID

### `list_pages` (~21 tokens)

List all pages of the site (metadata only, without source)

### `get_page_source` (~51 tokens)

Get page source overview: section count, element type counts, and all custom CSS classes. Use this first, then use search_page_elements to find specific elements

Input parameters:

- `page_id` (string, required): Page ID

### `search_page_elements` (~268 tokens)

Search/filter elements within a page source. Returns matching elements with full detail (id, type, style, text, classes, etc.).
Examples:
\- Find all buttons: type="button"
\- Find elements with custom class: custom_class="hero"
\- Find text containing "subscribe": text="subscribe"
\- Find all data-bound elements: has_bind=true
\- Find all elements with events: has_events=true
\- Find all elements with custom CSS classes: has_custom_class=true

Input parameters:

- `custom_class` (string): Filter by custom class substring
- `has_bind` (boolean): Only elements with data bindings (product, category, blog)
- `has_custom_class` (boolean): Only elements that have a custom class
- `has_events` (boolean): Only elements with events (click, submit, mouseenter, etc.)
- `id` (string): Filter by element ID substring (e.g. 'TEXT', 'BUTTON-3')
- `limit` (number): Max results (default 50)
- `page_id` (string, required): Page ID
- `text` (string): Filter by text content substring
- `type` (string): Filter by element type (e.g. 'text', 'button', 'image', 'container', 'section', 'form', 'input')

### `create_page` (~209 tokens)

Create a new (empty) page. For a page with content use build_page instead. type is a KIND (main/store/member/blog/custom/error/maintain) mapped to the numeric backend type; pass seo so it doesn't publish with an empty title.

Input parameters:

- `is_homepage` (boolean): Set as homepage
- `name` (string, required): Page name
- `seo` (object): SEO → settings.seo (title/description/keyword/favicon/thumbnail). Tokens {{name_page}}/{{name_site}} allowed.
- `slug` (string, required): URL slug WITHOUT a leading slash, e.g. 'about', 'collections', 'cart'. A leading '/' is stripped automatically (the storefront matches the bare path segment, so '/cart' would 404). Homepage needs no…
- `type` (string): Page kind (main/store/member/blog/custom/error/maintain). store/member/blog need their data-source flag enabled — prefer build_page which auto-enables it.

### `update_page` (~100 tokens)

Update page properties (name, slug, settings, custom code)

Input parameters:

- `is_homepage` (boolean): Set as homepage
- `name` (string): New name
- `page_id` (string, required): Page ID
- `settings` (object): Page settings
- `slug` (string): New slug WITHOUT a leading slash (e.g. 'about', 'cart'). A leading '/' is stripped automatically — '/cart' would 404 on the storefront.

### `get_site_custom_code` (~123 tokens)

Get custom code of the site (CSS/JS). Two modes:
\- Default: returns ALL 4 code fields (full content)
\- With field filter: returns only the specified field(s) — saves tokens when you only need CSS or JS
Add include_guide=true on first call to get the coding guide

Input parameters:

- `fields` (array): Only return specific fields (e.g. ['code_custom_css']). Omit to get all 4 fields
- `include_guide` (boolean): Include the custom code coding guide (only needed on first call)

### `update_site_custom_code` (~179 tokens)

Update custom code (CSS/JS) for the entire site. Only sends fields you specify — others remain unchanged.
IMPORTANT: Before calling, you MUST read existing code with get_site_custom_code first, then show the user what will change and get explicit confirmation. NEVER update without user approval.
\- code_before_head: HTML/script inserted before </head>
\- code_before_body: HTML/script inserted before </body>
\- code_custom_css: Custom CSS (auto-wrapped in <style>)
\- code_custom_javascript: Custom JavaScript

Input parameters:

- `code_before_body` (string): HTML/script to insert before </body>
- `code_before_head` (string): HTML/script to insert in <head>
- `code_custom_css` (string): Custom CSS for the site
- `code_custom_javascript` (string): Custom JavaScript for the site

### `append_site_custom_code` (~101 tokens)

Append or prepend code to a custom code field WITHOUT reading the existing content first.
Use this when you need to ADD new CSS rules, JS code, or script tags — no need to read first.
For full rewrites, use update_site_custom_code instead.

Input parameters:

- `code` (string, required): Code to add
- `field` (string, required): Which code field to modify
- `position` (string): Add to end (append) or beginning (prepend)

### `delete_page` (~24 tokens)

Delete a page

Input parameters:

- `page_id` (string, required): Page ID to delete

### `get_page_versions` (~26 tokens)

View version history of a page

Input parameters:

- `page_id` (string, required): Page ID

### `list_page_contents` (~29 tokens)

List multi-language contents of a page

Input parameters:

- `page_id` (string): Filter by Page ID

### `update_page_content` (~101 tokens)

Create/update page content for a specific language.
IMPORTANT: Before calling, you MUST read existing content with list_page_contents first, then show the user what will change and get explicit confirmation. NEVER update without user approval.

Input parameters:

- `content` (object, required): Page content
- `language_code` (string, required): Language code (e.g. 'en', 'vi')
- `meta_tags` (array): SEO meta tags
- `page_id` (string, required): Page ID

### `get_page_element` (~88 tokens)

Get full detail of a single element by its ID (e.g. 'TEXT-3', 'BUTTON-1', 'SECTION-2'). Returns style, config, specials, events, bindings, responsive, and children IDs

Input parameters:

- `element_id` (string, required): Element ID (e.g. 'TEXT-3', 'BUTTON-1')
- `page_id` (string, required): Page ID

### `update_page_element` (~377 tokens)

Update properties of a specific element in page source. Two-step process:
STEP 1: Call with dry_run=true (default) → returns diff of what will change.
STEP 2: Show the diff to the user and ask for confirmation. NEVER proceed without explicit user approval.
STEP 3: Only after user confirms, call again with dry_run=false to apply.
IMPORTANT: You MUST show the diff to the user and get explicit "yes/ok/confirm" before calling with dry_run=false. Skipping confirmation risks data loss.
Merge rules: style/config/specials = shallow merge, responsive = merge by bp key.
events/bindings = REPLACE the whole array — pass the COMPLETE list (read it first with get_page_element so you don't drop the others); entries are auto-normalized (id + eventName filled in, so you can pass just { action, ...fields } / { target }).

Input parameters:

- `bindings` (array): Complete bindings array (replaces existing)
- `config` (object): Config properties to merge
- `dry_run` (boolean): Preview only (true) or apply changes (false). Defaults to confirm_mode setting. Use toggle_confirm_mode to change default.
- `element_id` (string, required): Element ID to update (e.g. 'TEXT-3', 'BUTTON-1')
- `events` (array): Complete events array (replaces existing)
- `page_id` (string, required): Page ID
- `responsive` (object): Responsive breakpoint overrides (e.g. {bp1: {style: {...}, config: {...}}})
- `specials` (object): Specials to merge (text, custom_class, custom_css, etc.)
- `style` (object): CSS style properties to merge (e.g. {color: '#fff', 'font-size': '16px'})

### `update_page_elements` (~179 tokens)

Batch update multiple elements in one page. Two-step process:
STEP 1: Call with dry_run=true (default) → returns per-element diff.
STEP 2: Show all diffs to the user and ask for confirmation. NEVER proceed without explicit user approval.
STEP 3: Only after user confirms, call again with dry_run=false to apply.
IMPORTANT: You MUST show the diff to the user and get explicit "yes/ok/confirm" before calling with dry_run=false. Skipping confirmation risks data loss.
Same merge rules: style/config/specials = shallow merge, events/bindings = replace.

Input parameters:

- `dry_run` (boolean): Preview only (true) or apply changes (false). Defaults to confirm_mode setting.
- `page_id` (string, required): Page ID
- `updates` (array, required): Array of element updates

### `update_page_source` (~128 tokens)

Directly update the full page source JSON.
IMPORTANT: Before calling this tool, you MUST:
1\. Read existing source with get_page_source first
2\. Show the user what will change and get explicit confirmation
3\. NEVER call without user approval — this replaces the ENTIRE page source
Safeguarded: blocks if new source is <50% of existing size.

Input parameters:

- `custom_code` (string): Custom code (CSS/JS) for this page
- `page_id` (string, required): Page ID
- `source`: Full page source object (sections tree) or JSON string

### `list_collections` (~69 tokens)

List all database collections (tables) for the site. Returns collection names, table names, and field counts. Use get_collection for full schema details

Input parameters:

- `limit` (number): Items per page
- `page` (number): Page number
- `term` (string): Search by collection name

### `get_collection` (~39 tokens)

Get a specific collection's details including full schema (field names, types, constraints, references) and records

Input parameters:

- `id` (string, required): Collection ID

### `query_collection_records` (~145 tokens)

Query records from a collection (custom data table) by table name. Supports paging + an optional `where` filter and `order_by` sort. (Uses the CMS api-key auth the records endpoint requires.)

Input parameters:

- `limit` (number): Items per page
- `order_by` (string): Field to sort by (e.g. 'inserted_at').
- `page` (number): Page number
- `table_name` (string, required): Collection table name (e.g. 'subscribers', 'custom_orders') — from get_collection.table_name
- `where` (object): Filter object, e.g. { status: 'active' } — matches records by field value.

### `create_collection` (~150 tokens)

Create a new collection (custom data TABLE). It starts with the system columns (id/inserted_at/updated_at/creator_id); pass `columns` to add custom fields. NOTE: to WRITE records into it, use an HTTP function (webcake-data: db.model(table).create({...})) — the dashboard has no direct record-insert API. See get_http_function for the SDK guide.

Input parameters:

- `columns` (array): Custom columns to add, e.g. [{name:'email',type:'text'},{name:'amount',type:'integer'}].
- `name` (string, required): Display name.
- `table_name` (string): Table name (snake_case, unique). Defaults to name.

### `update_collection_columns` (~86 tokens)

Add or change a collection's custom columns. Reads the current schema, then PATCHes it with the system columns + your custom columns (the PATCH replaces the whole schema, so omitting a column drops it).

Input parameters:

- `collection_id` (string, required): Collection id (from list_collections / get_collection).
- `columns` (array, required): The FULL set of custom columns the table should have.

### `delete_collection` (~35 tokens)

Delete a collection (table) and all its records by id. Irreversible.

Input parameters:

- `collection_id` (string, required): Collection id.

### `list_articles` (~57 tokens)

List blog articles (metadata only, without HTML content). Use get_article to get full content

Input parameters:

- `category_id` (string): Filter by category
- `limit` (number): Items per page
- `page` (number): Page number

### `get_article` (~23 tokens)

Get article details by ID

Input parameters:

- `id` (string, required): Article ID

### `create_article` (~176 tokens)

Create a blog article so blog/post pages (post-list, grid-blog, post-overlay) have content.
Built via the dashboard command pipeline: title + optional summary, HTML content, image URLs, and
category linkage. Pass category_ids from create_blog_category / list articles' categories so the
post shows up under those categories (it is also auto-filed under the default category). Image URLs
must be hosted (search_images / upload_images). The backend generates the id and slug.

Input parameters:

- `category_ids` (array): Blog category IDs to file the post under (from create_blog_category)
- `content` (string): HTML content of the post
- `images` (array): Hosted image URLs; the first is the cover image
- `name` (string, required): Article title
- `summary` (string): Short summary / excerpt

### `update_article` (~88 tokens)

Update a blog article

Input parameters:

- `category_id` (string): Category ID
- `content` (string): New HTML content
- `id` (string, required): Article ID
- `is_hidden` (boolean): Hide from public
- `name` (string): New title
- `slug` (string): New slug
- `summary` (string): New summary
- `tags` (array): Tags

### `delete_article` (~22 tokens)

Delete a blog article

Input parameters:

- `id` (string, required): Article ID

### `list_customers` (~107 tokens)

List/search the site's customers (browse or segment). Pass `term` to search by name/phone/email. Returns name, phone, email, order_count, purchased_amount, reward_point, tags, last_order_at. Use find_customer for an exact id/phone/email lookup.

Input parameters:

- `limit` (number): Items per page (default 50)
- `page` (number): Page number (default 1)
- `term` (string): Keyword — searches name / phone / email

### `find_customer` (~38 tokens)

Find a customer by ID, phone number, or email

Input parameters:

- `by` (string, required): Search field
- `value` (string, required): Search value

### `list_products` (~66 tokens)

List products of the site (metadata only: id, name, slug, price, image, status). Use get_product for full details

Input parameters:

- `limit` (number): Items per page
- `page` (number): Page number
- `term` (string): Search by product name

### `get_product` (~40 tokens)

Get full product details by ID: name, description, price, variations, images, attributes, SEO, etc.

Input parameters:

- `id` (string, required): Product ID

### `search_products` (~48 tokens)

Search products by keyword. Returns matching products with basic info

Input parameters:

- `limit` (number): Items per page
- `page` (number): Page number
- `term` (string, required): Search keyword

### `list_categories` (~16 tokens)

List all product categories of the site

### `create_product` (~360 tokens)

Create a product so the storefront has real merchandise (grid-product / slider-product bindings need this).
Simple use: pass name + price (+ images, category_ids). One default variation with the price/stock is created for you.
Advanced use: pass attributes (e.g. Color/Size) + variations for a multi-SKU product.
Images must be HOSTED URLs — get them from search_images or upload_images first. The backend generates id, slug and publishes the product.

Input parameters:

- `attributes` (array): Variant axes, e.g. [{name:'Color',values:['Đen','Trắng']},{name:'Size',values:['S','M','L']}]
- `category_ids` (array): Product category IDs to file the product under (from create_product_category / list_categories)
- `description` (string): Full product description (HTML allowed) — binds to product::description on the detail page.
- `images` (array): Hosted image URLs (search_images/upload_images). First image becomes the product thumbnail.
- `name` (string, required): Product name
- `original_price` (number): List/compare-at price for the simple single-variation case
- `price` (number): Selling price (used when you don't pass variations). Required unless variations are given.
- `short_description` (string): Short description / tagline (HTML allowed) — binds to product::short_description on cards + the detail page. Set this so cards aren't blank.
- `sku` (string): SKU / custom_id for the simple case (auto-generated if omitted)
- `stock` (number): Stock quantity for the simple single-variation case
- `variations` (array): Explicit per-SKU variations. Omit to auto-build one from price/stock/sku.

### `create_product_category` (~103 tokens)

Create a product category (so grid-category / a category page has something to show, and products can be filed under it).
Returns the new category id — pass it to create_product's category_ids. Image must be a hosted URL.

Input parameters:

- `description` (string): Category description
- `image` (string): Hosted image URL for the category card
- `name` (string, required): Category name
- `parent_id` (string): Parent category id for a sub-category

### `create_blog_category` (~79 tokens)

Create a blog/article category. Returns the new category id — pass it to create_article's category_id so posts are grouped (post-list / blog pages bind to it). Image must be a hosted URL.

Input parameters:

- `description` (string): Category description
- `image` (string): Hosted image URL
- `name` (string, required): Blog category name

### `update_product` (~165 tokens)

Update an existing product. Pass product_id + only the fields to change. To change
price/stock, pass variations (get_product first to see the existing variation shape).
Images must be hosted CDN urls (search_images cdn_url / upload_images).

Input parameters:

- `category_ids` (array): Replace the product's categories
- `description` (string): New description (HTML allowed)
- `images` (array): New hosted image URLs; first becomes the thumbnail
- `is_published` (boolean): Publish/unpublish the product
- `name` (string): New name
- `product_id` (string, required): Product id to update
- `variations` (array): Replace variations (price/stock/SKU per variant). Reuse existing custom_ids from get_product to edit in place.

### `set_product_published` (~53 tokens)

Publish or unpublish one or more products quickly (without a full update).

Input parameters:

- `is_published` (boolean, required): true = publish (visible), false = hide
- `product_ids` (array, required): Product ids

### `delete_product` (~28 tokens)

Delete one or more products by id.

Input parameters:

- `product_ids` (array, required): Product ids to delete

### `update_product_category` (~86 tokens)

Update a product category (name, image, description, or visibility). Pass id + fields to change.

Input parameters:

- `description` (string): New description
- `hidden` (boolean): Hide (true) or show (false) the category
- `id` (string, required): Category id
- `image` (string): New hosted image URL
- `name` (string): New name

### `delete_product_category` (~29 tokens)

Delete one or more product categories by id.

Input parameters:

- `ids` (array, required): Category ids to delete

### `list_orders` (~81 tokens)

List orders of the site (metadata only). Use get_order for full details including items

Input parameters:

- `limit` (number): Items per page
- `page` (number): Page number
- `status` (number): Filter by status (0=pending, 50=confirmed, 100=shipping, 150=delivered, -1=cancelled)

### `get_order` (~37 tokens)

Get full order details by ID: customer info, items, payment, shipping, discounts, etc.

Input parameters:

- `id` (string, required): Order ID

### `count_orders_by_status` (~22 tokens)

Get order count grouped by status. Useful for dashboard overview

### `get_site_info` (~33 tokens)

Get full site information: name, domain, settings (colors, typography, layout, language, payment methods, etc.)

### `list_themes` (~34 tokens)

List all custom themes of the site. Returns theme name, colors, typographies, transitions, and which one is active

### `list_template_themes` (~98 tokens)

Search/list the public Webcake template marketplace (api.storecake.io). Use to match customer brief against existing templates by keyword. Returns id, name, preview_url, thumbnail, categories

Input parameters:

- `lang` (string): Language code (default 'vi')
- `limit` (number): Items per page (default 12)
- `page` (number): Page number (default 1)
- `q` (string): Keyword to search themes

### `semantic_search_themes` (~118 tokens)

Semantic search across the theme marketplace using bge-m3 embeddings (cosine similarity). Use when the brief is a natural-language description of industry + features (e.g. 'website mỹ phẩm có popup minigame và loyalty'), not just keywords. Returns top matches with theme_id, score, name, preview_url, thumbnail, description_vi/en

Input parameters:

- `limit` (number): Number of matches to return (default 5, max 10)
- `query` (string, required): Natural-language description of the desired website (industry + features)

### `create_site_from_template` (~182 tokens)

Create a NEW site from a marketplace TEMPLATE (the dedicated "use this template" API).
Clones the template's pages, global sections, cart, popups, styles and fonts into a fresh
site. Pick a template with semantic_search_themes / list_template_themes, then pass its
theme_id here. Switches to the new site so you can immediately edit layout/content with
update_page_element(s), colours/fonts via the site-style tools, then publish_site.

Input parameters:

- `name` (string, required): Name for the new site
- `slug` (string): URL-safe slug for the new site (auto-generated if omitted)
- `switch_to` (boolean): Switch the session to the new site after creating it (saved for next session)
- `theme_id` (string, required): Marketplace theme id (from semantic_search_themes / list_template_themes)

### `list_apps` (~131 tokens)

List the site's installed applications (type, status, settings).
App type codes: 0=product_review, 1=articles_review, 2=automation, 3=telegram, 4=affiliates, 5=multilingual, 6=appointment, 7=send_email, 8=botcake, 9=sale_channel, 10=product_design, 11=auth_otp, 12=personal_product_design, 14=course, 15=zalo_mini_app, 16=cms, 17=recaptcha, 18=pwa.

### `get_app` (~281 tokens)

Get one installed app by its type code (returns null if not installed).
App type codes: 0=product_review, 1=articles_review, 2=automation, 3=telegram, 4=affiliates, 5=multilingual, 6=appointment, 7=send_email, 8=botcake, 9=sale_channel, 10=product_design, 11=auth_otp, 12=personal_product_design, 14=course, 15=zalo_mini_app, 16=cms, 17=recaptcha, 18=pwa. You may pass the number or the name.

Input parameters:

- `type` (number|string, required): App type — a code (e.g. 2) or a name (e.g. "automation"). Codes: 0=product_review, 1=articles_review, 2=automation, 3=telegram, 4=affiliates, 5=multilingual, 6=appointment, 7=send_email, 8=botcake, 9…

### `install_app` (~174 tokens)

Install (register) an application on the current site so its features become usable.
For example, automations need the "automation" app installed first.
App types: 0=product_review, 1=articles_review, 2=automation, 3=telegram, 4=affiliates, 5=multilingual, 6=appointment, 7=send_email, 8=botcake, 9=sale_channel, 10=product_design, 11=auth_otp, 12=personal_product_design, 14=course, 15=zalo_mini_app, 16=cms, 17=recaptcha, 18=pwa.

Input parameters:

- `app` (string, required): App to install (by name)
- `is_active` (boolean): Activate the app on install

### `uninstall_app` (~61 tokens)

Uninstall (remove) an installed application from the current site.
Pass the app's subscription id — get it from list_apps (the `id` field) or get_app.

Input parameters:

- `id` (string, required): App subscription id (from list_apps / get_app)

### `update_app` (~108 tokens)

Update an installed app's configuration. Pass the app subscription id and an `attrs` object
that is merged onto the subscription — usually `{ settings: {...} }`, optionally `{ status }`.
For the product-review app, prefer update_app_review (it also propagates shop_info).

Input parameters:

- `attrs` (object, required): Fields to update, e.g. { "settings": { ... }, "status": 1 }
- `id` (string, required): App subscription id (from list_apps / get_app)

### `update_app_review` (~101 tokens)

Update the product-review app's settings (e.g. shop_info, auto-approve, display options).
Pass the review app's subscription id (get_app with type "product_review") and the full `settings` object.

Input parameters:

- `id` (string, required): Review app subscription id (get_app type=product_review)
- `settings` (object, required): Review app settings object, e.g. { "shop_info": { ... }, "auto_approve": true }

### `list_promotions` (~73 tokens)

List all promotions/discounts of the site (metadata only). Use get_promotion for full details

Input parameters:

- `include_guide` (boolean): Include promotion type reference guide
- `limit` (number): Items per page (default: 20)
- `page` (number): Page number (default: 1)

### `get_promotion` (~44 tokens)

Get full promotion details by ID: name, type, schedule, discount rules, coupon settings, items, bonus products, etc.

Input parameters:

- `id` (string, required): Promotion ID

### `get_promotion_items` (~65 tokens)

Get products/variations/categories attached to a promotion. Returns items with discount details (fixed_prices, level_info, coupon_item_info)

Input parameters:

- `id` (string, required): Promotion ID
- `limit` (number): Items per page
- `page` (number): Page number

### `get_active_promotions` (~28 tokens)

Get all currently active promotions (is_activated=true and within start_time/end_time range)

### `search_promotions` (~148 tokens)

Search/filter promotions with advanced filters: by type, status (coming_soon/in_progress/finished), keyword, date range

Input parameters:

- `is_activated` (boolean): Filter by active status
- `limit` (number): Items per page
- `page` (number): Page number
- `status` (number): Filter by time status: 1=coming_soon, 2=in_progress, 3=finished
- `term` (string): Search by promotion name
- `type` (string): Filter by type: normal, same_price, coupon, coupon_id_multiple_times, discount_by_coupon_id, promotion_order, promotion_category, x_get_y_prod, x_get_y_category

### `list_combos` (~82 tokens)

List all combo/bundle products of the site. Use get_combo_items for combo composition details

Input parameters:

- `include_guide` (boolean): Include combo type reference guide
- `limit` (number): Items per page (default: 20)
- `page` (number): Page number (default: 1)
- `term` (string): Search by combo name

### `get_combo_items` (~69 tokens)

Get items (products/variations) and bonus products that compose a combo. Returns combo_items (required items with count) and bonus_items (free gifts)

Input parameters:

- `combo_product_id` (string, required): Combo product ID
- `is_variation_bonus` (boolean): Whether bonus items are variation-based

### `list_global_sources` (~71 tokens)

List global sources (cart, popup, etc.). Returns compact summary per source.
Always provide component to filter by type — the API may not return all types without a filter.

Input parameters:

- `component` (string): Filter by component type (e.g. "cart-droppable", "popup"). Recommended to always provide

### `get_source_cart` (~34 tokens)

Get all cart global sources with compact tree view.
Shows full element hierarchy — no need to call get_global_source_detail separately.

### `get_global_source_detail` (~97 tokens)

Get full detail of a global source — compact tree view showing all elements.
Each line: ID [type] "text" .class [events] [bindings] (children_count).
Provide component for faster lookup; omit if you already called list_global_sources.

Input parameters:

- `component` (string): Component hint for faster lookup (e.g. "popup", "cart-droppable")
- `global_source_id` (string, required): Global source ID

### `search_global_source_elements` (~243 tokens)

Search/filter elements within a global source. No component param needed.
Examples:
\- Find all buttons: type="button"
\- Find by class: custom_class="hero"
\- Find text: text="subscribe"
\- Data-bound only: has_bind=true
\- With events: has_events=true
\- With custom class: has_custom_class=true

Input parameters:

- `component` (string): Component hint for faster lookup (e.g. "popup", "cart-droppable")
- `custom_class` (string): Filter by custom class substring
- `global_source_id` (string, required): Global source ID
- `has_bind` (boolean): Only elements with data bindings
- `has_custom_class` (boolean): Only elements with custom class
- `has_events` (boolean): Only elements with events
- `id` (string): Filter by element ID substring (e.g. 'TEXT', 'BUTTON-3')
- `limit` (number): Max results (default 50)
- `text` (string): Filter by text content substring
- `type` (string): Filter by element type (e.g. 'text', 'button', 'image', 'container', 'section')

### `get_global_source_element` (~79 tokens)

Get full detail of a single element (style, config, specials, events, bindings, responsive, children).

Input parameters:

- `component` (string): Component hint for faster lookup
- `element_id` (string, required): Element ID (e.g. 'TEXT-3', 'BUTTON-1')
- `global_source_id` (string, required): Global source ID

### `update_global_source_element` (~341 tokens)

Update a single element within a global source. Two-step process:
STEP 1: Call with dry_run=true (default) → returns diff of what will change.
STEP 2: Show the diff to the user and ask for confirmation. NEVER proceed without explicit user approval.
STEP 3: Only after user confirms, call again with dry_run=false to apply.
IMPORTANT: You MUST show the diff to the user and get explicit "yes/ok/confirm" before calling with dry_run=false. Skipping confirmation risks data loss.
Merge rules: style/config/specials = shallow merge, responsive = merge by bp key.
events/bindings = REPLACE the whole array — pass the COMPLETE list (read it first); entries are auto-normalized (id + eventName filled in).

Input parameters:

- `bindings` (array): Complete bindings array (replaces existing)
- `component` (string): Component hint for faster lookup
- `config` (object): Config properties to merge
- `dry_run` (boolean): Preview only (true) or apply changes (false). Defaults to confirm_mode setting. Use toggle_confirm_mode to change default.
- `element_id` (string, required): Element ID to update (e.g. 'TEXT-3', 'BUTTON-1')
- `events` (array): Complete events array (replaces existing)
- `global_source_id` (string, required): Global source ID
- `responsive` (object): Responsive overrides (e.g. {bp1: {style: {...}}})
- `specials` (object): Specials to merge (text, custom_class, custom_css)
- `style` (object): CSS style properties to merge

### `update_global_source_elements` (~195 tokens)

Batch update multiple elements in one global source. Two-step process:
STEP 1: Call with dry_run=true (default) → returns per-element diff.
STEP 2: Show all diffs to the user and ask for confirmation. NEVER proceed without explicit user approval.
STEP 3: Only after user confirms, call again with dry_run=false to apply.
IMPORTANT: You MUST show the diff to the user and get explicit "yes/ok/confirm" before calling with dry_run=false. Skipping confirmation risks data loss.
Same merge rules: style/config/specials = shallow merge, events/bindings = replace.

Input parameters:

- `component` (string): Component hint for faster lookup
- `dry_run` (boolean): Preview only (true) or apply changes (false). Defaults to confirm_mode setting.
- `global_source_id` (string, required): Global source ID
- `updates` (array, required): Array of element updates

### `create_global_source` (~81 tokens)

Create a new global source component. Component types: "cart-droppable" (cart), "popup", or any custom type.

Input parameters:

- `component` (string, required): Component type (e.g. "cart-droppable", "popup")
- `source`: Source configuration (sections/elements JSON)
- `type` (string): Type variant (default: "default")

### `update_global_source` (~118 tokens)

Replace full source of a global source.
IMPORTANT: Before calling this tool, you MUST:
1\. Read existing source with get_global_source_detail first
2\. Show the user what will change and get explicit confirmation
3\. NEVER call without user approval — this replaces the ENTIRE source
Safeguarded: blocks if new source is <50% of existing size. For element-level changes, prefer update_global_source_element instead.

Input parameters:

- `global_source_id` (string, required): Global source ID
- `source`: New source configuration (JSON object)

### `delete_global_source` (~32 tokens)

Delete a global source and its published version

Input parameters:

- `global_source_id` (string, required): Global source ID to delete

### `get_global_source_contents` (~40 tokens)

Get multilingual contents for global sources by component type

Input parameters:

- `component` (string, required): Component type (e.g. "cart-droppable", "popup")

### `update_global_source_contents` (~78 tokens)

Update multilingual contents (upsert). Each entry: global_source_id, language_code, content.
IMPORTANT: Before calling, you MUST read existing contents with get_global_source_contents first, then show the user what will change and get explicit confirmation. NEVER update without user approval.

Input parameters:

- `contents` (array, required): Array of content entries to upsert

### `list_global_sections` (~86 tokens)

List reusable global sections (Header, Footer, shared content blocks) — SLIM summary only.
Each entry: id, name, slot (header/footer/block), element count + type histogram + custom classes.
The full element tree is large, so it is NOT returned here — drill in with get_global_section
(compact tree), search_global_section_elements, or get_global_section_element.

### `get_global_section` (~124 tokens)

Get one global section as a COMPACT tree (3-5x fewer tokens than raw JSON).
Each line: ID [type] "text" .class [Nbind] [Nev] (children_count).
Use this to learn how a real Header/Footer/block is composed before building your own.

Input parameters:

- `global_section_id` (string, required): Global section ID (from list_global_sections)
- `raw` (boolean): Return the FULL raw section JSON (large) instead of the compact tree — delivered via the large-result cache so you can split-read it with read_cached_result.

### `search_global_section_elements` (~183 tokens)

Search/filter elements within a global section (Header/Footer/block) without dumping the whole tree.
Filter by type, id substring, custom_class, text, or has_bind / has_events / has_custom_class.

Input parameters:

- `custom_class` (string): Filter by custom class substring
- `global_section_id` (string, required): Global section ID
- `has_bind` (boolean): Only elements with data bindings
- `has_custom_class` (boolean): Only elements with a custom class
- `has_events` (boolean): Only elements with events
- `id` (string): Filter by element ID substring
- `limit` (number): Max results (default 50)
- `text` (string): Filter by text content substring
- `type` (string): Filter by element type (e.g. 'menu', 'menu-item', 'container', 'image', 'text')

### `get_global_section_element` (~78 tokens)

Get full detail (style, config, specials, events, bindings, responsive bp1..bp4, children IDs) of a single element inside a global section.

Input parameters:

- `element_id` (string, required): Element ID (e.g. 'MENU-1', 'TEXT-3')
- `global_section_id` (string, required): Global section ID

### `create_global_section` (~235 tokens)

Create a reusable global section (Header / Footer / shared block) the way the builder does:
persists a global_section record AND embeds the same section node into page sources so it
actually renders across the site (header → top of every page, footer → bottom).
Build the section first with new_section (give it a real bg/padding + logo/menu/links), then pass it here.
Two-step safety: dry_run=true (default) previews which pages change; dry_run=false performs the atomic save.

Input parameters:

- `dry_run` (boolean): Preview which pages would change (true) or perform the atomic save (false).
- `name` (string, required): Display name in the editor (e.g. 'Header', 'Footer')
- `page_ids` (array): Pages to embed into. Omit to apply to ALL pages of the site (typical for header/footer).
- `section`: A section node from new_section (object or JSON string) — the content of the header/footer.
- `type` (string, required): header = top chrome (logo/nav/cart), footer = bottom chrome, section = reusable content block

### `delete_global_section` (~97 tokens)

Delete a global section (Header/Footer/block) and remove its node from every page source.
Two-step safety: dry_run=true (default) shows which pages would change; dry_run=false performs the atomic save.

Input parameters:

- `dry_run` (boolean): Preview (true) or perform the delete + page cleanup (false).
- `section_id` (string, required): The global section's section_id (the section node id) — from list_global_sections.

### `read_cached_result` (~109 tokens)

Read a slice of a large cached result produced by another tool (look for "cached":true + a cache_id in its output).
Page through with offset/length; the response reports next_offset + remaining_chars until done.

Input parameters:

- `cache_id` (string, required): The cache_id returned by the producing tool (e.g. "cache-3")
- `length` (number): Number of characters to return (default 12000)
- `offset` (number): Start character offset (default 0)

### `list_cached_results` (~28 tokens)

List the large results currently held in the session cache (id, label, size, age).

### `scan_unique_images` (~172 tokens)

Scan all images used across page sources, global sources, and global sections. Returns a unique list of image URLs with which elements use each one.
Useful for: image audit, finding broken/duplicated CDN URLs, bulk replace planning, theme migration.
Scans every string field in the source tree (config.src, style.background-image, etc.) and CSS url(...) refs — wide net catches all variants.

Input parameters:

- `include_relative` (boolean): Include relative-path images (e.g. /uploads/...). Default only http(s) URLs
- `lazy` (boolean): Return only unique URL list, no usage tracking — faster for large sites
- `page_id` (string): Limit to one page (only used when scope is 'pages' or 'all')
- `scope` (string): Which sources to scan

### `read_image` (~222 tokens)

Fetch an image URL and return its bytes for vision analysis by the AI client. Pair with scan_unique_images to inspect images already on the site.

After receiving the image, describe it (subject, style, palette, composition, mood, lighting, background, notable_details) to build an image-generation brief.

Describe the image with these fields, useful as input for new image generation:
\- subject: main object / scene / person
\- style: photography, illustration, 3D render, flat vector, watercolor, ...
\- palette: 3–5 dominant colors (hex or names)
\- composition: layout, framing, focal point
\- mood: emotion or atmosphere
\- lighting: natural / studio / golden hour / dramatic / soft / ...
\- background: setting / environment
\- notable_details: props, textures, typography, brand elements
Use these as building blocks when drafting an image-gen brief.

Input parameters:

- `max_size_mb` (number): Reject images larger than this (default 8MB)
- `url` (string, required): Absolute http(s) image URL

### `list_image_elements` (~141 tokens)

Find all image elements across pages + global sources, with element_id, current alt, src, and the field path where alt is/should be written. Use as the first step before generating alt text via vision (read_image) and writing back with set_image_alts.
Note: global_sections are read-only via the API and are not included.

Input parameters:

- `limit` (number): Max elements to return
- `only_missing_alt` (boolean): Return only elements whose alt is empty
- `page_id` (string): Limit to one page (only used when scope is 'pages' or 'all')
- `scope` (string): Which sources to inspect

### `set_image_alts` (~113 tokens)

Batch-write alt text for image elements across pages + global sources. Groups updates by source so each source is fetched + saved exactly once.
Workflow: list_image_elements → read_image (per src) → describe → set_image_alts(items).
If alt_path is omitted, it is auto-detected via the same probe used by list_image_elements (config.image.alt → config.alt → specials.alt).

Input parameters:

- `dry_run` (boolean): Preview the diff without saving
- `items` (array, required): List of alt updates

### `fetch_images_for_alt_fill` (~192 tokens)

One-shot helper for filling image_alt across the site. Returns image bytes + element metadata in a single response so Claude can describe everything in one pass, then call set_image_alts once.

Workflow:
1\. Call this tool with scope/limit.
2\. Tool returns each image inline with its element_id + source_type + source_id.
3\. Claude reads images, drafts an alt for each, then calls set_image_alts(items) once with the template at the end of the response.

The pre-built "items" template at the end contains placeholders — fill in "alt" and call set_image_alts.

Input parameters:

- `limit` (number): Max images per call (cap 20)
- `max_size_mb` (number)
- `only_missing_alt` (boolean): Default true — skip elements that already have alt
- `page_id` (string)
- `scope` (string)

### `read_images` (~217 tokens)

Batch fetch multiple image URLs in parallel. Use when comparing several references or extracting motifs across a set.
Capped at 5 images per call to keep context manageable. For each image, describe subject/style/palette/composition/mood; then synthesize common themes for the brief.

Describe the image with these fields, useful as input for new image generation:
\- subject: main object / scene / person
\- style: photography, illustration, 3D render, flat vector, watercolor, ...
\- palette: 3–5 dominant colors (hex or names)
\- composition: layout, framing, focal point
\- mood: emotion or atmosphere
\- lighting: natural / studio / golden hour / dramatic / soft / ...
\- background: setting / environment
\- notable_details: props, textures, typography, brand elements
Use these as building blocks when drafting an image-gen brief.

Input parameters:

- `max_size_mb` (number): Per-image size cap in MB
- `urls` (array, required): 1–5 absolute http(s) image URLs

### `get_build_guide` (~50 tokens)

Get the BuilderX page authoring guide: page shape, the grid layout model, styling, breakpoints, forms/data, and the build workflow. Read this before building or heavily editing a page.

### `get_page_schema` (~79 tokens)

Get the authoritative JSON Schema (Draft 2020-12) for a page source `{ sections: [...] }` — the structural contract for every node (id/type/specials/runtime{style,config}/children/events/bindings) in the CSS-grid model. Use it as the shape to emit; validate_page enforces the semantic rules.

### `list_elements` (~37 tokens)

List all BuilderX element/component types you can place on a page, grouped by category with a one-line summary and whether each is a container.

### `get_element` (~103 tokens)

Get the full detail of an element type: category, container flag, summary, an ATTRIBUTES reference (the meaningful specials/config keys + their purpose/allowed values, events, and dataset binding targets), and a live skeleton node (the authoritative default shape) you can copy and edit. Read this before authoring/editing an element so you set the right keys.

Input parameters:

- `type` (string, required): Element type, e.g. 'text', 'button', 'grid-product'

### `list_events` (~108 tokens)

List every interaction EVENT you can attach to a node: the triggers (eventName: click/hover/success/submit/…) and the actions (open_page, scroll_to, toggle, open_popup, add_to_cart, buy_now, phone_call, open_link, …) with the exact extra fields each action needs. Attach via new_element/new_section opts.events (ids are auto-minted, e.g. opts.events=[{ action:'add_to_cart', open_page:'cart' }]).

### `list_bindings` (~114 tokens)

List every dynamic-data BINDING target: the datasets (product, cart_item, order, order_item, post, category, customer, customer_address, …) and their exact field names ('product::product_price', …), which page type each needs (store/member/blog), and how repeater children (grid-product, cart-items, post-list) bind per-item. Attach via new_element opts.bindings (ids auto-minted, e.g. opts.bindings=[{ target:'product::product_price' }]).

### `new_element` (~132 tokens)

Build a single structurally-valid element node from the real builder factory. Returns the node — edit its specials/style, then place it in a section's children.

Input parameters:

- `opts` (object): Factory opts: { text, src, width, height, style, config, specials, events, bindings, responsive, align }. align = horizontal placement in the grid cell: 'left'|'center'|'right'|'fill' (works on any e…
- `type` (string, required): Element type (see list_elements)

### `new_section` (~120 tokens)

Build a complete section node with children laid out in the builder's vertical grid.
Pass an array of element specs; each child is stacked top-to-bottom. Nest containers via the child's own 'children'.
Example children: [{ "type":"text", "opts":{"text":"Welcome","style":{"fontSize":"40px"}} }, { "type":"button", "opts":{"text":"Shop now"} }]

Input parameters:

- `children` (array): Child element specs, stacked vertically in the section
- `section_opts` (object): Optional factory opts for the section node itself

### `new_row` (~312 tokens)

Build a multi-column ROW container: children laid out SIDE BY SIDE (not stacked).
This is how real pages build feature cards, category tiles, footer columns, a 2-col hero, etc.
The row is RESPONSIVE — it auto-collapses to fewer columns on tablet/mobile (default tablet 2, mobile 1) so cards never become cramped slivers.
Place the returned node as a child inside a section (section children still stack vertically; nest a row for horizontal layout).
Example children: [{ "type":"container", "children":[{"type":"image","opts":{...}},{"type":"text","opts":{...}}] }, { ... }, { ... }]

Input parameters:

- `children` (array): Child specs, one per column (laid out left-to-right)
- `col_widths` (array): Explicit per-column unit objects (length = #children), e.g. [{unit:'fr',value:2},{unit:'fr',value:1}]. Default: equal columns.
- `collapse` (object): Columns to show per breakpoint, e.g. {bp3:2,bp4:1}. Default: tablet 2, mobile 1.
- `column_gap` (number): Horizontal gap (px) between columns (default 24)
- `container_opts` (object): Optional factory opts for the row container node itself (e.g. { style:{...} })
- `row_gap` (number): Vertical gap (px) between wrapped rows (default 24)

### `new_page_skeleton` (~36 tokens)

Return an empty but valid page source: { sections: [] }. Add sections built with new_section, then save with build_page.

### `validate_page` (~68 tokens)

Validate a page source ({ sections: [...] }). Returns errors (block saving: duplicate/missing ids, missing types) and warnings (unknown types, form fields without field_name, dangling event targets) plus stats. Always run this before build_page.

Input parameters:

- `source`: Page source object or JSON string

### `build_page` (~374 tokens)

Create a brand-new page AND set its full content source in one step.
Two-step safety: call with dry_run=true (default) to validate and preview, then dry_run=false to actually create + save.
The source must be { sections: [...] } — build sections with new_section. Validation errors block the real save.

Input parameters:

- `dry_run` (boolean): Preview+validate only (true) or create+save (false)
- `is_homepage` (boolean): Set as the site homepage
- `name` (string, required): Page name
- `seo` (object): SEO for this page → settings.seo. Without it the page publishes with an EMPTY title/description. For a store page a good default title is '{{name_product}} | {{name_site}}' (product) or '{{name_categ…
- `slug` (string, required): URL slug WITHOUT a leading slash, e.g. 'about', 'collections', 'cart'. A leading '/' is stripped automatically (the storefront matches the bare path segment, so '/cart' would 404). Store pages MUST u…
- `source`: Full page source { sections: [...] } (object or JSON string)
- `type` (string): Page kind. SPECIAL pages need a site data-source enabled — build_page does this automatically: store→use_store (product/cart bindings), member→use_member (customer/order bindings), blog→use_blog, err…

### `add_section` (~119 tokens)

Append a section to an EXISTING page's source. Reads the current source, appends your section, validates, and (when dry_run=false) saves.
The section is re-id'd to avoid collisions. Build it with new_section.
Two-step safety: dry_run=true (default) previews; dry_run=false saves.

Input parameters:

- `dry_run` (boolean): Preview only (true) or save (false)
- `page_id` (string, required): Target page id
- `section`: A section node (from new_section) — object or JSON string

### `search_images` (~187 tokens)

Search stock photos (Pexels) for a page/product. IMPORTANT: the storefront only renders
images served from the WebCake CDN (image domains are whitelisted) — raw Pexels URLs will
NOT display. By default this re-hosts each result on the WebCake CDN and returns a ready-to-use
cdn_url (cached, so repeats are free). Use cdn_url for image src / product images.
Requires the PEXELS_API_KEY environment variable.

Input parameters:

- `orientation` (string): Preferred orientation
- `per_page` (number): How many results (default 6)
- `query` (string, required): Subject to search, e.g. 'coffee shop interior'
- `upload` (boolean): Re-host each result on the WebCake CDN and return cdn_url (default true — required for the image to show). Set false to only browse Pexels URLs.

### `upload_images` (~342 tokens)

Convert external image URLs, data: URIs, or LOCAL FILE PATHS into site-hosted CDN URLs by reading/downloading each image and re-uploading it to the WebCake backend. Use this whenever the user supplies their OWN images (their URLs or files from their machine), or a page is built from a reference HTML/URL. The returned CDN URLs go straight into an image element's specials.src / runtime.config.src, or a product/category image. This is REQUIRED for any external image (incl. Pexels search results) because the storefront only renders whitelisted WebCake-CDN image domains. Results are cached per site, so re-uploading the same source is free.
Processes up to 20 entries per call in parallel; non jpeg/png/webp inputs are converted to JPEG. UPLOADS BY DEFAULT (dry_run defaults to FALSE — this touches no account data): returns an "images" map (original source → hosted URL). Pass dry_run:true to only preview the entries that WOULD be processed (local paths report whether the file exists + its size) without any network/filesystem upload. Local file paths are only permitted when the MCP server runs locally (stdio); on the remote HTTP transport they are rejected per-entry.

Input parameters:

- `dry_run` (boolean): Default FALSE — actually reads/downloads and uploads, returning hosted URLs. Set true to only preview what would be processed.
- `urls` (array, required): Image sources — 1–20 per call. Accepts: http(s) URLs, data:image/...;base64,... URIs, or local file paths (absolute /path, ~/path, file:// — stdio mode only).

### `publish_site` (~88 tokens)

Publish the whole site live — snapshots all current page sources into the live (published) version.
Note: BuilderX publishes at the SITE level, not per page; publishing makes every saved page go live.
Two-step safety: dry_run=true (default) describes what will happen; dry_run=false actually publishes.

Input parameters:

- `dry_run` (boolean): Preview (true) or publish for real (false)

### `ingest_html` (~59 tokens)

Parse reference HTML into a structural blueprint (title, headings, paragraphs, images, buttons, colour palette) you can rebuild as BuilderX sections with new_section. Not a 1:1 clone.

Input parameters:

- `html` (string, required): Raw HTML to analyse

### `ingest_url` (~52 tokens)

Fetch a public URL and parse it into a structural blueprint (see ingest_html). Note: client-rendered (React/Vue) pages may return little content.

Input parameters:

- `url` (string, required): Public page URL to analyse

### `start_page_draft` (~300 tokens)

Start a page draft (no network). Build a multi-section page safely: cache each section with add_draft_section, then commit_page_draft persists it to the backend INCREMENTALLY (resumable on timeout). Use this instead of build_page for large/multi-section pages. The draft cache is DISPOSABLE (Redis on the remote server when REDIS_URL is set, in-memory otherwise; sliding ~2h TTL) — if a draft is ever lost, just re-send the sections, never a failure.

Input parameters:

- `is_homepage` (boolean): Set as the site homepage on commit
- `name` (string, required): Page name
- `seo` (object): SEO for this page → settings.seo (applied on commit).
- `slug` (string, required): URL slug WITHOUT a leading slash, e.g. 'about', 'collections', 'cart'. A leading '/' is stripped automatically (the storefront matches the bare path segment, so '/cart' would 404). Store pages MUST u…
- `type` (string): Page kind. SPECIAL pages need a site data-source enabled on commit: store→use_store, member→use_member, blog→use_blog, error→use_error, maintain→use_maintain. 'main'/'custom' need nothing.

### `add_draft_section` (~96 tokens)

Append ONE section to a local page draft (NO network — this is the durable per-section cache step that can't time out). The section is re-id'd to avoid collisions and quick-validated; warnings are surfaced but never block. Build the section with new_section.

Input parameters:

- `draft_id` (string, required): Draft id from start_page_draft
- `section`: A section node (from new_section) — object or JSON string

### `get_page_draft` (~53 tokens)

Inspect a local page draft: its meta, the section ids, total section count, and (if a commit is in progress) the page_id + committed_count.

Input parameters:

- `draft_id` (string, required): Draft id

### `list_page_drafts` (~40 tokens)

List local page drafts for the current site (summaries only: id, name, slug, type, section count, commit progress, updated_at).

### `commit_page_draft` (~150 tokens)

Persist a local page draft to the backend INCREMENTALLY (one section per request, 120s timeout each) so no single huge request can time out.
dry_run=true (default) validates the assembled page and previews stats. dry_run=false creates the page then appends sections one at a time, saving progress after each.
RESUMABLE: if a request fails mid-commit, the draft keeps its page_id + committed_count — just call commit_page_draft again to continue from where it stopped.

Input parameters:

- `draft_id` (string, required): Draft id from start_page_draft
- `dry_run` (boolean): Validate+preview only (true) or create+persist incrementally (false)

### `clear_page_draft` (~37 tokens)

Delete a local page draft (does NOT delete any backend page already created from it).

Input parameters:

- `draft_id` (string, required): Draft id

### `list_tool_groups` (~40 tokens)

List every WebCake tool group, how many tools it has, and whether it is loaded natively or reached on-demand via search_tools + invoke_tool.

### `search_tools` (~137 tokens)

Find WebCake tools by keyword across the FULL catalog — including capabilities NOT loaded natively
(marketing/CRM, translations, media, appointments, affiliate, reviews, domains/SEO/shipping, brands/tags/ribbons,
courses, sale channels, automation…). Returns name, group, description and JSON input schema. Then run one with invoke_tool.

Input parameters:

- `group` (string): Restrict to a group name (see list_tool_groups)
- `limit` (number): Max results (default 8)
- `query` (string, required): Keywords, e.g. 'affiliate payout', 'translate product', 'add domain ssl', 'block phone'

### `invoke_tool` (~74 tokens)

Run any WebCake tool by exact name with its arguments (discover names + schemas via search_tools).
Arguments are validated before running. Use this for tools that are not loaded natively.

Input parameters:

- `arguments` (object): Arguments object matching the tool's input schema
- `name` (string, required): Exact tool name (from search_tools)

## Diagnostics

Captured diagnostic sections: Provenance, Vulnerabilities, Dependencies. The full working is on the page: https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/webcake-storefront-mcp#diagnostics

## Score history

- 2026-08-03: 57
- 2026-08-02: 57
- 2026-08-01: 20
- 2026-07-31: 27
- 2026-07-29: 25
- 2026-07-28: 45
- 2026-07-27: 45

## Links

- npm package: https://www.npmjs.com/package/webcake-storefront-mcp
- Socket report: https://socket.dev/npm/package/webcake-storefront-mcp
- Repository: https://github.com/vuluu2k/webcake-storefront-mcp
- Changelog RSS feed: https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/webcake-storefront-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/webcake-storefront-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/vuluu2k-webcake-storefront-mcp/webcake-storefront-mcp
