OpenCloset
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data β all from the browser, and deployed in milliseconds.
This document summarizes how the three wardrobe widgets (ItemCard, MultiItemCard, OutfitCard) have been registered with the starter template.
- Displays a single wardrobe item with image and category
- Uses inline styles for consistent appearance
- Accesses data via
globalThis.openai?.toolOutput?.structuredContent
- Displays multiple wardrobe items in a 3-column grid
- Handles empty state gracefully
- Maps over items array from structured content
- Displays a complete outfit with top and bottom pieces
- Uses TypeScript CSSProperties for type safety
- Shows "Today's pick" header with labeled sections
export { default as ItemCard } from "./components/ItemCard.tsx";
export { default as MultiItemCard } from "./components/MultiItemCard.tsx";
export { default as OutfitCard } from "./components/OutfitCard.tsx";
const ITEM_CARD_URI = "ui://ItemCard";
const MULTI_ITEM_CARD_URI = "ui://MultiItemCard";
const OUTFIT_CARD_URI = "ui://OutfitCard";
Each widget is registered as a separate MCP resource with:
- Unique URI (e.g.,
ui://ItemCard) - Dedicated HTML template that imports the specific component
- Proper CSP configuration for external domains
- Skybridge MIME type for ChatGPT integration
show_item_card- Creates single item with sample datashow_multi_item_card- Creates multiple items (1-9 configurable)show_outfit_card- Creates outfit with top and bottom pieces
export const WardrobeItemSchema = z.object({
id: z.number(),
imageUrl: z.string(),
category: z.string(),
});
export const ItemCardOutputSchema = z.object({
kind: z.literal("item_card"),
item: WardrobeItemSchema,
});
export const MultiItemCardOutputSchema = z.object({
kind: z.literal("multi_item_card"),
items: z.array(WardrobeItemSchema),
});
export const OutfitCardOutputSchema = z.object({
kind: z.literal("outfit_card"),
top: WardrobeItemSchema,
bottom: WardrobeItemSchema,
});
- Uses Unsplash images for realistic wardrobe items
- Random selection from predefined categories
- Configurable item counts for multi-item displays
- Individual HTML templates for each component
- Automatic component importing and rendering
- Consistent styling with TailwindCSS and custom styles
- Proper
_metaconfiguration withopenai/outputTemplate - Structured content matching component expectations
- Error handling for missing data
- "Show me an item card"
- "Show me an item card for a dress"
- "Show me multiple wardrobe items"
- "Show me 4 wardrobe items"
- "Show me an outfit"
- "Create an outfit for me"
- β Components transpile correctly
- β Exports are accessible from widget.tsx
- β Individual component files serve properly
- β MCP resources are registered
- β Sample data generates correctly
- These widgets are individual components (not routes)
- They render as standalone widgets in ChatGPT
- Each has its own
ui://resource URI - Different from the route-based widgets (Counter, Todo, Weather)
- Uses
globalThis.openai?.toolOutput?.structuredContent - Direct access to structured data (no hooks needed)
- Matches the original component specifications exactly
- Uses inline styles for maximum compatibility
- No dependency on theme hooks or external CSS
- Consistent with the original component designs
The three wardrobe widgets are now fully registered and ready for use in ChatGPT!