ChatGPT Apps are MCP Apps. Every moonpeak resource carries both the MCP Apps metadata and the older ChatGPT Apps SDK keys, so ChatGPT renders your Views without extra work:
| moonpeak | ChatGPT key |
|---|---|
tool resource |
openai/outputTemplate |
tool invoking, invoked |
openai/toolInvocation/invoking, .../invoked |
tool visibility: ["app"] |
openai/visibility: "private" and openai/widgetAccessible: true |
resource description |
openai/widgetDescription |
resource prefersBorder |
openai/widgetPrefersBorder |
resource csp |
openai/widgetCSP |
ChatGPT-only hooks
import { useIsChatGPT, useWidgetState, useOpenAiGlobal, useUploadFile, useRequestModal, useUserAgent } from "moonpeak/chatgpt";They read window.openai and do nothing outside ChatGPT. Prefer the portable hooks when one exists: useAppState already saves to ChatGPT's widget state.
Try it in ChatGPT
- Deploy over HTTPS (see Deployment).
- In ChatGPT: Settings → Apps → enable Developer mode → Create app.
- Enter
https://your-domain/mcpand save. - In a new chat, ask for something your tool handles.
The inspector's ChatGPT host replicates window.openai (globals, widget state, display modes), so most issues show up locally first.