RemoteDOMResourceRenderer Component
The <RemoteDOMResourceRenderer />
component is used to render UI resources with the application/vnd.mcp-ui.remote-dom
mime type. It leverages Shopify's remote-dom
library to securely render host-native components from a server-provided UI description.
This approach offers greater flexibility and security compared to <iframe>
-based HTML resources, enabling UIs that seamlessly integrate with the host application's look and feel.
How It Works
- The MCP server sends a resource containing a script that builds a "remote" DOM structure.
- The
@mcp-ui/client
securely executes this script in a sandboxed environment (a Web Worker inside an iframe). - As the remote DOM is manipulated, a series a JSON messages describing the changes are sent to the host window.
<RemoteDOMResourceRenderer />
receives these messages and translates them into React component tree updates.
This ensures that no arbitrary code from the server runs in the main application thread, maintaining security while allowing dynamic and interactive UIs.
Props
resource
: Theresource
object from an MCP message. ThemimeType
must beapplication/vnd.mcp-ui.remote-dom+javascript; flavor={react | webcomponents}
.library
: A component library that maps remote element tag names (e.g., "button") to your host's React components.onUIAction
: A callback function to handle events (e.g., button clicks) initiated from the remote UI.
Component Libraries
A component library is a Map
where keys are remote element tag names (as strings) and values are the corresponding React components that should render them.
@mcp-ui/client
exports a basicComponentLibrary
that maps standard HTML tags like <p>
, <div>
, <h1>
, and <button>
to simple React equivalents.
Example: Custom Library
import { MyButton, MyCard } from './MyComponents';
const customLibrary = new Map([
['fancy-button', MyButton],
['info-card', MyCard],
]);
<RemoteDOMResourceRenderer resource={resource} library={customLibrary} />
2
3
4
5
6
7
8
If the remote DOM contains <fancy-button>
, it will be rendered using your MyButton
component.
Usage
The <UIResourceRenderer />
component automatically handles rendering <RemoteDOMResourceRenderer />
when it detects the correct mime type, so you typically won't use this component directly.
import React from 'react';
import { UIResourceRenderer } from '@mcp-ui/client';
function App({ mcpResource }) {
if (
mcpResource.type === 'resource' &&
mcpResource.resource.uri?.startsWith('ui://')
) {
// UIResourceRenderer will instantiate RemoteDOMResourceRenderer internally
// if the resource mimeType is 'application/vnd.mcp-ui.remote-dom'.
return (
<UIResourceRenderer
resource={mcpResource.resource}
onUIAction={(action) => console.log('UI Action:', action)}
/>
);
}
return <p>Unsupported resource</p>;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19