npx claudepluginhub rehan-ul-haq/my-skills --plugin my-skillsThis skill uses the workspace's default tool permissions.
Create production-ready widgets for ChatGPT Apps following official OpenAI guidelines.
assets/templates/react-widget/Widget.tsxassets/templates/react-widget/hooks.tsassets/templates/react-widget/index.tsassets/templates/vanilla-widget/widget.htmlreferences/authentication.mdreferences/display-modes.mdreferences/react-hooks.mdreferences/state-management.mdreferences/ux-principles.mdreferences/window-openai-api.mdBuilds MCP apps adding interactive UI widgets like forms, pickers, dashboards, and confirmation dialogs to MCP servers for inline rendering in Claude and ChatGPT chats.
Generates JSON UI specs from predefined component catalogs for json-render framework, covering renderer selection (React, shadcn, React Native), catalog design, MCP Apps delivery, and GemSkills visual asset integration.
Provides best practices for building ChatGPT apps using OpenAI Apps SDK and MCP, including UI patterns, React hooks, state management, server architecture, and decision trees.
Share bugs, ideas, or general feedback.
Create production-ready widgets for ChatGPT Apps following official OpenAI guidelines.
window.openai integrationreferences/authentication.md for patterns)| Dependency | Version/Notes |
|---|---|
window.openai API | Required - injected by ChatGPT runtime |
| Modern browser | ES2020+, CSS Grid/Flexbox |
| CSP compliance | No inline scripts, approved CDNs only |
No external dependencies required - widgets run in ChatGPT's sandboxed iframe.
Never build a widget without understanding requirements. Ask these questions:
Data Shape: "What data will this widget display? Can you show the expected toolOutput structure?"
Example: { items: [{ id: 1, title: "...", status: "..." }], total: 10 }
Read vs Write: "Is this display-only or does it allow editing/submission?"
Single vs Multi-turn: "Does the task complete in one exchange or persist across interactions?"
Display Mode: "Which display mode fits your use case?"
inline (default) - Simple displays, โค2 actions, in conversation flowfullscreen - Complex workflows, editing, maps, detailed viewspip - Persistent content like video, games, live sessionsMCP Tool Name: "What tool should be called for actions?" (if interactive)
Check existing context first:
Proceed only after requirements are clear.
Reference these for latest patterns and complex widgets:
| Resource | URL | Use For |
|---|---|---|
| UX Principles | https://developers.openai.com/apps-sdk/concepts/ux-principles | Design decisions |
| UI Guidelines | https://developers.openai.com/apps-sdk/concepts/ui-guidelines | Visual design rules |
| Component Types | https://developers.openai.com/apps-sdk/plan/components | List, Map, Album, Carousel, Shop patterns |
| Build ChatGPT UI | https://developers.openai.com/apps-sdk/build/chatgpt-ui | Implementation, CSP, bundling |
| State Management | https://developers.openai.com/apps-sdk/build/state-management | Widget state, persistence patterns |
| Authentication | https://developers.openai.com/apps-sdk/build/auth | OAuth 2.1 for user-specific data (advanced) |
| UI Components | https://openai.github.io/apps-sdk-ui/ | Pre-built UI library |
| Example Apps | https://github.com/openai/openai-apps-sdk-examples | Reference implementations |
For complex widgets (maps, charts, 3D, video players) not covered below, fetch from these docs.
Version Note: OpenAI Apps SDK is actively evolving. When building complex widgets, fetch latest docs to verify API signatures and CSP rules haven't changed.
Before implementation, verify widget concept passes:
If widget concept violates these, redesign before building.
See references/ux-principles.md for complete guidelines.
Reference: https://developers.openai.com/apps-sdk/build/state-management
| State Type | Owner | Lifetime | Example |
|---|---|---|---|
| Business Data | MCP Server | Long-lived | Tasks, documents, user records |
| UI State | Widget | Message-scoped | Selections, expanded panels, sort order |
| Cross-Session | Backend Storage | Persistent | Saved filters, preferences |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. User action in widget โ
โ 2. Widget calls server tool (callTool) โ
โ 3. Server updates authoritative data โ
โ 4. Server returns new snapshot (toolOutput) โ
โ 5. Widget re-renders with snapshot + local UI state โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Server is authoritative - Never let UI state diverge from server data.
// Tool output (structuredContent from MCP)
const data = window.openai?.toolOutput;
// Private metadata (_meta, not sent to model)
const meta = window.openai?.toolResponseMetadata;
// Listen for updates
window.addEventListener('openai:set_globals', () => {
const newData = window.openai?.toolOutput;
});
const theme = window.openai?.theme ?? 'light';
// Apply system fonts: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif
const result = await window.openai?.callTool('tool_name', { param: value });
const responseData = result?.structuredContent;
// Save (shown to model, <4KB)
window.openai?.setWidgetState({ selectedId: 5 });
// Read
const saved = window.openai?.widgetState;
// Tool call with error handling
async function safeToolCall(toolName: string, params: object) {
try {
const result = await window.openai?.callTool(toolName, params);
if (result?.isError) {
showError(result.content?.[0]?.text ?? 'Operation failed');
return null;
}
return result?.structuredContent;
} catch (err) {
showError('Connection error. Please try again.');
return null;
}
}
// Data validation
function validateToolOutput(data: unknown): data is ExpectedType {
return data != null && typeof data === 'object' && 'requiredField' in data;
}
Always handle: Missing data, malformed responses, network failures, timeouts.
See references/window-openai-api.md for complete API reference.
Reference: https://developers.openai.com/apps-sdk/plan/components
callTool, results visualizationcallToolFor patterns not listed, fetch from official docs.
Every widget must include:
window.openai data access with null checksopenai:set_globalswindow.openai.theme)Read based on need (progressive disclosure):
| File | When to Read |
|---|---|
references/window-openai-api.md | API details, CSP configuration |
references/state-management.md | Widget state, persistence patterns |
references/display-modes.md | Choosing/implementing display modes |
references/ux-principles.md | Validating design decisions |
references/react-hooks.md | Building React widgets |
references/authentication.md | OAuth 2.1 for user-specific data (advanced) |
Copy and customize:
assets/templates/vanilla-widget/ - HTML/CSS/JS, no build stepassets/templates/react-widget/ - TypeScript with hooks