Enables the creation and serving of ChatGPT-compatible widgets using the OpenAI Apps SDK, featuring support for official UI components, automatic tool and resource registration, and interactive capabilities such as persistent state and follow-up messages.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Apps Servershow a product carousel for the latest running shoes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Apps Server
An MCP server template with OpenAI Apps SDK integration for ChatGPT-compatible widgets.
Features
🤖 OpenAI Apps SDK: Full compatibility with ChatGPT widgets
🎨 Official UI Components: Integrated OpenAI Apps SDK UI components for consistent, accessible widgets
🛒 Ecommerce Widgets: Complete ecommerce example with carousel, search, map, and order confirmation
🔄 Automatic Registration: Widgets auto-register from
resources/folder📦 Props Schema: Zod schema validation for widget props
🌙 Theme Support: Dark/light theme detection via
useWidgethook🛠️ TypeScript: Complete type safety
🔧 Widget Capabilities: Full support for
callTool,sendFollowUpMessage, and persistent state
What's New: Apps SDK Integration
This template demonstrates how to build ChatGPT-compatible widgets using OpenAI's Apps SDK:
Getting Started
Development
This starts:
MCP server on port 3000
Widget serving at
/mcp-use/widgets/*Inspector UI at
/inspector
Production
Project Structure
How Automatic Registration Works
All React components in the resources/ folder are automatically registered as MCP tools and resources when they export widgetMetadata:
This automatically creates:
Tool:
display-weather- Accepts parameters via OpenAIResource:
ui://widget/display-weather- Static access
Building Widgets with Apps SDK
Using the useWidget Hook
Note: Widgets render before the tool execution completes. On first render,
propswill be empty{}andisPendingwill betrue. Always checkisPendingbefore accessing props. See the Widget Lifecycle documentation for more details.
Defining Widget Metadata
Use Zod schemas to define widget inputs:
Theme Support
Automatically adapt to ChatGPT's theme:
Official UI Components
This template uses the OpenAI Apps SDK UI component library for building consistent, accessible widgets. The library provides:
Button: Primary, secondary, and outline button variants
Card: Container component for content sections
Carousel: Image and content carousel with transitions
Input: Form input fields
Icon: Consistent iconography
Transition: Smooth animations and transitions
Import components like this:
Ecommerce Widgets
This template includes a complete ecommerce example with four widgets:
1. Ecommerce Carousel (ecommerce-carousel.tsx)
A product carousel widget featuring:
Title and description
Carousel of product items with placeholder images
Info button and Add to Cart button for each item
Uses official Carousel, Card, Button, Icon, and Transition components
Integrates with
callToolfor cart operationsPersistent state management
2. Product Search Result (product-search-result.tsx)
A search results widget with:
Search input with real-time filtering
Price range filters and stock status filter
Grid layout of product cards
Uses
callToolto perform searchesUses
sendFollowUpMessageto update conversationPersistent filter state
3. Stores Locations Map (stores-locations-map.tsx)
A store locator widget featuring:
Interactive map display (placeholder)
List of store locations with details
Distance calculation
Get directions functionality
Store details on click
Uses
callToolfor directions and store info
4. Order Confirmation (order-confirmation.tsx)
An order confirmation widget with:
Order summary and items list
Shipping information
Order status tracking
Track order and view receipt actions
Uses
callToolfor order tracking
Brand Info Tool
The template includes a get-brand-info tool (normal MCP tool, not a widget) that returns brand information:
Example: Weather Widget
The included display-weather.tsx widget demonstrates:
Schema Definition: Zod schema for validation
Metadata Export: Widget registration info
Theme Detection: Dark/light mode support
Type Safety: Full TypeScript support
Using Widgets in ChatGPT
Via Tool Call
Via Resource Access
Customization Guide
Adding New Widgets
Create a React component in
resources/my-widget.tsx:
The widget is automatically registered!
Adding Traditional MCP Tools
You can mix Apps SDK widgets with regular MCP tools:
Testing Your Widgets
Via Inspector UI
Start the server:
npm run devOpen:
http://localhost:3000/inspectorTest widgets interactively
Direct Browser Access
Visit: http://localhost:3000/mcp-use/widgets/display-weather
Via MCP Client
Apps SDK vs Other Widget Types
Feature | Apps SDK | External URL | Remote DOM |
ChatGPT Compatible | ✅ Yes | ❌ No | ❌ No |
Theme Detection | ✅ Automatic | ❌ Manual | ❌ Manual |
Props Validation | ✅ Zod Schema | ❌ Manual | ❌ Manual |
React Support | ✅ Full | ✅ Full | ❌ Limited |
OpenAI Metadata | ✅ Yes | ❌ No | ❌ No |
Benefits of Apps SDK
✅ ChatGPT Native - Works seamlessly in ChatGPT ✅ Theme Aware - Automatic dark/light mode ✅ Type Safe - Full TypeScript with Zod validation ✅ Simple API - One hook for all props ✅ Auto Registration - Export metadata and done
Troubleshooting
Widget Not Loading
Ensure widget has
widgetMetadataexportCheck Zod schema is valid
Verify widget exists in
dist/resources/mcp-use/widgets/
Props Not Passed
Ensure schema includes all props
Check
.describe()for each propVerify
useWidgethook is called
Theme Not Applied
Theme is only available in ChatGPT
Use
themefromuseWidget()hookTest in actual ChatGPT interface
Migration from Other Templates
Moving from starter to mcp-apps:
Using Widget Capabilities
The widgets in this template demonstrate the full capabilities of the Apps SDK:
Calling Tools (callTool)
Widgets can call other MCP tools:
Sending Follow-up Messages (sendFollowUpMessage)
Widgets can send messages to the ChatGPT conversation:
Persistent State (setState)
Widgets can maintain state across interactions:
Component Library Note
This template uses the OpenAI Apps SDK UI component library. The exact component API may vary based on the library version. If you encounter import errors, check the official documentation for the correct component names and props.
If the official library is not available, you can replace the imports with custom React components or other UI libraries while maintaining the same widget structure.
Learn More
OpenAI Apps SDK UI Components - Official component library
Happy building! 🚀