This guide walks you through creating a complete MCP server that supports OpenAI Apps SDK widgets, enabling rich interactive experiences in ChatGPT and other OpenAI-powered applications.
What You’ll Build
By the end of this guide, you’ll have:- A fully functional MCP server with Apps SDK support
- Automatic widget registration from React components
- Tools that return interactive widgets
- Production-ready configuration
Prerequisites
- Node.js 18+ installed
- Basic knowledge of TypeScript and React
- Familiarity with MCP concepts (see MCP 101)
Step 1: Create Your Project
The easiest way to start is using the Apps SDK template:Step 2: Understanding the Server Setup
Let’s examine the server entry point (index.ts):
Key Configuration Options
baseUrl: Required for production. Used to configure Content Security Policy (CSP) for Apps SDK widgetsversion: Server version for client discoverydescription: Human-readable server description
Step 3: Create Your First Widget
Widgets are React components in theresources/ folder. They’re automatically registered as both MCP tools and resources.
Create resources/user-profile.tsx:
How Automatic Registration Works
When you callserver.listen(), the framework:
- Scans the
resources/directory for.tsxfiles - Extracts
widgetMetadatafrom each component - Registers a tool with the filename as the name (e.g.,
user-profile) - Registers a resource at
ui://widget/user-profile.html - Builds the widget for Apps SDK compatibility
Step 4: Add Traditional MCP Tools
You can mix automatic widgets with traditional tools:Step 5: Configure Apps SDK Metadata
For production widgets, you may want to customize Apps SDK metadata. You can do this manually:widgetMetadata.
Step 6: Testing Your Server
Start the Development Server
- MCP server on port 3000
- Widget development server with Hot Module Replacement (HMR)
- Inspector UI at
http://localhost:3000/inspector
Test in Inspector
- Open
http://localhost:3000/inspector - Navigate to the Tools tab
- Find your
user-profiletool - Enter test parameters:
- Click Execute to see the widget render
Test in ChatGPT
- Configure your MCP server in ChatGPT settings
- Ask ChatGPT: “Show me a user profile for Jane Smith, email [email protected], role admin”
- ChatGPT will call the
user-profiletool and display the widget
Step 7: Advanced Widget Features
Accessing Tool Output
Widgets can access the output of their own tool execution:Calling Other Tools
Widgets can call other MCP tools:Persistent State
Widgets can maintain state across interactions:Step 8: Production Configuration
Environment Variables
Create a.env file:
Build for Production
- Compiles TypeScript
- Bundles React widgets for Apps SDK
- Optimizes assets
- Generates production-ready HTML templates
Content Security Policy
WhenbaseUrl is set, CSP is automatically configured:
- Widget URLs use the correct domain
- CSP includes your server domain
- Works behind proxies and custom domains
Step 9: Deployment
Deploy to mcp-use Cloud
The easiest deployment option:Manual Deployment
- Build your server:
npm run build - Set environment variables
- Deploy to your hosting platform (Railway, Render, etc.)
- Update
MCP_URLto your production domain
Best Practices
1. Schema Design
Use descriptive Zod schemas to help LLMs understand your widgets:2. Theme Support
Always support both light and dark themes:3. Error Handling
Handle missing or invalid props gracefully:4. Widget Focus
Keep widgets focused on a single purpose:Troubleshooting
Widget Not Appearing
Problem: Widget file exists but tool doesn’t appear Solutions:- Ensure file has
.tsxextension - Export
widgetMetadataobject - Export default React component
- Check server logs for errors
Props Not Received
Problem: Component receives empty props Solutions:- Use
useWidget()hook (not React props) - Ensure
widgetMetadata.inputsis a valid Zod schema - Verify tool parameters match schema
- Check Apps SDK is injecting
window.openai.toolInput
CSP Errors
Problem: Widget loads but assets fail with CSP errors Solutions:- Set
baseUrlin server config - Add external domains to CSP whitelist
- Use HTTPS for all resources
Next Steps
- UI Widgets Overview - Deep dive into automatic widget registration
- Apps SDK Resources - Apps SDK primitives and metadata
- Project Templates - Explore available templates
- Deployment Guide - Deploy your server to production
Example: Complete Server
Here’s a complete example combining everything:Summary
You’ve learned how to:- ✅ Create an MCP server with Apps SDK support
- ✅ Use automatic widget registration
- ✅ Build React widgets with
useWidgethook - ✅ Configure Apps SDK metadata
- ✅ Test and deploy your server