Cowork & Claude Code deliver MCP App tool results with Messages-API image shape; widget stuck on "Waiting for results…"

Status Open
Maintainer reply None cached
Activity 1 comment · opened Jul 17, 2026

Environment

Claude desktop app, macOS. Reproduced in the Cowork and Claude Code surfaces. Plain desktop chat and claude.ai web are not affected. MCP server: Mobbin (https://mobbin.com/api/mcp); app SDK @modelcontextprotocol/ext-apps ^1.7.1.

Expected

The host passes the raw MCP CallToolResult to the app iframe in ui/notifications/tool-result. MCP image blocks are {type:"image", data:"<base64>", mimeType:"image/..."}.

Actual

Image blocks arrive in Anthropic's Messages-API shape: {type:"image", source:{type:"base64", media_type:"image/jpeg", data:"<base64>"}}. That is not a valid MCP content block, so the ext-apps SDK (which validates against MCP's CallToolResultSchema) drops the whole notification. The app's ontoolresult never fires and the widget stays on "Waiting for results…". The model's own answer is unaffected.

Captured payload (Cowork, image data truncated)

{
  "jsonrpc": "2.0",
  "method": "ui/notifications/tool-result",
  "params": {
    "content": [
      { "type": "image",
        "source": { "type": "base64", "media_type": "image/jpeg", "data": "/9j/2wBDAAUD…(truncated)" } },
      { "type": "text",
        "text": "{\"query\":\"Airbnb login screen\",\"screens\":[…]}" }
    ],
    "isError": false,
    "structuredContent": { "query": "Airbnb login screen", "screens": [ … ] }
  }
}

Only the image block is reshaped; text and structuredContent are intact. Our server returns the correct MCP shape, so the transform happens host-side.

Impact

Any MCP App that returns an image content block is stuck loading in these two surfaces. A single small jpeg is enough. Works in plain desktop chat, claude.ai web, and ChatGPT.

Suggested fix

Pass the raw MCP CallToolResult through to the app iframe, as the chat surfaces already do.

Repro

  1. MCP server with a tool that declares an MCP App (_meta.ui.resourceUri) and returns ≥1 image block plus structuredContent.
  2. Call it from Cowork or Claude Code in the Claude desktop app.
  3. Widget stays on "Waiting for results…"; the ui/notifications/tool-result delivered to the iframe shows source.media_type instead of flat data/mimeType.

Possibly related reports (same symptom class; root cause unconfirmed for the last two)

  • modelcontextprotocol/ext-apps#696 — Claude Desktop strips structuredContent from ui/notifications/tool-result. Same notification, same class of host-side CallToolResult mutation, different field.
  • anthropics/claude-code#65653 — MCP tool-result widgets render as empty boxes (Claude Code Desktop). Same surface and symptom class, though those tools (Jira edit/transition) likely return no image blocks, so it may be a different host-side delivery bug.
  • anthropics/claude-code#48194 — Cowork renders MCP App iframes but never delivers tool results (ontoolresult never fires; closed as stale). Same symptom on Cowork; unclear whether that tool returned image blocks.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