Skip to content

MCP Apps portability issue: widgets render in ChatGPT but not Claude due to host-specific globals and asset assumptions #413

@hatgit

Description

@hatgit

Summary

While implementing MCP Apps UI widgets, we encountered a portability issue where the same MCP server and UI widgets:

  • ✅ Render correctly in ChatGPT (Apps SDK) and a custom web host
  • ❌ Fail to render in Claude Desktop / Claude Web, despite MCP Apps support being enabled

After investigation, the issue is not with Claude specifically, but with implicit assumptions that are not currently addressed or warned about in the MCP Apps spec.

This issue is intended as constructive feedback and may fit best as non-normative guidance rather than a protocol change.


Observed behavior

  • The MCP server connects successfully in Claude
  • Tool discovery and execution may succeed or partially succeed, but the associated UI does not render
  • The UI iframe renders blank or non-functional
  • No explicit error is surfaced to the user

The same MCP server and widgets work without modification in ChatGPT.


Root causes identified

1. Reliance on host-specific runtime globals (window.openai)

Widget JavaScript uses APIs such as:

window.openai.callTool(...)
window.openai.notifyIntrinsicHeight(...)

These APIs are provided by ChatGPT’s Apps SDK, but are not part of the MCP Apps specification.
Claude does not inject window.openai, so widgets that rely on these globals fail at runtime.


2. Implicit localhost asset loading

Widget HTML references assets like:

<script src="http://localhost:4444/market-scanner.js"></script>
<link rel="stylesheet" href="http://localhost:4444/styles.css" />

This works in local development environments and some hosts, but fails in hosted MCP clients where localhost is not reachable, resulting in a blank iframe.


3. OpenAI-specific metadata keys

Tool → UI wiring uses keys such as:

"openai/outputTemplate"
"openai/csp"

These keys are specific to ChatGPT’s Apps SDK. Other hosts may ignore them entirely and instead expect the standardized MCP Apps metadata shape:

_meta.ui.resourceUri

Why this matters for MCP Apps

Without explicit guidance, MCP Apps authors may:

  • Build widgets that are unintentionally ChatGPT-only
  • Assume they are spec-compliant because things “work” in one host
  • Encounter silent failures in other hosts with no clear debugging path

This increases fragmentation and slows adoption of MCP Apps across clients.


Suggested improvements (non-normative)

These suggestions do not require protocol changes.

Portability guidance for UI authors

  • Avoid relying on injected globals like window.openai
  • Prefer host-agnostic postMessage + JSON-RPC as defined in MCP Apps

Asset hosting guidance

  • UI resources should be self-contained or served via MCP resources (ui://)
  • Hard-coded localhost asset URLs are not portable across hosts

Explicit compatibility pattern

Clarify that host-specific APIs (e.g. ChatGPT Apps SDK) may be used only as optional fallbacks, not as the primary integration mechanism.

Illustrative example:

if (window.openai?.callTool) {
  window.openai.callTool(...)
} else {
  window.parent.postMessage({
    jsonrpc: "2.0",
    method: "ui/tool-call",
    params: { ... }
  }, "*")
}

Clearer metadata examples

  • Emphasize _meta.ui.resourceUri as the portable way to bind tools to UI resources
  • Note that vendor-specific metadata keys may not be honored by other hosts

Question

Would maintainers be open to adding a short non-normative “Portability considerations for UI authors” section to the MCP Apps docs?
I’m happy to help draft wording or examples (disclosure: I did use AI to help summarize this feedback).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions