Protocol Detection
Overview
Section titled “Overview”Studio checks widget compatibility with ChatGPT and Claude by detecting which communication protocol the widget uses. Results appear as compatibility badges after tool execution.
| Badge | Meaning |
|---|---|
| ChatGPT ✓ | Widget uses window.openai (legacy) or ext-apps protocol |
| Claude ✓ | Widget uses the ext-apps protocol (MCP Apps) |
Two widget protocols
Section titled “Two widget protocols”Legacy OpenAI (window.openai)
Section titled “Legacy OpenAI (window.openai)”The original ChatGPT widget protocol. The host injects a window.openai global with toolInput, toolOutput, and action methods.
const data = window.openai.toolOutput;Supported by: ChatGPT only.
ext-apps (MCP Apps)
Section titled “ext-apps (MCP Apps)”The JSON-RPC protocol used by Claude and ChatGPT. The widget communicates with the host via window.parent.postMessage, starting with a ui/initialize handshake.
window.parent.postMessage({ jsonrpc: "2.0", id: 1, method: "ui/initialize", params: { protocolVersion: "2026-01-26", appInfo: { name: "my-widget", version: "1.0.0" }, appCapabilities: {}, },}, "*");Supported by: ChatGPT and Claude.
How Studio detects each protocol
Section titled “How Studio detects each protocol”Static detection (before render)
Section titled “Static detection (before render)”Runs when widget HTML is loaded, before the iframe executes JavaScript.
| Signal | Detects | Source |
|---|---|---|
window.openai in HTML | legacy OpenAI | Regex scan |
ui/initialize in HTML | ext-apps | Regex scan |
@modelcontextprotocol/ext-apps in HTML | ext-apps | SDK import |
Resource MIME text/html;profile=mcp-app | ext-apps | MCP resource metadata |
_meta.ui in tool/resource response | ext-apps | MCP response metadata |
Runtime detection (during render)
Section titled “Runtime detection (during render)”Fires when the widget actually accesses an API inside the iframe.
| Signal | Detects | Mechanism |
|---|---|---|
Widget reads window.openai.toolInput or toolOutput | legacy OpenAI | Getter trap on injected mock |
Widget sends ui/initialize via postMessage | ext-apps | Message listener on iframe |
Runtime detection is a fallback for cases where static analysis misses (e.g., minified code or dynamic protocol selection).
