Bug: publish_content 的 images 既是 required 又允许 null,且缺少 minItems,与文档「至少需要1张图片」矛盾
环境
- 镜像:
xpzouying/xiaohongshu-mcp(latest,启动日志显示version: v2.5.0) - 部署:docker compose,MCP over HTTP,
http://localhost:18060/mcp - 客户端:Claude Code + MCP Inspector(两端 schema 一致)
问题
publish_content 的 images 同时满足以下三点,导致契约自相矛盾:
- 出现在
required里 type允许null- 没有
minItems
而字段描述明确写着「至少需要1张图片」。
从 tools/list 取到的原始 schema(未经任何客户端加工):
"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:
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 是必填且不允许为空,建议明确表达为:
"images": { "type": "array", "items": {"type": "string"}, "minItems": 1 }tags / products 带 omitempty,本身是可选的,允许 null 影响较小,可按需处理。
附带:schema 可移植性
同一处反射还导致 publish_content(images/tags/products)和 publish_with_video(tags/products)的 type 是数组形式。MCP Inspector 会对此报 schema portability 警告:type 数组是合法 JSON Schema,但部分 MCP 客户端只按单一字符串解析,可能直接拒绝该工具或丢弃约束。
Claude Code 实测可以正常接收和调用,所以这条只影响跨客户端兼容性,优先级低于上面的 images 契约问题。
对可选字段而言,等价写法是:
{ "anyOf": [ {"type": "null"}, {"type": "array", "items": {"type": "string"}} ] }Source: xpzouying/xiaohongshu-mcp