Building MCP Tools with Rich UIs
Learn how to design MCP tools that render interactive widgets inside ChatGPT, Claude, and Cursor using drio's visual builder.
MCP tools do not have to return plain text. Most MCP servers today return JSON or markdown — fine for simple lookups, but it falls apart the moment a user needs to interact with data. With the right setup, your tools can render interactive widgets — tables, charts, forms, product cards — directly inside ChatGPT, Claude, and Cursor.
This guide covers how to build MCP tools with rich UIs using drio's visual builder. If you are not familiar with the protocol itself, start with What Is MCP?.
Plain text vs. rich widgets
Here is what a typical MCP tool response looks like when it returns plain text:
Weather in Berlin:
Temperature: 18°C
Conditions: Partly cloudy
Wind: 12 km/h NW
Humidity: 65%Functional. But compare that to a tool that returns a card widget with the current conditions, a chart showing the 7-day forecast, and a table with the hourly breakdown — all rendered inline in the chat, styled with your brand colors.
The difference is not just cosmetic. Rich widgets let users interact with data — sort tables, click through carousels, submit forms, trigger follow-up actions — without leaving the conversation. The AI client becomes the interface.
This is possible because MCP supports structured content in tool responses. When an AI client receives structured content with widget metadata, it renders the appropriate UI inline. The MCP specification defines how this works at the protocol level.
The 5 most useful widget primitives
drio ships with 21 widget primitives out of the box. Here are the ones that cover 80% of use cases:
Data Table
Best for structured data — database records, API responses, CSV exports, search results.
Tables support sorting, filtering, and pagination. Each row can have click actions that trigger follow-up messages to the AI or open external URLs. If your tool returns a list of anything, a data table is usually the right choice.
When to use it: Product catalogs, employee directories, log entries, order histories, search results.
Form
Collect user input with validation, dropdowns, date pickers, and file uploads. Forms submit their data back to the AI as a follow-up message, which can trigger another tool call.
This creates multi-step flows. A support tool might show a form for issue submission, then use the form data to query a database, then render the result as a stat card.
When to use it: Issue submission, patient intake, booking requests, survey collection, data entry.
Chart
Visualize trends with line, bar, pie, and area charts. Charts accept data arrays and render responsive, interactive visualizations.
When to use it: Analytics dashboards, financial trends, performance metrics, forecast data, comparison views.
Product Card and Carousel
Purpose-built for commerce. Product cards show an image, title, price, description, and action buttons. Carousels display multiple cards in a swipeable layout.
Actions on product cards can trigger other tools — "add to cart," "view details," "compare." This is how you build conversational commerce experiences.
When to use it: E-commerce product search, catalog browsing, recommendation engines, menu displays.
Stat Dashboard
Display key metrics as a grid of stat cards — each showing a number, label, and optional trend indicator. Think of it as the summary view before a user drills into detail.
When to use it: KPI dashboards, account overviews, campaign summaries, system health monitoring.
Combining widgets
The real power comes from composing multiple widgets in a single tool response. A single tool can return:
- A form for filtering criteria
- A table for the filtered results
- A chart summarizing the data visually
All rendered together, inline in the chat. The user does not need to invoke three separate tools — one tool call returns a complete, interactive view.
This is different from how most MCP servers work. The typical approach is one tool, one text response. With drio, one tool response can contain an entire mini-app.
Wiring up data in drio
Every widget connects to your tool's data flow through the canvas. Here is the workflow:
- Add an API Request node — This calls your external API and returns the response
- Drag a widget onto the canvas — Pick the primitive that fits your data shape
- Map response fields to widget properties — Click a widget property, then click the corresponding API response field. drio shows you the response schema so you know exactly what is available.
- Configure actions — Set what happens when users interact with the widget (follow-up messages, open URLs, trigger other tools)
flowchart LR api["API Request node<br/>Calls the external API"] widget["Widget primitive<br/>Table · chart · form · card"] mapping["Field mapping<br/>Response schema → widget props"] actions["Action config<br/>Follow-up messages · URLs · tool triggers"] result["Interactive widget output<br/>Rendered inside the chat"] api --> widget --> mapping --> actions --> result

The visual mapper handles all the data transformation. You do not write template strings or construct JSON manually. When your API schema changes, you just reconnect the nodes — the widget updates accordingly.
For a hands-on walkthrough of connecting an API end-to-end, check out Connecting Your First API.
Branding your widgets
Every widget primitive in drio consumes a shared set of CSS custom properties derived from your app's brand configuration. This means:
- Colors — Primary, secondary, accent, and background colors applied consistently across all widgets
- Typography — Choose from 8 production-grade Google Fonts
- Corner styles — Sharp, subtle, medium, or rounded across all primitives
- Logo — Upload your logo and drio auto-extracts brand colors using k-means clustering
Light and dark themes are auto-detected from your background color luminance. A single branding configuration applies to every widget in your app.
What most guides miss
A few things that trip people up when building rich UI tools:
Widget actions are not just visual. When a user clicks "Add to Cart" on a product card, that action sends a structured message back to the AI, which can trigger another tool call. This is how you build multi-step conversational workflows — the widgets are not just displaying data, they are driving the conversation.
Hidden fields matter. Every widget can include hidden fields that are sent to the AI but not displayed to the user. This is how you pass context — a product ID, a session token, a user preference — without cluttering the visual interface. The AI uses this data to make informed follow-up responses.
Display modes change the experience. drio supports three display modes: inline (in the chat flow), picture-in-picture (floating overlay), and fullscreen. The mode you choose affects how the widget feels. A quick lookup should be inline. A complex dashboard should be fullscreen.
Try it yourself
Open the drio builder, create a new tool, and drag a Data Table widget onto the canvas. Connect it to any REST endpoint — something simple like a free weather API works great for a first test — and watch your data appear as an interactive table inside ChatGPT.
If you want the full end-to-end walkthrough, the Connecting Your First API guide walks you through every step. And if you want to see what other people are building with widgets, check out our Community Spotlight.
The best MCP tools feel like mini-apps embedded in the conversation. With drio, building them is just as intuitive as using them.


