Skip to main content
Estimated reading time: 12 minutes
Transforming JSON tool responses into rich UI widgets Here’s what happens when your AI tool returns data:
The user sees… JSON. Or maybe the LLM summarizes it into text. Either way, it’s functional but not beautiful. Not interactive. Not what users expect from modern AI apps. What if your tool could return this instead? UI widgets example A beautiful card with the temperature displayed prominently, a weather icon, a gradient background—rendered right inside ChatGPT. That’s exactly what FrontMCP’s Tool UI does.

The Platform Fragmentation Problem

Rich UI in AI responses sounds simple until you realize:
  • ChatGPT renders widgets in iframes with specific security rules
  • Claude has limited UI support
  • OpenAI Apps SDK expects specific metadata formats
  • Each platform has different CSP (Content Security Policy) requirements
  • You can’t use external scripts or stylesheets
Building widgets for each platform means: Most developers give up and return plain text. FrontMCP handles all of this automatically. You write one template, and Tool UI adapts it to each platform.

What is Tool UI?

Tool UI is a rendering system built into FrontMCP that:

Type-Safe Templates

Template functions receive typed input and output based on your Zod schemas. TypeScript catches errors before runtime.

Platform Aware

Automatically detects ChatGPT, Claude, ext-apps, and custom clients. Renders appropriately for each.

Security Built-In

XSS prevention, safe JSON embedding, Content Security Policy—all handled automatically.

Graceful Degradation

If a platform doesn’t support UI, your tool still returns structured data. Never fails silently.

Your First Widget

Let’s add a UI widget to a weather tool. Start with a basic tool:
Now add the ui property:
When ChatGPT calls this tool, users see a beautiful weather card—not raw JSON.

Template Context API

The template function receives a context object with everything you need:

Type Safety

Because inputSchema and outputSchema are Zod schemas, TypeScript knows exactly what’s available:
Always use ctx.helpers.escapeHtml() for user-provided data. It prevents XSS attacks by escaping <, >, &, ", and '.

Serving Modes

Tool UI supports four serving modes, each with different trade-offs: Tool UI Serving Modes Comparison Diagram
Renders HTML on every request, embeds in response metadata.
Pros:
  • Fresh content every time
  • Simple to implement
  • Works with all platforms
Cons:
  • Larger response payload
  • Rendering overhead per request
Best for: Dynamic content that changes per request

Using @frontmcp/ui Components

Writing raw HTML gets tedious. FrontMCP provides two approaches: HTML string functions for simple templates and React components for interactive widgets.

HTML String Components

Import from @frontmcp/ui/components—these functions return HTML strings:

React Widgets (Static Mode)

For complex, interactive widgets, create a separate React component file. FrontMCP bundles these at server startup and serves them as static widgets: 1. Create the widget file (widgets/weather-widget.tsx):
2. Reference the widget in your tool:
React widgets are transpiled once at server startup, not on every request. The bundled widget reads tool output from the platform context (window.openai.toolOutput on ChatGPT) and can call back to tools via the MCP Bridge.

Choosing Your Approach

Available Components

card()

Container with title, subtitle, and actions

badge()

Status indicators and labels

button()

Interactive buttons (for MCP Bridge)

descriptionList()

Key-value data display

table()

Tabular data rendering

alert()

Status messages and notifications
HTML String Components (@frontmcp/ui/components):
  • card(content, options) - Card container
  • badge(text, options) - Status badge
  • button(text, options) - Clickable button
  • descriptionList(items, options) - Key-value pairs
  • table(columns, data, options) - Data table
  • alert(content, options) - Alert message
  • form(content, options) - Form container
  • input(options) - Text input
  • select(options) - Dropdown select
  • modal(content, options) - Modal dialog
React Components (@frontmcp/ui/react) - for static widgets:
  • <Card> - Card container with title, subtitle, actions
  • <Badge> - Status indicators and labels
  • <Button> - Clickable buttons with loading state
  • <Alert> - Info, success, warning, danger alerts
React Hooks (@frontmcp/ui/react/hooks) - for interactive widgets:
  • useToolInput<T>() - Get typed tool input
  • useToolOutput<T>() - Get typed tool output
  • useCallTool(name) - Call another tool from widget
  • useTheme() - Access theme context
  • useMcpBridge() - Low-level bridge access

Security Features

Tool UI has security built in at multiple layers:

XSS Prevention

The escapeHtml() helper escapes dangerous characters:
Always escape user-provided data:

Safe JSON Embedding

Need to pass data to JavaScript in your widget?

Content Security Policy

FrontMCP generates appropriate CSP headers for each platform:
Never use eval(), new Function(), or inline event handlers like onclick. These are blocked by CSP and create security vulnerabilities.

Platform Behavior

ChatGPT (OpenAI Apps SDK)

ChatGPT renders Tool UI widgets in an iframe: The widget can access tool output via window.openai.toolOutput for static serving mode.

Claude

Claude has limited UI support. Tool UI gracefully degrades:
  • Widgets are not rendered
  • Tool returns structured JSON as usual
  • Claude summarizes the data in natural language
This is automatic—no code changes needed.

Custom Clients

For custom MCP clients, Tool UI metadata is available in _meta:
Your client can render the HTML or ignore it.

Advanced: MCP Bridge

For truly interactive widgets, use the MCP Bridge to call tools from within the widget:
MCP Bridge is only available in platforms that support it (currently ChatGPT with OpenAI Apps SDK). Use feature detection before calling window.frontmcp.

Real-World Example: Complete Weather Widget

Here’s a production-ready weather widget with all best practices:

Get Started

Tool UI Documentation

Complete API reference for templates, components, and configuration

Component Library

Browse all available UI components with examples

Platform Integration

Deep dive into ChatGPT, Claude, and custom client support

MCP Bridge Guide

Build interactive widgets that call back to your tools

Tool UI is part of FrontMCP’s mission to make AI tools feel native and beautiful. Combine it with Agents for autonomous workflows and deploy to Vercel for global edge performance. Star us on GitHub to follow development.