useWidget hook provides a type-safe React adapter for the OpenAI Apps SDK window.openai API. It automatically maps MCP UI props from toolInput, subscribes to all OpenAI global changes, and provides access to theme, display mode, safe areas, and action methods.
Import
Basic Usage
Type Parameters
The hook accepts four optional type parameters:Return Values
Props and State
| Property | Type | Description |
|---|---|---|
props | TProps | Widget props (mapped from toolInput for MCP compatibility) |
output | TOutput | null | Tool output from the last execution |
metadata | TMetadata | null | Response metadata from the tool |
state | TState | null | Persisted widget state |
setState | (state: TState | ((prev: TState | null) => TState)) => Promise<void> | Update widget state (persisted and shown to model) |
Layout and Theme
| Property | Type | Description |
|---|---|---|
theme | "light" | "dark" | Current theme (auto-syncs with ChatGPT) |
displayMode | "inline" | "pip" | "fullscreen" | Current display mode |
safeArea | SafeArea | Safe area insets for mobile layout |
maxHeight | number | Maximum height available (pixels) |
userAgent | UserAgent | Device capabilities (device, capabilities) |
locale | string | Current locale (e.g., "en-US") |
mcp_url | string | MCP server base URL for making API requests |
Actions
| Method | Signature | Description |
|---|---|---|
callTool | (name: string, args: Record<string, unknown>) => Promise<CallToolResponse> | Call a tool on the MCP server |
sendFollowUpMessage | (prompt: string) => Promise<void> | Send a follow-up message to the ChatGPT conversation |
openExternal | (href: string) => void | Open an external URL in a new tab |
requestDisplayMode | (mode: DisplayMode) => Promise<{ mode: DisplayMode }> | Request a different display mode |
notifyIntrinsicHeight | (height: number) => Promise<void> | Notify OpenAI about intrinsic height changes for auto-sizing |
Availability
| Property | Type | Description |
|---|---|---|
isAvailable | boolean | Whether the window.openai API is available |
Complete Example
Helper Hooks
For convenience, there are specialized hooks for common use cases:useWidgetProps
Get only the widget props:useWidgetTheme
Get only the theme:useWidgetState
Get state management:Key Features
1. Props Without Props
Components don’t accept props via React props. Instead, props come from the hook:2. Automatic Provider Detection
The hook automatically detects whether it’s running in:- Apps SDK (ChatGPT): Reads from
window.openai - MCP-UI: Reads from URL parameters
- Standalone: Uses default props
3. Reactive Updates
The hook subscribes to allwindow.openai global changes via the openai:set_globals event, ensuring your component re-renders when:
- Theme changes
- Display mode changes
- Widget state updates
- Tool input/output changes
4. Auto-sizing Support
UsenotifyIntrinsicHeight to notify OpenAI about height changes:
McpUseProvider with autoSize={true} for automatic height notifications.
5. State Management
Widget state persists across widget interactions and is shown to the model:6. Tool Calls
Call other MCP tools from your widget:7. Follow-up Messages
Send messages to the ChatGPT conversation:8. Display Mode Control
Request display mode changes:Default Values
The hook provides safe defaults when values are not available:theme:"light"displayMode:"inline"safeArea:{ insets: { top: 0, bottom: 0, left: 0, right: 0 } }maxHeight:600userAgent:{ device: { type: "desktop" }, capabilities: { hover: true, touch: false } }locale:"en"props:{}(ordefaultPropsif provided)output:nullmetadata:nullstate:null
Error Handling
The hook throws errors when methods are called but the API is not available:Related Components
McpUseProvider- Unified provider that includes necessary setupWidgetControls- Debug and view controlsThemeProvider- Theme managementErrorBoundary- Error handling