Our MCP client models a tool-result content block as text only:
type Content struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
}
internal/mcp/client.go:24-27. There is no data, mimeType, resource or annotations, and CallToolResult (:29-32) has no structuredContent. TextContent (:443-451) keeps only blocks where Type == "text" and drops everything else.
So a server returning an image, audio, an embedded resource, or structured content produces (empty MCP tool result). Browser and screenshot MCP servers are the common case: the tool call succeeds, the server returns a perfectly good image, and the model is told nothing came back. It then usually retries, which is the worst outcome.
Two parts, and the first is worth doing alone:
- Stop silently dropping. If a result contains only non-text blocks, say what they were (
returned 1 image/png block, which Zero cannot yet forward) instead of reporting empty. Prevents the retry loop even before we can carry the payload.
- Carry image blocks through. We already have the plumbing:
zeroruntime.ImageBlock and Message.Images, plus normalisation in internal/imageinput. This is gated on tool results having an image channel at all, which is a separate issue.
Our MCP client models a tool-result content block as text only:
internal/mcp/client.go:24-27. There is nodata,mimeType,resourceorannotations, andCallToolResult(:29-32) has nostructuredContent.TextContent(:443-451) keeps only blocks whereType == "text"and drops everything else.So a server returning an image, audio, an embedded resource, or structured content produces
(empty MCP tool result). Browser and screenshot MCP servers are the common case: the tool call succeeds, the server returns a perfectly good image, and the model is told nothing came back. It then usually retries, which is the worst outcome.Two parts, and the first is worth doing alone:
returned 1 image/png block, which Zero cannot yet forward) instead of reporting empty. Prevents the retry loop even before we can carry the payload.zeroruntime.ImageBlockandMessage.Images, plus normalisation ininternal/imageinput. This is gated on tool results having an image channel at all, which is a separate issue.