Bug: publish_content 的 images 既是 required 又允许 null,且缺少 minItems,与文档「至少需要1张图片」矛盾

Author: BretttttttttCreated Aug 28, 2026Updated Aug 28, 2026

环境

  • 镜像:xpzouying/xiaohongshu-mcplatest,启动日志显示 version: v2.5.0
  • 部署:docker compose,MCP over HTTP,http://localhost:18060/mcp
  • 客户端:Claude Code + MCP Inspector(两端 schema 一致)

问题

publish_contentimages 同时满足以下三点,导致契约自相矛盾:

  1. 出现在 required
  2. type 允许 null
  3. 没有 minItems

而字段描述明确写着「至少需要1张图片」。

tools/list 取到的原始 schema(未经任何客户端加工):

json
"required": ["title", "content", "images"],
"images": {
  "type": ["null", "array"],
  "items": { "type": "string" },
  "description": "图片路径列表(至少需要1张图片)。..."
}

因此下面两种入参都能通过 schema 校验,但都违反文档要求:

  • {"images": null}
  • {"images": []}

校验放行之后,真正的失败会推迟到浏览器自动化内部才暴露,报错信息对调用方很不友好;对 LLM 客户端来说,schema 没有约束就意味着它有可能真的这么传。

根因

schema 是从 Go struct 反射生成的,不是手写的。mcp_server.go:22

go
Images   []string `json:"images" jsonschema:"图片路径列表(至少需要1张图片)。..."`
Tags     []string `json:"tags,omitempty" jsonschema:"..."`
Products []string `json:"products,omitempty" jsonschema:"..."`

Go 的 nil slice 序列化成 null,所以每个 []string 都被反射成 ["null","array"]。这也解释了为什么 images / tags / products 三个字段表现完全一致——不是某一处笔误。

建议

images 是必填且不允许为空,建议明确表达为:

json
"images": { "type": "array", "items": {"type": "string"}, "minItems": 1 }

tags / productsomitempty,本身是可选的,允许 null 影响较小,可按需处理。

附带:schema 可移植性

同一处反射还导致 publish_contentimages/tags/products)和 publish_with_videotags/products)的 type 是数组形式。MCP Inspector 会对此报 schema portability 警告:type 数组是合法 JSON Schema,但部分 MCP 客户端只按单一字符串解析,可能直接拒绝该工具或丢弃约束。

Claude Code 实测可以正常接收和调用,所以这条只影响跨客户端兼容性,优先级低于上面的 images 契约问题。

对可选字段而言,等价写法是:

json
{ "anyOf": [ {"type": "null"}, {"type": "array", "items": {"type": "string"}} ] }

Source: xpzouying/xiaohongshu-mcp