webcake-storefront-mcp 1.33.0 → 1.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,11 @@
1
1
  [
2
+ {
3
+ "v": "1.33.1",
4
+ "d": "14/10/2026",
5
+ "type": "Changed",
6
+ "en": "create_product, create_product_category, create_blog_category, and create_article no longer accept a seo parameter; set SEO afterwards with…",
7
+ "vi": "create_product, create_product_category, create_blog_category và create_article không còn nhận tham số seo; hãy đặt SEO sau khi tạo bằng…"
8
+ },
2
9
  {
3
10
  "v": "1.33.0",
4
11
  "d": "14/10/2026",
@@ -33,12 +40,5 @@
33
40
  "type": "Changed",
34
41
  "en": "create_site and create_site_from_template now stamp the new site with by_ai: \"mcp\" (persisted to the backend sites.by_ai column), extending the…",
35
42
  "vi": "create_site và create_site_from_template nay đánh dấu site mới với by_ai: \"mcp\" (lưu vào cột sites.by_ai ở backend), mở rộng dấu hiệu AI-tạo vốn chỉ…"
36
- },
37
- {
38
- "v": "1.31.10",
39
- "d": "08/09/2026",
40
- "type": "Added",
41
- "en": "list_articles accepts a term parameter to search articles by title or slug, and its response now includes page and limit alongside total.",
42
- "vi": "list_articles nay nhận thêm tham số term để tìm bài viết theo tiêu đề hoặc slug, và kết quả trả về nay có thêm page và limit bên cạnh total."
43
43
  }
44
44
  ]
@@ -144,14 +144,14 @@ that view is the public one, so hidden posts and posts scheduled in the future a
144
144
  Built via the dashboard command pipeline: title + optional summary, HTML content, image URLs, and
145
145
  category linkage. Pass category_ids from create_blog_category / list articles' categories so the
146
146
  post shows up under those categories (it is also auto-filed under the default category). Image URLs
