chatgpt-app-sdk
WHEN building ChatGPT apps using the OpenAI Apps SDK and MCP; NOT for OpenAI API chat completions, agent frameworks, or MCP servers with no ChatGPT widget; create conversational, composable experiences with proper UX, UI, state management, and server patterns.
- License 许可
- MIT
- 所属仓库
- mintuz/skills
- 最近更新
- 2026-11-11
- Stars
- ★ 35
- Forks
- 7
01 前言 Front Matter
- name
- chatgpt-app-sdk
- description
- WHEN building ChatGPT apps using the OpenAI Apps SDK and MCP; NOT for OpenAI API chat completions, agent frameworks, or MCP servers with no ChatGPT widget; create conversational, composable experiences with proper UX, UI, state management, and server patterns.
02 资源文件 6
- 参考文档references/local-tunnel-setup.md3.4 KB
- 参考文档references/mcp-server.md6.3 KB
- 参考文档references/react-integration.md12.7 KB
- 参考文档references/state-management.md4.7 KB
- 参考文档references/ui-components.md4.1 KB
- 参考文档references/ui-guidelines.md2.6 KB
03 SKILL.md 正文
ChatGPT Apps SDK Best Practices
Build ChatGPT apps using the OpenAI Apps SDK, Model Context Protocol (MCP), and component-based UI patterns.
Quick Reference
| Topic | Guide |
|---|---|
| Display modes, visual design, accessibility | ui-guidelines.md |
| MCP architecture, tools, and server patterns | mcp-server.md |
| React patterns and window.openai API | ui-components.md |
| React hooks (useOpenAiGlobal, useWidgetState) | react-integration.md |
| Three-tier state architecture and best practice | state-management.md |
Critical Setup Requirements
| Issue | Prevention |
|---|---|
| CORS blocking | Enable https://chatgpt.com origin on endpoints |
| Widget 404s | Use ui://widget/ prefix format for widget resources |
| Plain text display | Set MIME type to text/html+skybridge for widgets |
| Tool not suggested | Use action-oriented descriptions in tool definitions |
| Missing widget data | Pass initial data via _meta.initialData field |
| CSP script blocking | Reference external scripts from allowed CDN origins |
The Payload Boundary Rule
Every other page in this skill defers to this rule.
structuredContent, content, _meta, and widget state all reach the user's
browser. _meta is widget-visible transport, not a private channel: the model
does not read it, but the user can. Authorise and project on the server first,
then send only the projection the current view renders.
Keep server-side: credentials, records the signed-in user may not see, internal fields the view does not render, raw diagnostics, stack traces, and technical logs. Return safe error content with an opaque correlation ID for support cases.
Send only the page or slice the view renders. To show more, return an opaque cursor or page argument and fetch the next page with another tool call.
Decision Trees
What display mode should I use?
Is this a multi-step workflow or deep exploration?
├── Yes → Fullscreen
└── No → Is this a parallel activity (game, live session)?
├── Yes → Picture-in-Picture (PiP)
└── No → Inline
├── Single item with quick action → Inline Card
└── 3-8 similar items → Inline Carousel
Where should state live?
Is this data from your API/database?
├── Yes → MCP Server (Business Data)
│ Return in structuredContent from tool calls
└── No → Is it user preference/cross-session data?
├── Yes → Backend Storage (via OAuth)
└── No → Widget State (UI-scoped, model-visible)
Use window.openai.widgetState / useWidgetState
Treat widget state as model-visible context, not private client storage: ChatGPT carries it into the conversation, where it costs tokens on later turns and the user can read it. Keep only identifiers and view preferences, such as selected ID, current page, current step, and sort order. Never keep answers, records, file contents, or credentials there; store those on the server and re-fetch them with a tool call.
A widget runs only while ChatGPT renders it. It cannot run in the background, wake up later, or act after the user leaves the conversation. Put scheduled work, waiting, and outbound notifications on the MCP server or another system you control, and let the next tool call report the result.
Should this be a separate tool?
Is this action:
- Atomic and standalone?
- Invokable by the model via natural language?
- Returning structured data?
├── Yes → Create public tool (model-accessible)
└── No → Is it only for widget interactions?
├── Yes → Use private tool ("openai/visibility": "private")
└── No → Handle within existing tool logic
What should go in structuredContent vs _meta?
Does the model need this data to:
- Understand results?
- Generate follow-ups?
- Reason about next steps?
├── Yes → structuredContent (concise, model-readable)
└── No → _meta (the authorised projection the widget renders)
Display-only data (precomputed series, layout hints) belongs in _meta; the
model does not reason about it. Apply the payload boundary rule to both halves.
Should I use custom UI or just text?
Does this require:
- User input beyond text?
- Structured data visualization?
- Interactive selection/filtering?
├── Yes → Custom UI component
└── No → Return plain text/markdown in content
Official Documentation
- MCP Specification: https://modelcontextprotocol.io
- TypeScript MCP SDK: https://github.com/modelcontextprotocol/typescript-sdk
- OpenAI Apps SDK: https://developers.openai.com/apps-sdk
- MCP Apps Extension: http://blog.modelcontextprotocol.io/posts/2025-11-21-mcp-apps
- ChatGPT Component Library: https://openai.github.io/apps-sdk-ui
04 同仓库更多 Skills
xstate
WHEN React state changes in response to an external answer — async submit, in-flight or loading flags, retries, cancellation, polling, optimistic updates, stale responses — or to an interaction with an interruptible middle, such as a drag or a gesture; or WHEN building, reviewing, testing, or visualising XState 5 actors and @xstate/react integrations; NOT for a value one event sets completely, such as a text draft, a focus flag, or a plain open and closed toggle; models typed lifecycles and renders legal Mermaid stateDiagram-v2 charts.
web-design
WHEN refining UI layout, typography, color, or polish; NOT code implementation; provides concise principles for intentional, legible design.
tailwind
WHEN building design systems or component libraries with Tailwind CSS; covers design tokens, CVA patterns and dark mode.
refactoring
WHEN you need a plan to refactor, restructure, or clean up working code and the test result is known, either green or a recorded failing set; NOT for new feature delivery or any behavior change; reversible-baseline safety with prioritized improvements.
react
WHEN building or changing React components, pages, hooks, effects, or apps, including edits to existing components; NOT for test code (react-testing) or styling (css, tailwind); enforces scalable architecture, state management, API layer, performance patterns.
react-testing
WHEN testing React components/hooks/context with React Testing Library; NOT e2e; covers renderHook, providers, forms, and anti-patterns.