Complex
While raw HTML and Remote DOM provide great ways to create UI components, they have limitations when it comes to building truly complex, interactive applications. Raw HTML requires you to write all styling from scratch, and Remote DOM, while consistent, can be cumbersome for complex layouts and interactions. For sophisticated applications that need rich functionality, responsive design, and complex state management, you need a more powerful approach.
The solution is iframe-based UI components - embedding full web applications (though normally just widgets rather than fully routed solutions) as UI resources in MCP. This approach lets you leverage entire frameworks like React, Vue, or any other web technology to create rich, interactive interfaces that can communicate with the host application through a standardized protocol.
Example:
import { createUIResource } from '@mcp-ui/server'
// Create a UI resource with an iframe for a task management widget
const resource = createUIResource({
uri: `ui://task-dashboard/${Date.now()}`,
content: {
type: 'externalUrl',
iframeUrl: 'https://example.com/widgets/task-dashboard',
},
encoding: 'text',
uiMetadata: {
'preferred-frame-size': ['1200px', '800px'],
},
})
Iframe-based UI components use the
externalUrl
content type to embed full
web applications. The uiMetadata
allows you to specify preferred sizing for
the iframe, giving the host application hints about optimal dimensions.Here's how this works in practice. When an AI assistant needs to show a complex journal viewer with interactive features like deleting entries, viewing details, and summarizing content, instead of trying to build this with raw HTML or Remote DOM, it can embed a full React application that handles all the complexity.
The iframe approach provides several key advantages:
- Full Framework Support: Use any web framework. If it can serve a web page, it can be embedded in an iframe.
- Complex State Management: Handle sophisticated application state with libraries like Redux, Zustand, or Context
- Rich Interactions: Build complex user interactions with full access to browser APIs
- Responsive Design: Leverage CSS frameworks and responsive design patterns
- Communication Protocol: Standardized
postMessage
API for iframe-to-host communication
Key message types include:
ui-lifecycle-iframe-ready
- Notify host that iframe is ready to receive messagesui-size-change
- Inform host when iframe dimensions changetool
- Request host to execute an MCP toolprompt
- Request host to send a prompt to the AIlink
- Request host to navigate to a URL
There are other message types, but they typically require specific server-client integration and are out of scope for this workshop.
Here's a sequence diagram showing how iframe-based UI components work:
In this exercise, you'll implement a sophisticated journal viewer using iframe-based UI components. You'll learn how to:
- Create iframe-based UI resources using the
externalUrl
content type - Set up proper communication between iframe and host using
postMessage
- Handle iframe lifecycle events like ready state and size changes
- Implement responsive iframe sizing that adapts to content
- Build complex interactive features within the iframe
The key difference from previous approaches is that instead of creating simple UI components, you're building full web applications that can leverage the entire ecosystem of web technologies while maintaining secure communication with the host application.
It's important to note that you can perform interactive operations with
the rawHtml or remoteDom contet types, but maintaining that can be cumbersome
and error prone.
Iframe-based UI components are more complex to implement than raw HTML or
Remote DOM, but they provide the flexibility and power needed for
sophisticated applications. The communication protocol adds complexity but
enables rich interactions between the iframe and host application.