147
- must be hosted (search_images / upload_images). The backend generates the id and slug.`, {
147
+ must be hosted (search_images / upload_images). The backend generates the id and slug.
148
+ SEO: set it afterwards with update_article({ id, seo }).`, {
148
149
  name: z.string().describe("Article title"),
149
150
  content: z.string().optional().describe("HTML content of the post"),
150
151
  summary: z.string().optional().describe("Short summary / excerpt"),
151
152
  images: z.array(z.string()).optional().describe("Hosted image URLs; the first is the cover image"),
152
153
  category_ids: z.array(z.string()).optional().describe("Blog category IDs to file the post under (from create_blog_category)"),
153
- seo: seoSchema,
154
- }, ({ name, content, summary, images, category_ids, seo }) => handle(async () => {
154
+ }, ({ name, content, summary, images, category_ids }) => handle(async () => {
155
155
  const id = randomUUID();
156
156
  const commands = [{ name: "create_article", data: { id, name } }];
157
157
  if (summary)
@@ -162,8 +162,6 @@ must be hosted (search_images / upload_images). The backend generates the id and
162
162
  commands.push({ name: "content_article", data: { id, content } });
163
163
  if (category_ids && category_ids.length)
164
164
  commands.push({ name: "bulk_add_category_to_article", data: { id, ids: category_ids } });
165
- if (seo)
166
- commands.push({ name: "set_article_seo", data: { id, meta_tags: mergeSeoTags(seo) } });
167
165
  await api.createBlogArticle(commands);
168
166
  return {
169
167
  success: true,
@@ -56,7 +56,8 @@ export function registerCatalogWriteTools(server, api, handle) {
56
56
  server.tool("create_product", `Create a product so the storefront has real merchandise (grid-product / slider-product bindings need this).
57
57
  Simple use: pass name + price (+ images, category_ids). One default variation with the price/stock is created for you.
58
58
  Advanced use: pass attributes (e.g. Color/Size) + variations for a multi-SKU product.
59
- Images must be HOSTED URLs — get them from search_images or upload_images first. The backend generates id, slug and publishes the product.`, {
59
+ Images must be HOSTED URLs — get them from search_images or upload_images first. The backend generates id, slug and publishes the product.
60
+ SEO: set it afterwards with update_product({ product_id, seo }).`, {
60
61
  name: z.string().describe("Product name"),
61
62
  price: z.number().optional().describe("Selling price (used when you don't pass variations). Required unless variations are given."),
62
63
  original_price: z.number().optional().describe("List/compare-at price for the simple single-variation case"),
@@ -71,8 +72,7 @@ Images must be HOSTED URLs — get them from search_images or upload_images firs
71
72
  .optional()
72
73
  .describe("Variant axes, e.g. [{name:'Color',values:['Đen','Trắng']},{name:'Size',values:['S','M','L']}]"),
73
74
  variations: z.array(variationSpec).optional().describe("Explicit per-SKU variations. Omit to auto-build one from price/stock/sku."),
74
- seo: seoSchema,
75
- }, ({ name, price, original_price, stock, sku, images, description, short_description, category_ids, attributes, variations, seo }) => handle(async () => {
75
+ }, ({ name, price, original_price, stock, sku, images, description, short_description, category_ids, attributes, variations }) => handle(async () => {
76
76
  let vars = variations;
77
77
  // Enrich attribute axes with the id + keyword shape the storefront variation selector
78
78
  // needs (a raw {name,values} declares the axis but attaches it to no variation).
@@ -146,11 +146,7 @@ Images must be HOSTED URLs — get them from search_images or upload_images firs
146
146
  // Success response is { product: {...} } at the top level (not under data).
147
147
  const prod = res?.product || res?.data?.product || res?.data?.attributes || res?.data || {};
148
148
  const productId = prod?.id || null;
149
- const warning = seo && productId
150
- ? await applyProductSeo(api, productId, seo).then(() => undefined, (e) => `Product created, but SEO failed: ${e?.message ?? e}`)
151
- : undefined;
152
149
  return {
153
- ...(warning ? { warning } : {}),
154
150
  success: true,
155
151
  product_id: productId,
156
152
  name,
@@ -161,13 +157,13 @@ Images must be HOSTED URLs — get them from search_images or upload_images firs
161
157
  };
162
158
  }));
163
159
  server.tool("create_product_category", `Create a product category (so grid-category / a category page has something to show, and products can be filed under it).
164
- Returns the new category id — pass it to create_product's category_ids. Image must be a hosted URL.`, {
160
+ Returns the new category id — pass it to create_product's category_ids. Image must be a hosted URL.
161
+ SEO: set it afterwards with update_product_category({ id, seo }).`, {
165
162
  name: z.string().describe("Category name"),
166
163
  image: z.string().optional().describe("Hosted image URL for the category card"),
167
164
  description: z.string().optional().describe("Category description"),
168
165
  parent_id: z.string().optional().describe("Parent category id for a sub-category"),
169
- seo: seoSchema,
170
- }, ({ name, image, description, parent_id, seo }) => handle(async () => {
166
+ }, ({ name, image, description, parent_id }) => handle(async () => {
171
167
  const id = randomUUID();
172
168
  const commands = [
173
169
  { name: "create_category", data: { id, name, ...(parent_id ? { parent_id } : {}) } },
@@ -180,25 +176,21 @@ Returns the new category id — pass it to create_product's category_ids. Image
180
176
  data: { id, multi_description: [{ id: randomUUID(), title: name, description }] },
181
177
  });
182
178
  }
183
- if (seo)
184
- commands.push({ name: "set_category_seo", data: { id, meta_tags: mergeSeoTags(seo) } });
185
179
  await api.createProductCategory(commands);
186
180
  return { success: true, category_id: id, name, ...(parent_id ? { parent_id } : {}) };
187
181
  }));
188
- server.tool("create_blog_category", `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.`, {
182
+ server.tool("create_blog_category", `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.
183
+ SEO: set it afterwards with update_blog_category({ id, seo }).`, {
189
184
  name: z.string().describe("Blog category name"),
190
185
  image: z.string().optional().describe("Hosted image URL"),
191
186
  description: z.string().optional().describe("Category description"),
192
- seo: seoSchema,
193
- }, ({ name, image, description, seo }) => handle(async () => {
187
+ }, ({ name, image, description }) => handle(async () => {
194
188
  const id = randomUUID();
195
189
  const commands = [{ name: "create_category", data: { id, name } }];
196
190
  if (description)
197
191
  commands.push({ name: "description_category", data: { id, description } });
198
192
  if (image)
199
193
  commands.push({ name: "image_category", data: { id, image } });
200
- if (seo)
201
- commands.push({ name: "set_category_seo", data: { id, meta_tags: mergeSeoTags(seo) } });
202
194
  await api.createBlogCategory(commands);
203
195
  return { success: true, category_id: id, name };
204
196
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webcake-storefront-mcp",
3
- "version": "1.33.0",
3
+ "version": "1.33.1",
4
4
  "description": "MCP server for the WebCake/StoreCake storefront builder — page CRUD, page authoring, products, orders, and more",
5
5
  "mcpName": "io.github.vuluu2k/webcake-storefront-mcp",
6
6
  "license": "MIT",