Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Bug Report: MCP Apps UI Resource Not Rendering in Claude Desktop / claude.ai

オープン
#671 コメント 23 件 リアクション 9 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
32/100
issue の種類
バグ
明瞭さ
説明が足りない
活発さ
活発
技術スタック
express, node.js, typescript

調査の方向性

SEP-1865 のホストレンダリングフローと @modelcontextprotocol/ext-apps の examples にある basic-host harness から始め、Claude Desktop の mcp-remote パスおよび claude_desktop_config.json と比較します。Claude host のサポートまたは capability forwarding のどちらが原因かを特定し、再現可能な結論、または範囲が明確な SDK/spec の問題を示せれば完了です。

索引モデルが issue の本文から書いたものです。

説明

bug

Bug Report: MCP Apps UI Resource Not Rendering in Claude Desktop / claude.ai
Reporter: Ernst Weyhausen (AMFXT — amfxt.com)
Date: 27 May 2026
Severity: Feature-blocking
Component: Claude Desktop (Windows) / claude.ai — MCP Apps iframe rendering


Summary
Claude (both Desktop and claude.ai) successfully negotiates io.modelcontextprotocol/ui capability with our MCP server, receives structuredContent alongside content in tool results, fetches the UI resource via resources/read, but does not render the HTML resource in an iframe. Instead, the text-only fallback message is shown:
[This tool call rendered an interactive widget in the chat. The user can already see the result — do not repeat it in text or with another visualization tool.]
No iframe or embedded UI is visible to the user.


Environment
• Claude Desktop: Latest Windows version (installed via winget install Anthropic.Claude, confirmed up to date 27 May 2026)
• claude.ai: Web interface, same account
• MCP Server: Custom Node.js/Express JSON-RPC handler at https://amfxt.com (also tested on http://localhost:1000)
• MCP Protocol Version: 2025-11-25
• MCP Apps Spec: SEP-1865, stable 2026-01-26
• SDK reference version: @modelcontextprotocol/ext-apps@1.7.2
• Connection method (claude.ai): Connected via claude.ai MCP connector settings
• Connection method (Desktop): mcp-remote proxy in claude_desktop_config.json
• OS: Windows 11


What Works (verified independently)

  1. Capability Negotiation ✅
    Claude sends io.modelcontextprotocol/ui in the initialize request. Server logs confirm:
    Initialize [ui=true]
  2. Resource Discovery ✅
    Claude calls resources/list and receives the UI resource declaration:
    {
    "resources": [{
    "uri": "ui://amfxt/slidetune",
    "name": "SlideTune Flight Comparison",
    "description": "Interactive fare comparison with bags, pets, equipment pricing, sorting and filtering",
    "mimeType": "text/html;profile=mcp-app"
    }]
    }
  3. Tool Registration with _meta.ui ✅
    tools/list returns the tool with the correct UI linkage:
    {
    "name": "AMFXT",
    "_meta": {
    "ui": {
    "resourceUri": "ui://amfxt/slidetune"
    }
    }
    }
  4. Tool Result with content + structuredContent ✅
    tools/call returns both text fallback and structured data per spec:
    {
    "content": [{ "type": "text", "text": "{...full JSON...}" }],
    "structuredContent": { "route_summary": {...}, "Swiss (LX)": [...], ... },
    "isError": false
    }
  5. Resource Read ✅
    resources/read returns the HTML resource with correct MIME type and CSP:
    {
    "contents": [{
    "uri": "ui://amfxt/slidetune",
    "mimeType": "text/html;profile=mcp-app",
    "text": "...2200 lines of interactive UI...",
    "_meta": {
    "ui": {
    "csp": {
    "resourceDomains": ["https://fonts.googleapis.com", "https://fonts.gstatic.com"]
    },
    "prefersBorder": false
    }
    }
    }]
    }
  6. End-to-End Rendering in basic-host ✅
    The identical server + UI combination renders correctly in the SDK's basic-host test harness (@modelcontextprotocol/ext-apps examples). The HTML:
    • Receives structuredContent via postMessage (ui/notifications/tool-result)
    • Parses flight data via loadFlightData()
    • Renders interactive flight cards with sorting, filtering, bag sliders, price breakdowns
    • Responds to host theme changes
    Screenshot of working basic-host rendering attached separately.
  7. MCP Inspector ✅
    MCP Inspector confirms the full JSON-RPC exchange is correct — tools/call returns valid content + structuredContent, resources/read returns valid HTML.

What Does Not Work
Claude Desktop & claude.ai: No iframe rendered ❌
Despite the complete and correct protocol exchange above, no iframe appears in the conversation. The user sees only the text:
[This tool call rendered an interactive widget in the chat. The user can already see the result — do not repeat it in text or with another visualization tool.]
This message indicates the backend/model layer acknowledges a widget should be rendered, but the frontend does not display it.


HTML Resource Details
The UI resource (SlideTune) is a self-contained ~2200-line HTML file implementing the MCP Apps lifecycle per SEP-1865:
• Sends ui/initialize request with protocolVersion: '2026-01-26'
• Sends ui/notifications/initialized notification after handshake
• Handles ui/notifications/tool-input and ui/notifications/tool-result
• Handles ui/notifications/host-context-changed (theme, safe area insets)
• Responds to ui/resource-teardown
• Uses postMessage for all communication (no SDK dependency — raw JSON-RPC per spec)
• Has baked-data fallback: works both as standalone HTML (direct URL) and as MCP App (iframe with postMessage data delivery)
• CSP requirements: Google Fonts only (fonts.googleapis.com, fonts.gstatic.com)


