
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@postman/mcp-ui-client
Advanced tools
What's mcp-ui? β’ Core Concepts β’ Installation β’ Getting Started β’ Walkthrough β’ Examples β’ Security β’ Roadmap β’ Contributing β’ License
mcp-ui
brings interactive web components to the Model Context Protocol (MCP). Deliver rich, dynamic UI resources directly from your MCP server to be rendered by the client. Take AI interaction to the next level!
This project is an experimental community playground for MCP UI ideas. Expect rapid iteration and enhancements!
mcp-ui
?mcp-ui
is a collection of SDKs comprising:
@mcp-ui/server
(TypeScript): Utilities to generate UI resources (UIResource
) on your MCP server.@mcp-ui/client
(TypeScript): UI components (e.g., <UIResourceRenderer />
) to render the UI resources and handle their events.mcp_ui_server
(Ruby): Utilities to generate UI resources on your MCP server in a Ruby environment.Together, they let you define reusable UI snippets on the server side, seamlessly and securely render them in the client, and react to their actions in the MCP host environment.
In essence, by using mcp-ui
SDKs, servers and hosts can agree on contracts that enable them to create and render interactive UI snippets (as a path to a standardized UI approach in MCP).
The primary payload returned from the server to the client is the UIResource
:
interface UIResource {
type: 'resource';
resource: {
uri: string; // e.g., ui://component/id
mimeType: 'text/html' | 'text/uri-list' | 'application/vnd.mcp-ui.remote-dom'; // text/html for HTML content, text/uri-list for URL content, application/vnd.mcp-ui.remote-dom for remote-dom content (Javascript)
text?: string; // Inline HTML, external URL, or remote-dom script
blob?: string; // Base64-encoded HTML, URL, or remote-dom script
};
}
uri
: Unique identifier for caching and routing
ui://β¦
β UI resources (rendering method determined by mimeType)mimeType
: text/html
for HTML content (iframe srcDoc), text/uri-list
for URL content (iframe src), application/vnd.mcp-ui.remote-dom
for remote-dom content (Javascript)
text/uri-list
format supports multiple URLs, MCP-UI uses only the first valid http/s
URL and warns if additional URLs are foundtext
vs. blob
: Choose text
for simple strings; use blob
for larger or encoded content.The UI Resource is rendered in the <UIResourceRenderer />
component. It automatically detects the resource type and renders the appropriate component.
It accepts the following props:
resource
: The resource object from an MCP Tool response. It must include uri
, mimeType
, and content (text
, blob
)onUIAction
: Optional callback for handling UI actions from the resource:
{ type: 'tool', payload: { toolName: string, params: Record<string, unknown> }, messageId?: string } |
{ type: 'intent', payload: { intent: string, params: Record<string, unknown> }, messageId?: string } |
{ type: 'prompt', payload: { prompt: string }, messageId?: string } |
{ type: 'notify', payload: { message: string }, messageId?: string } |
{ type: 'link', payload: { url: string }, messageId?: string }
When actions include a messageId
, the iframe automatically receives response messages for asynchronous handling.supportedContentTypes
: Optional array to restrict which content types are allowed (['rawHtml', 'externalUrl', 'remoteDom']
)htmlProps
: Optional props for the internal <HTMLResourceRenderer>
style
: Optional custom styles for the iframeiframeProps
: Optional props passed to the iframe elementremoteDomProps
: Optional props for the internal <RemoteDOMResourceRenderer>
library
: Optional component library for Remote DOM resources (defaults to basicComponentLibrary
)remoteElements
: remote element definitions for Remote DOM resources.text/html
and text/uri-list
)Rendered using the internal <HTMLResourceRenderer />
component, which displays content inside an <iframe>
. This is suitable for self-contained HTML or embedding external apps.
mimeType
:
text/html
: Renders inline HTML content.text/uri-list
: Renders an external URL. MCP-UI uses the first valid http/s
URL.application/vnd.mcp-ui.remote-dom
)Rendered using the internal <RemoteDOMResourceRenderer />
component, which utilizes Shopify's remote-dom
. The server responds with a script that describes the UI and events. On the host, the script is securely rendered in a sandboxed iframe, and the UI changes are communicated to the host in JSON, where they're rendered using the host's component library. This is more flexible than iframes and allows for UIs that match the host's look-and-feel.
mimeType
: application/vnd.mcp-ui.remote-dom+javascript; framework={react | webcomponents}
UI snippets must be able to interact with the agent. In mcp-ui
, this is done by hooking into events sent from the UI snippet and reacting to them in the host (see onUIAction
prop). For example, an HTML may trigger a tool call when a button is clicked by sending an event which will be caught handled by the client.
# using npm
npm install @mcp-ui/server @mcp-ui/client
# or pnpm
pnpm add @mcp-ui/server @mcp-ui/client
# or yarn
yarn add @mcp-ui/server @mcp-ui/client
gem install mcp_ui_server
You can use GitMCP to give your IDE access to mcp-ui
's latest documentation!
Server-side: Build your UI resources
import { createUIResource } from '@mcp-ui/server';
import {
createRemoteComponent,
createRemoteDocument,
createRemoteText,
} from '@remote-dom/core';
// Inline HTML
const htmlResource = createUIResource({
uri: 'ui://greeting/1',
content: { type: 'rawHtml', htmlString: '<p>Hello, MCP UI!</p>' },
encoding: 'text',
});
// External URL
const externalUrlResource = createUIResource({
uri: 'ui://greeting/1',
content: { type: 'externalUrl', iframeUrl: 'https://example.com' },
encoding: 'text',
});
// remote-dom
const remoteDomResource = createUIResource({
uri: 'ui://remote-component/action-button',
content: {
type: 'remoteDom',
script: `
const button = document.createElement('ui-button');
button.setAttribute('label', 'Click me for a tool call!');
button.addEventListener('press', () => {
window.parent.postMessage({ type: 'tool', payload: { toolName: 'uiInteraction', params: { action: 'button-click', from: 'remote-dom' } } }, '*');
});
root.appendChild(button);
`,
framework: 'react', // or 'webcomponents'
},
encoding: 'text',
});
Client-side: Render in your MCP host
import React from 'react';
import { UIResourceRenderer } from '@mcp-ui/client';
function App({ mcpResource }) {
if (
mcpResource.type === 'resource' &&
mcpResource.resource.uri?.startsWith('ui://')
) {
return (
<UIResourceRenderer
resource={mcpResource.resource}
onUIAction={(result) => {
console.log('Action:', result);
}}
/>
);
}
return <p>Unsupported resource</p>;
}
Server-side: Build your UI resources
require 'mcp_ui_server'
# Inline HTML
html_resource = McpUiServer.create_ui_resource(
uri: 'ui://greeting/1',
content: { type: :raw_html, htmlString: '<p>Hello, from Ruby!</p>' },
encoding: :text
)
# External URL
external_url_resource = McpUiServer.create_ui_resource(
uri: 'ui://greeting/2',
content: { type: :external_url, iframeUrl: 'https://example.com' },
encoding: :text
)
# remote-dom
remote_dom_resource = McpUiServer.create_ui_resource(
uri: 'ui://remote-component/action-button',
content: {
type: :remote_dom,
script: "
const button = document.createElement('ui-button');
button.setAttribute('label', 'Click me from Ruby!');
button.addEventListener('press', () => {
window.parent.postMessage({ type: 'tool', payload: { toolName: 'uiInteraction', params: { action: 'button-click', from: 'ruby-remote-dom' } } }, '*');
});
root.appendChild(button);
",
framework: :react,
},
encoding: :text
)
For a detailed, simple, step-by-step guide on how to integrate mcp-ui
into your own server, check out the full server walkthroughs on the mcp-ui documentation site:
These guides will show you how to add a mcp-ui
endpoint to an existing server, create tools that return UI resources, and test your setup with the ui-inspector
!
Client Examples
mcp-ui
-enabled servers.mcp-ui
client. Check out the hosted version!examples/remote-dom-demo
) - local demo app to test RemoteDOM resources (intended for hosts)Server Examples
typescript-server-demo
: A simple Typescript server that demonstrates how to generate UI resources.https://remote-mcp-server-authless.idosalomon.workers.dev/mcp
https://remote-mcp-server-authless.idosalomon.workers.dev/sse
mcp_ui_server
and mcp
gems together.Drop those URLs into any MCP-compatible host to see mcp-ui
in action. For a supported local inspector, see the ui-inspector.
Host and user security is one of mcp-ui
's primary concerns. In all content types, the remote code is executed in a sandboxed iframe.
Contributions, ideas, and bug reports are welcome! See the contribution guidelines to get started.
Apache License 2.0 Β© The MCP-UI Authors
This project is provided "as is", without warranty of any kind. The mcp-ui
authors and contributors shall not be held liable for any damages, losses, or issues arising from the use of this software. Use at your own risk.
FAQs
mcp-ui Client SDK
We found that @postman/mcp-ui-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 413 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.