Bug Report: MCP Apps UI Resource Not Rendering in Claude Desktop / claude.ai
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 32/100
- Tipo di issue
- Bug
- Chiarezza
- Da chiarire
- Stato di attività
- Attiva
- Stack tecnologico
- express, node.js, typescript
- Ambito
- api, backend-api-design, frontend
Direzione di ricerca
Inizia con il flusso di rendering dell'host di SEP-1865 e l'harness basic-host negli esempi di @modelcontextprotocol/ext-apps, quindi confrontali con il percorso mcp-remote di Claude Desktop e claude_desktop_config.json. Il lavoro è completato quando viene determinato se la compatibilità dell'host Claude o il forwarding delle capabilities è responsabile, con una conclusione riproducibile o un problema di SDK/spec chiaramente circoscritto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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/[email protected]
• 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)
- Capability Negotiation ✅
Claude sends io.modelcontextprotocol/ui in the initialize request. Server logs confirm:
Initialize [ui=true] - 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"
}]
} - Tool Registration with _meta.ui ✅
tools/list returns the tool with the correct UI linkage:
{
"name": "AMFXT",
"_meta": {
"ui": {
"resourceUri": "ui://amfxt/slidetune"
}
}
} - 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
} - 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
}
}
}]
} - 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. - 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
- Connect to MCP server at https://amfxt.com (or http://localhost:1000 locally)
- Verify Initialize [ui=true] in server logs
- Ask: "Fly me from MLA to ZRH on 20 June"
- 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":
- Host calls tools/call → receives result with structuredContent
- Host fetches resource via resources/read using the resourceUri from _meta.ui
- Host renders HTML in a sandboxed iframe
- Host sends ui/notifications/tool-result to iframe via postMessage
- 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
- Is MCP Apps UI rendering enabled in Claude Desktop for Windows as of May 2026?
- Is there a feature flag, account setting, or plan tier requirement to enable it?
- Does mcp-remote proxy correctly forward the io.modelcontextprotocol/ui extension capability? (Claude Desktop config uses mcp-remote for the connection)
- 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?
- 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"}]}]
- Lingua principale
- TypeScript
- Stelle
- 2.9k
- Fork
- 394
- Merge medio
- 4h 35m
- PR unite (30g)
- 13
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di modelcontextprotocol/ext-apps
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
modelcontextprotocol/ext-apps#786 ·
I maintainer di solito rispondono entro 1 giorno
-
Reference host renders tool.name in the app header; base spec display precedence is title → annotations.title → nameForse già presa @Michael-WhiteCapData l’ha presa 18 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
modelcontextprotocol/ext-apps#767 ·
I maintainer di solito rispondono entro 1 giorno
-
Documentation for MCP Apps does not match 2026-07-28 specificationForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
modelcontextprotocol/ext-apps#742 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
modelcontextprotocol/ext-apps#711 ·
I maintainer di solito rispondono entro 1 giorno
-
Spec: Deprecate SamplingAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
modelcontextprotocol/ext-apps#706 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di modelcontextprotocol/ext-apps
Issue simili
-
area/dashboard kind/bug QA/dev-automation
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
rancher/dashboard#19379 · 2 commenti ·
I maintainer di solito rispondono entro 5 giorni
-
perf(core): getComments() runs the approved count and the comment list as two sequential queriesApertaarea/core bot:bug bot:working
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
emdash-cms/emdash#3905 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
lingdojo/kana-dojo#31728 · 1 commento · 5 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
selective-claw: freshTailTurns=0 keeps ALL turns verbatim and summarizes none (slice(-0) === slice(0))Forse già presa @zjncs l’ha presa oggi. Apertacomponent:tokenless
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
agentic-os-org/ANOLISA#6112 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug needs triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
rjsf-team/react-jsonschema-form#5439 ·
I maintainer di solito rispondono entro 1 giorno