Steps to Reproduce

  1. Connect to MCP server at https://amfxt.com (or http://localhost:1000 locally)
  2. Verify Initialize [ui=true] in server logs
  3. Ask: "Fly me from MLA to ZRH on 20 June"
  4. Observe: tool call succeeds, data returned, but no UI rendered

Expected Behavior
Per SEP-1865 §"Host calls tool → Host renders resource UI → Server returns result → UI receives result":

  1. Host calls tools/call → receives result with structuredContent
  2. Host fetches resource via resources/read using the resourceUri from _meta.ui
  3. Host renders HTML in a sandboxed iframe
  4. Host sends ui/notifications/tool-result to iframe via postMessage
  5. UI renders interactive flight comparison

Actual Behavior
Steps 1-2 occur (confirmed by server logs). Steps 3-5 do not occur. No iframe is created. The model's text response references a widget that the user cannot see.


Questions for Anthropic

  1. Is MCP Apps UI rendering enabled in Claude Desktop for Windows as of May 2026?
  2. Is there a feature flag, account setting, or plan tier requirement to enable it?
  3. Does mcp-remote proxy correctly forward the io.modelcontextprotocol/ui extension capability? (Claude Desktop config uses mcp-remote for the connection)
  4. The "url" key in claude_desktop_config.json (for direct Streamable HTTP without mcp-remote) was rejected with "not a valid MCP configuration" — is this supported?
  5. Is there a list of hosts that currently render MCP Apps? The spec's clients page references host support varying.

Attachments
• Server logs showing complete protocol exchange
• Screenshot of successful rendering in basic-host test harness
Initialize [ui=true]
===>>> method: [notifications/initialized] -> result: [{}]
===>>> method: [resources/list] -> result: [{"resources":[{"uri":"ui://amfxt/slidetune","name":"SlideTune Flight Comparison","description":"Interactive fare comparison with bags, pets, equipment pricing, sorting and filtering","mimeType":"text/html;profile=mcp-app"}]}]
===>>> method: [resources/list] -> result: [{"resources":[{"uri":"ui://amfxt/slidetune","name":"SlideTune Flight Comparison","description":"Interactive fare comparison with bags, pets, equipment pricing, sorting and filtering","mimeType":"text/html;profile=mcp-app"}]}]
===>>> method: [tools/list] -> result: [{"tools":[{"name":"AMFXT","annotations":{"title":"AMFXT","readOnlyHint":true,"openWorldHint":true,"destructiveHint":false,"idempotentHint":false},"description":"Unified flight search, airline equipment policy, and pet transport policy tool. One tool, one call.\n\nACTION DISPATCH — set 'action' to choose mode:\n\n FLIGHTS:\n flight_search → Search flights with all-inclusive pricing (bags, pets, equipment). Supports multiple extras in one search (e.g. pet + bicycle). Returns fares across 6 classes, on-time stats, star ratings, CO₂, booking links. Supports wildcard discovery ('---').\n\n EQUIPMENT POLICIES (29 types × 600+ airlines):\n equipment_lookup → One airline + one equipment type → full policy detail\n equipment_airline → One airline → all 29 equipment policies\n equipment_compare → One equipment type across 2-5 airlines\n equipment_search → All airlines for one equipment type (with optional filter)\n\n PET POLICIES (12 modes × 21 species × 626+ airlines):"}],"_meta":{"ui":{"resourceUri":"ui://amfxt/slidetune"}}}]}]
Initialize [ui=true]
===>>> method: [notifications/initialized] -> result: [{}]
===>>> method: [tools/list] -> result: [{"tools":[{"name":"AMFXT","annotations":{"title":"AMFXT","readOnlyHint":true,"openWorldHint":true,"destructiveHint":false,"idempotentHint":false},"description":"Unified flight search, airline equipment policy, and pet transport policy tool. One tool, one call.\n\nACTION DISPATCH — set 'action' to choose mode:\n\n FLIGHTS:\n flight_search → Search flights with all-inclusive pricing (bags, pets, equipment). Supports multiple extras in one search (e.g. pet + bicycle). Returns fares across 6 classes, on-time stats, star ratings, CO₂, booking links. Supports wildcard discovery ('---').\n\n EQUIPMENT POLICIES (29 types × 600+ airlines):\n equipment_lookup → One airline + one equipment type → full policy detail\n equipment_airline → One airline → all 29 equipment policies\n equipment_compare → One equipment type across 2-5 airlines\n equipment_search → All airlines for one equipment type (with optional filter)\n\n PET POLICIES (12 modes × 21 species × 626+ airlines):"}],"_meta":{"ui":{"resourceUri":"ui://amfxt/slidetune"}}}]}]
===>>> method: [resources/list] -> result: [{"resources":[{"uri":"ui://amfxt/slidetune","name":"SlideTune Flight Comparison","description":"Interactive fare comparison with bags, pets, equipment pricing, sorting and filtering","mimeType":"text/html;profile=mcp-app"}]}]

Image
主要言語
TypeScript
スター
2.9k
フォーク
387
平均マージ
2時間 54分
マージ済み PR(30日)
7

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

modelcontextprotocol/ext-apps のほかの issue

modelcontextprotocol/ext-apps の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。