mcpcompat drops entire tool/prompt result when it contains an embedded resource
维护者通常 1 天内回复
还没有人认领这个 Issue。
- #171 来自 @jhrozek —— 已关闭,未合并
评估
调研方向
从 EmbeddedResource 和 UnmarshalContent 开始,然后跟踪 CallToolResult.UnmarshalJSON 以及 issue 中描述的 convertResult 路径。使用提供的 wire payload 重现失败,并验证仅包含 resource 的内容和混合 tool 内容都能成功解码,且不会丢失同级项;同时检查 prompts/get 路径。
由索引模型根据 Issue 内容生成。
描述
Summary
mcpcompat.EmbeddedResource has a Resource ResourceContents field where ResourceContents is a non-empty interface, and EmbeddedResource has no custom UnmarshalJSON. So json.Unmarshal of any "type":"resource" content item errors:
json: cannot unmarshal object into Go struct field EmbeddedResource.resource of type mcp.ResourceContents
Because CallToolResult.UnmarshalJSON (and the client's convertResult) propagate that error, any tool result — or prompt message — containing an embedded resource is lost in its entirety, including any sibling text/image parts in the same content array.
Impact
Discovered from a ToolHive vMCP MCP-conformance run (the mcp-go → mcpcompat swap). Two conformance scenarios regressed:
tools-call-embedded-resource→ "No resource content found"tools-call-mixed-content→ "Expected multiple content items; Missing image content; Missing resource content"
The prompts/get path is affected too, since convertGetPromptResult also decodes content via mcp.UnmarshalContent.
Call chain
client.CallToolconverts the go-sdk result via the genericconvertResult→jsonConvert.- That runs
CallToolResult.UnmarshalJSON, which callsUnmarshalContentper item. UnmarshalContent, caseContentTypeResource, doesjson.Unmarshal(data, &EmbeddedResource{})— stdlib cannot populate theResourceContentsinterface field → error.- The error aborts the whole decode;
convertResultdiscards the partially-decoded result.
ReadResource and GetPrompt were hand-written to avoid this exact trap (convertReadResourceResult maps concrete text/blob types explicitly); CallTool was left on the generic path.
Fix
Add a custom UnmarshalJSON to EmbeddedResource that resolves the polymorphic Resource field to a concrete TextResourceContents/BlobResourceContents (blob-precedence, mirroring convertReadResourceResult). UnmarshalContent is the single chokepoint backing both tools/call and prompts/get.
Repro
wire := []byte(`{"type":"resource","resource":{"uri":"file:///x.txt","mimeType":"text/plain","text":"body"}}`)
_, err := mcp.UnmarshalContent(wire)
// err: json: cannot unmarshal object into Go struct field EmbeddedResource.resource of type mcp.ResourceContents
- 主要语言
- Go
- 星标
- 2
- 派生
- 6
- 平均合并
- 23 小时 44 分钟
- 30 天内合并 PR
- 133
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
stacklok/toolhive-core 的其他 Issue
-
needs-triage
难度 4/5 3-5 天 新手友好度 54/100
stacklok/toolhive-core#466 ·
维护者通常 1 天内回复
-
needs-triage
难度 3/5 1-2 天 新手友好度 66/100
stacklok/toolhive-core#426 ·
维护者通常 1 天内回复
-
mcpcompat/server: refuse dispatch of a request whose per-request context is gone可能已有人在做 @jhrozek 于 15 天前认领。 未关闭needs-triage
难度 4/5 3-5 天 新手友好度 54/100
stacklok/toolhive-core#414 ·
维护者通常 1 天内回复
-
needs-triage
难度 5/5 一周以上 新手友好度 8/100
stacklok/toolhive-core#343 ·
维护者通常 1 天内回复
-
needs-triage
难度 5/5 一周以上 新手友好度 12/100
stacklok/toolhive-core#342 ·
维护者通常 1 天内回复
查看 stacklok/toolhive-core 的全部 Issue
相似的 Issue
-
GitHub webhook is not subscribed to release events, so `event: release` never triggers可能已有人在做 @qsun 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
woodpecker-ci/woodpecker#7542 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
zilliztech/milvus-backup#1386 ·
维护者通常 1 天内回复
-
Pipelined flush no longer observes kill signals after #2042: flush backoffer is built with nil vars未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
model:sonnet runtime:claude security size:S
难度 2/5 1-3 小时 新手友好度 78/100
FootprintAI/Containarium#3624 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 86/100
维护者通常 1 天内回复