@sea-ecommerce/admin-mcp-server 0.1.3 → 0.1.4

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.
@@ -21567,6 +21567,23 @@ function loadConfig() {
21567
21567
  requiredLocales
21568
21568
  };
21569
21569
  }
21570
+ var LOCALE_CANON = {
21571
+ en: "en-US",
21572
+ "en-us": "en-US",
21573
+ "en-US": "en-US",
21574
+ zh: "zh-CN",
21575
+ "zh-cn": "zh-CN",
21576
+ "zh-CN": "zh-CN",
21577
+ ms: "ms-MY",
21578
+ "ms-my": "ms-MY",
21579
+ "ms-MY": "ms-MY",
21580
+ id: "id-ID",
21581
+ "id-id": "id-ID",
21582
+ "id-ID": "id-ID"
21583
+ };
21584
+ function normalizeLocale(input) {
21585
+ return LOCALE_CANON[input] ?? LOCALE_CANON[input.trim().toLowerCase()] ?? null;
21586
+ }
21570
21587
 
21571
21588
  // src/auth.ts
21572
21589
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
@@ -22573,15 +22590,19 @@ metadata \u4E3A**\u5408\u5E76**\u8BED\u4E49\uFF1A\u65B0\u952E\u8986\u76D6\u540C\
22573
22590
  {
22574
22591
  name: "get_product_content",
22575
22592
  description: `\u8BFB\u53D6\u5546\u54C1\u8BE6\u60C5\u9875\u5BCC\u5185\u5BB9\u5757\uFF08GET /admin/product-contents\uFF09\u3002
22576
- locale \u7528\u533A\u57DF\u7801\uFF1Aen-US / zh-CN / ms-MY / id-ID\uFF08\u4E0E\u524D\u7AEF useProductContent \u7684 localeMap \u4E00\u81F4\uFF09\u3002
22593
+ locale \u63A5\u53D7\u533A\u57DF\u7801 en-US / zh-CN / ms-MY / id-ID\uFF08\u63A8\u8350\uFF0C\u4E0E\u524D\u7AEF\u4E00\u81F4\uFF09\u6216\u77ED\u7801 en / zh / ms / id\uFF08\u81EA\u52A8\u5F52\u4E00\u5316\u4E3A\u533A\u57DF\u7801\uFF09\u3002
22577
22594
  \u8FD4\u56DE { product_content: { id, product_id, locale, status, blocks(\u5DF2\u89E3\u6790\u6570\u7EC4) } | null }\u3002`,
22578
22595
  schema: {
22579
22596
  product_id: external_exports.string(),
22580
- locale: external_exports.enum(["en-US", "zh-CN", "ms-MY", "id-ID"]).default("en-US"),
22597
+ locale: external_exports.string().default("en-US").describe("\u533A\u57DF\u7801 en-US/zh-CN/ms-MY/id-ID\uFF0C\u6216\u77ED\u7801 en/zh/ms/id"),
22581
22598
  status: external_exports.enum(["draft", "published"]).default("published")
22582
22599
  },
22583
22600
  async run(input, { client: client2 }) {
22584
- const data = await client2.getProductContent(input.product_id, input.locale, input.status);
22601
+ const locale = normalizeLocale(input.locale);
22602
+ if (!locale) {
22603
+ return `\u9519\u8BEF\uFF1Alocale "${input.locale}" \u4E0D\u53D7\u652F\u6301\uFF0C\u8BF7\u7528 en-US / zh-CN / ms-MY / id-ID\uFF08\u6216\u77ED\u7801 en/zh/ms/id\uFF09\u3002`;
22604
+ }
22605
+ const data = await client2.getProductContent(input.product_id, locale, input.status);
22585
22606
  const pc = data?.product_content;
22586
22607
  if (!pc) return { product_content: null };
22587
22608
  let blocks = [];
@@ -22604,11 +22625,11 @@ storefront \u8BE6\u60C5\u9875\u300C\u5BCC\u5185\u5BB9\u300D\u533A\u7531\u8FD9\u4
22604
22625
  - video: data.{ url, poster? }\uFF08\u652F\u6301 YouTube\uFF09
22605
22626
  - faq: data.{ items: {question,answer}[] }
22606
22627
  - specs: data.{ rows: {label,value}[] }
22607
- \u26A0\uFE0F locale \u5FC5\u987B\u7528\u533A\u57DF\u7801 en-US / zh-CN / ms-MY / id-ID\uFF08\u4E0E\u524D\u7AEF\u4E00\u81F4\uFF09\uFF1B\u5546\u54C1\u6807\u9898/\u63CF\u8FF0\u7684\u7FFB\u8BD1\u7528\u77ED\u7801 en/zh/ms/id\uFF0C\u4E8C\u8005\u4E0D\u540C\u3002
22628
+ \u26A0\uFE0F locale \u7528\u533A\u57DF\u7801 en-US / zh-CN / ms-MY / id-ID\uFF08\u4E0E\u524D\u7AEF\u4E00\u81F4\uFF0C\u63A8\u8350\uFF09\uFF1B\u4E5F\u63A5\u53D7\u77ED\u7801 en/zh/ms/id\uFF08\u81EA\u52A8\u5F52\u4E00\u5316\u4E3A\u533A\u57DF\u7801\uFF09\u3002\u5546\u54C1\u6807\u9898/\u63CF\u8FF0\u7684\u7FFB\u8BD1\u7528\u77ED\u7801\uFF0C\u4E8C\u8005\u4E0D\u540C\u3002
22608
22629
  \u9ED8\u8BA4 dry_run\uFF08confirm=false\uFF09\u4EC5\u9884\u89C8\u3002`,
22609
22630
  schema: {
22610
22631
  product_id: external_exports.string(),
22611
- locale: external_exports.enum(["en-US", "zh-CN", "ms-MY", "id-ID"]).default("en-US"),
22632
+ locale: external_exports.string().default("en-US").describe("\u533A\u57DF\u7801 en-US/zh-CN/ms-MY/id-ID\uFF0C\u6216\u77ED\u7801 en/zh/ms/id"),
22612
22633
  status: external_exports.enum(["draft", "published"]).default("published"),
22613
22634
  blocks: external_exports.array(
22614
22635
  external_exports.object({
@@ -22620,12 +22641,16 @@ storefront \u8BE6\u60C5\u9875\u300C\u5BCC\u5185\u5BB9\u300D\u533A\u7531\u8FD9\u4
22620
22641
  confirm: external_exports.boolean().default(false)
22621
22642
  },
22622
22643
  async run(input, { client: client2 }) {
22644
+ const locale = normalizeLocale(input.locale);
22645
+ if (!locale) {
22646
+ return `\u9519\u8BEF\uFF1Alocale "${input.locale}" \u4E0D\u53D7\u652F\u6301\uFF0C\u8BF7\u7528 en-US / zh-CN / ms-MY / id-ID\uFF08\u6216\u77ED\u7801 en/zh/ms/id\uFF09\u3002`;
22647
+ }
22623
22648
  if (!input.confirm) {
22624
22649
  return {
22625
22650
  dry_run: true,
22626
22651
  will_create: {
22627
22652
  product_id: input.product_id,
22628
- locale: input.locale,
22653
+ locale,
22629
22654
  status: input.status,
22630
22655
  block_count: input.blocks.length,
22631
22656
  types: input.blocks.map((b) => b.type)
@@ -22634,7 +22659,7 @@ storefront \u8BE6\u60C5\u9875\u300C\u5BCC\u5185\u5BB9\u300D\u533A\u7531\u8FD9\u4
22634
22659
  }
22635
22660
  const data = await client2.createProductContent({
22636
22661
  product_id: input.product_id,
22637
- locale: input.locale,
22662
+ locale,
22638
22663
  status: input.status,
22639
22664
  blocks: input.blocks
22640
22665
  });
@@ -22822,7 +22847,7 @@ var config2 = loadConfig();
22822
22847
  var auth = new AuthManager(config2);
22823
22848
  var client = new MedusaAdminClient(config2, auth);
22824
22849
  var ctx = { client, config: config2 };
22825
- var server = new McpServer({ name: "derlux-admin", version: "0.1.3" });
22850
+ var server = new McpServer({ name: "derlux-admin", version: "0.1.4" });
22826
22851
  for (const def of toolDefs) {
22827
22852
  server.tool(def.name, def.description, def.schema, async (args) => {
22828
22853
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sea-ecommerce/admin-mcp-server",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "让运营同学用本地 AI agent(Codex / Workbuddy / Claude / Cursor / CodeBuddy)运营 Medusa 后台的 MCP server。",
package/skill/SKILL.md CHANGED
@@ -29,7 +29,7 @@ description: 运营使用本地 AI agent(derlux-admin MCP server)操作 DERL
29
29
  6. **商品必须挂销售渠道才在前端可见**:新建商品默认**不在任何销售渠道**,storefront(按 publishable key → 渠道过滤)拉不到它,详情页表现成「空/404」。录入后用 `add_product_to_sales_channel`(`confirm=true`)把它加入渠道(默认第一个启用渠道;马来西亚站用 `sc_01M4K4F0D6HBHZ0NH6WB7H5KPT`「MY Storefront」)。
30
30
  7. **两套 locale 码,别混**:
31
31
  - 商品标题/描述的**翻译**(`create_product` 的 `translations`、后端 `/admin/translations/batch`):用**简码** `en` / `zh` / `ms` / `id`。store `/store/products?locale=zh` 即回退到 zh 翻译。
32
- - 商品详情页**富内容块**(`create_product_content` 的 `locale`):必须用**区域码** `en-US` / `zh-CN` / `ms-MY` / `id-ID`(与前端 `useProductContent` 的 localeMap 一致)。用简码会导致该语言详情页读不到内容。
32
+ - 商品详情页**富内容块**(`create_product_content` / `get_product_content` 的 `locale`):推荐用**区域码** `en-US` / `zh-CN` / `ms-MY` / `id-ID`(与前端 `useProductContent` 的 localeMap 一致);**简码 `en`/`zh`/`ms`/`id` 也会被工具自动归一化为区域码**,两种写法都能命中,但请统一用区域码避免歧义。
33
33
  8. **详情页「富内容」区靠 `create_product_content`,不是 `description`**:storefront 详情页下方大块内容由 `product_content` 模块渲染(`richtext`/`specs`/`image_gallery` 等)。只填 `product.description` 不会显示在那里——录入完整商品时必须再建一份 `product_content`(建议每语言一份)。`get_product` 默认不含该字段,核对请用 `get_product_content`。
34
34
  9. **不建库存 = 前端缺货**:变体 `manage_inventory` 默认 `true`,但新商品默认 0 库存——`create_product` 时必须给 `initial_stock`(如 `{quantity:100}`,默认写 Main Warehouse),或对已有商品调 `set_product_stock`,否则前台显示缺货、无法下单。
35
35
  10. **多语言核对用 `get_translations`**:`get_product` 默认字段**不含** translations,不要凭它为空就判断没翻译。用 `get_translations`(reference_id=商品id或handle) 读取实际写入的各语言 title/description。