This guide walks you through creating a complete MCP server that supports MCP Apps widgets, enabling rich interactive experiences in ChatGPT or Claude.
What You'll Build
By the end of this guide, you'll have:
- A fully functional MCP server with MCP Apps 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 MCP Apps template:
This creates a project structure:
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 MCP Apps widgetsversion: Server version for client discoverydescription: Human-readable server description
Step 3: Create Your First Widget
Widgets are React components in the resources/ folder. They're automatically registered as both MCP tools and resources.
Create resources/user-profile.tsx:
How Automatic Registration Works
When you call server.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 MCP Apps compatibility
No manual registration needed!
Step 4: Add Traditional MCP Tools
You can mix automatic widgets with traditional tools:
Step 5: Configure MCP Apps Metadata
For production widgets, you may want to customize MCP Apps metadata. You can do this manually:
However, with automatic registration, metadata is generated automatically based on your widgetMetadata.
Step 6: Testing Your Server
Start the Development Server
This starts:
- 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
The build process:
- Compiles TypeScript
- Bundles React widgets for MCP Apps
- Optimizes assets
- Generates production-ready HTML templates
Content Security Policy
When baseUrl is set, CSP is automatically configured:
This ensures:
- 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:
See the Deployment Guide for details.
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 MCP Apps 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
- MCP Apps Resources - MCP Apps primitives and metadata
- Server Introduction - Explore available templates and getting started
- 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 MCP Apps support
- ✅ Use automatic widget registration
- ✅ Build React widgets with
useWidgethook - ✅ Configure MCP Apps metadata
- ✅ Test and deploy your server
Your MCP server is now ready to provide rich interactive experiences in ChatGPT or Claude!







