使用说明
📦 模型上下文协议UI SDK
What's mcp-ui? • Core Concepts • Installation • Getting Started • Walkthrough • Examples • Supported Hosts • Security • Roadmap • Contributing • License
mcp-ui 将交互式web组件引入 模型上下文协议 (MCP)。直接从MCP服务器交付丰富、动态的UI资源,由客户端呈现。将AI交互提升到一个新的水平!
这个项目是MCP UI想法的实验性社区游乐场。期待快速迭代和增强!
💡 什么 mcp-ui?
mcp-ui 是UI相对于MCP的开放规范的游乐场。它提供了一系列社区SDK,包括:
@mcp-ui/server(TypeScript):生成UI资源的实用程序(UIResource)在您的MCP服务器上。- **
@mcp-ui/client(TypeScript)**UI组件(例如。,<UIResourceRenderer />)以呈现UI资源并处理它们的事件。 mcp_ui_server(红宝石):在Ruby环境中在MCP服务器上生成UI资源的实用程序。mcp-ui-serverpython:在Python环境中在MCP服务器上生成UI资源的实用程序。
它们一起允许您在服务器端定义可重用的UI片段,在客户端无缝安全地呈现它们,并在MCP主机环境中对它们的操作做出反应。
✨ 核心概念
本质上,通过使用 mcp-ui SDK、服务器和主机可以就合同达成一致,使他们能够创建和呈现交互式UI片段(作为MCP中标准化UI方法的途径)。
UI资源
从服务器返回给客户端的主要有效负载是 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:缓存和路由的唯一标识符ui://…--UI资源(由mimeType确定的呈现方法)
mimeType:text/html对于HTML内容(iframe srcDoc),text/uri-list对于URL内容(iframe src),application/vnd.mcp-ui.remote-dom用于远程dom内容(Javascript)- MCP-UI需要一个URL:虽然
text/uri-list格式支持多个URL,MCP-UI仅使用第一个有效URLhttp/sURL,并在发现其他URL时发出警告
- MCP-UI需要一个URL:虽然
textvs。blob:选择text对于简单的字符串;使用blob用于更大或编码的内容。
资源呈现器
UI资源在 <UIResourceRenderer /> 组件。它会自动检测资源类型并呈现相应的组件。
它可以作为React组件和Web组件使用。
React 组件
它接受以下道具:
resource:MCP工具响应中的资源对象。它必须包括uri,mimeType,和内容(text,blob)onUIAction:用于处理来自资源的UI操作的可选回调:当行动包括{ 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 }messageId,iframe会自动接收异步处理的响应消息。supportedContentTypes:可选数组,用于限制允许的内容类型(['rawHtml', 'externalUrl', 'remoteDom'])htmlProps:内部可选道具<HTMLResourceRenderer>style:iframe的可选自定义样式iframeProps:传递给iframe元素的可选道具iframeRenderData:可选Record<string, unknown>在渲染时将数据传递给iframe。这使得父应用程序需要为沙盒iframe内容提供初始状态或配置的高级用例成为可能。autoResizeIframe:可选boolean | { width?: boolean; height?: boolean }自动将iframe调整为内容的大小。
remoteDomProps:内部可选道具<RemoteDOMResourceRenderer>library:远程DOM资源的可选组件库(默认为basicComponentLibrary)remoteElements:远程DOM资源的远程元素定义。
Web组件
Web组件可用作 <ui-resource-renderer>它接受与React组件相同的props,但它们必须作为字符串传递。
例子:
<ui-resource-renderer
resource='{ "mimeType": "text/html", "text": "<h2>Hello from the Web Component!</h2>" }'
></ui-resource-renderer>
这个 onUIAction prop可以通过将事件监听器附加到组件来处理:
const renderer = document.querySelector('ui-resource-renderer');
renderer.addEventListener('onUIAction', (event) => {
console.log('Action:', event.detail);
});
Web组件可在 @mcp-ui/client 包裹在 dist/ui-resource-renderer.wc.js.
支持的资源类型
HTML(text/html 和 text/uri-list)
使用内部渲染 <HTMLResourceRenderer /> 组件,用于显示 <iframe>。这适用于自包含的HTML或嵌入外部应用程序。
mimeType:text/html:呈现内联HTML内容。text/uri-list:呈现外部URL。MCP-UI使用第一个有效URLhttp/sURL。
远程DOM(application/vnd.mcp-ui.remote-dom)
使用内部渲染 <RemoteDOMResourceRenderer /> 组件,它利用Shopify的 remote-dom服务器用描述UI和事件的脚本进行响应。在主机上,脚本安全地呈现在沙盒iframe中,UI更改以JSON形式传达给主机,在那里使用主机的组件库进行呈现。这比iframe更灵活,并允许与主机的外观和感觉相匹配的UI。
mimeType:application/vnd.mcp-ui.remote-dom+javascript; framework={react | webcomponents}
UI操作
UI片段必须能够与代理交互。进入 mcp-ui,这是通过挂接到从UI代码段发送的事件并在主机中对其做出反应来实现的(请参见 onUIAction 道具)。例如,当点击按钮时,HTML可能会通过发送一个事件来触发工具调用,该事件将被客户端捕获和处理。
平台适配器
MCP-UI SDK包括对特定于主机的实现的适配器支持,使您的开放MCP-UI小部件能够无缝工作,而不管主机如何。适配器在MCP-UI之间自动转换 postMessage 协议和主机特定的API。随着时间的推移,随着主机与开放规范兼容,这些适配器将不再需要。
可用适配器
应用SDK适配器
对于应用程序SDK环境(例如ChatGPT),该适配器将MCP-UI协议转换为应用程序SDK API调用(例如。, window.openai).
它是如何工作的:
- 拦截MCP-UI
postMessage来自小部件的调用 - 将它们转换为适当的应用程序SDK API调用
- 处理双向通信(工具、提示、状态管理)
- 透明地工作-您现有的MCP-UI代码无需更改即可继续工作
用途:
import { createUIResource } from '@mcp-ui/server';
const htmlResource = createUIResource({
uri: 'ui://greeting/1',
content: {
type: 'rawHtml',
htmlString: `
<button onclick="window.parent.postMessage({ type: 'tool', payload: { toolName: 'myTool', params: {} } }, '*')">
Call Tool
</button>
`
},
encoding: 'text',
// Enable adapters
adapters: {
appsSdk: {
enabled: true,
config: ...
}
// Future adapters can be enabled here
}
});
适配器脚本会自动注入到HTML内容中,并处理所有协议转换。
支持的操作:
- ✅ 工具调用 -
{ type: 'tool', payload: { toolName, params } } - ✅ 提示词 -
{ type: 'prompt', payload: { prompt } } - ✅ 意图 -
{ type: 'intent', payload: { intent, params } }(转换为提示) - ✅ 通知 -
{ type: 'notify', payload: { message } } - ✅ 渲染数据 -访问
toolInput,toolOutput,widgetState,theme,locale - ⚠️ 链接 -
{ type: 'link', payload: { url } }(可能不受支持,在某些环境中返回错误)
高级用法
您可以手动使用适配器包装HTML或直接访问适配器脚本:
import { wrapHtmlWithAdapters, getAppsSdkAdapterScript } from '@mcp-ui/server';
// Manually wrap HTML with adapters
const wrappedHtml = wrapHtmlWithAdapters(
'<button>Click me</button>',
{
appsSdk: {
enabled: true,
config: { intentHandling: 'ignore' }
}
}
);
// Get a specific adapter script
const appsSdkScript = getAppsSdkAdapterScript({ timeout: 60000 });
🏗️ 安装
TypeScript
# 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
python
# using pip
pip install mcp-ui-server
# or uv
uv add mcp-ui-server
🚀 入门指南
你可以使用 GitMCP 的 让您的IDE访问 mcp-ui的最新文档!
TypeScript
-
服务器端:构建UI资源
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', }); -
客户端:在MCP主机中渲染
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>; }
python
服务器端:构建UI资源
from mcp_ui_server import create_ui_resource
# Inline HTML
html_resource = create_ui_resource({
"uri": "ui://greeting/1",
"content": { "type": "rawHtml", "htmlString": "<p>Hello, from Python!</p>" },
"encoding": "text",
})
# External URL
external_url_resource = create_ui_resource({
"uri": "ui://greeting/2",
"content": { "type": "externalUrl", "iframeUrl": "https://example.com" },
"encoding": "text",
})
红宝石
服务器端:构建UI资源
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
)
🚶 攻略
有关如何集成的详细、简单、分步指南 mcp-ui 进入您自己的服务器,查看 mcp用户界面文档网站:
这些指南将向您展示如何添加 mcp-ui 端点到现有服务器,创建返回UI资源的工具,并使用 ui-inspector!
🌍 示例
客户示例
- 鹅 -支持的开源AI代理
mcp-ui. - Librechat -增强的ChatGPT克隆,支持
mcp-ui. - ui检查员 -检查当地
mcp-ui-启用的服务器。 - MCP-UI聊天 -使用构建的交互式聊天
mcp-ui客户。看看 托管版本! - MCP-UI远程DOM游乐场(
examples/remote-dom-demo)-本地演示应用程序,用于测试RemoteDOM资源 - MCP-UI Web组件演示(
examples/wc-demo)-本地演示应用程序,用于测试主机中的Web组件集成
服务器示例
- TypeScriptA. 全功能服务器 它被部署到托管环境中以便于测试。
typescript-server-demo:一个简单的Typescript服务器,演示如何生成UI资源。- 服务器A. 全功能Typescript服务器 它被部署到托管的Cloudflare环境中,以便于测试。
- HTTP流:
https://remote-mcp-server-authless.idosalomon.workers.dev/mcp - 上海证券交易所:
https://remote-mcp-server-authless.idosalomon.workers.dev/sse
- HTTP流:
- 红宝石:白骨 演示服务器 这展示了如何使用
mcp_ui_server和mcp宝石在一起。 - python:一个简单的 演示服务器 这展示了如何使用
mcp-ui-serverPython包。 - XMCP -带的打字MCP框架
mcp-ui初学者示例。
将这些URL放入任何兼容MCP的主机中查看 mcp-ui 在行动中。有关支持的本地检查员,请参阅 ui检查员.
💻 支持的主机
mcp-ui 由越来越多的MCP兼容客户端支持。功能支持因主机而异:
| 主机 | 渲染 | UI操作 | 注释 |
|---|---|---|---|
| 纳米机器人 | ✅ | ✅ | |
| ChatGPT | ✅ | ⚠️ | 指南 |
| 邮递员 | ✅ | ⚠️ | |
| 鹅 | ✅ | ⚠️ | |
| Librechat | ✅ | ⚠️ | |
| 铁匠铺 | ✅ | ❌ | |
| MCPJam | ✅ | ✅ | |
| 快速代理 | ✅ | ❌ | |
| Visual Studio Code (TBA) | ? | ? |
传说:
- ✅: 支持
- ⚠️: 部分支持
- ❌: 尚不支持
🔒 安全
主机和用户安全是 mcp-ui的主要关注点。在所有内容类型中,远程代码都在沙盒iframe中执行。
🛣️ 路线图
- [X] 添加在线游乐场
- [X] 扩展UI操作API(超出工具调用)
- [X] 支持Web组件
- [X] 支持远程DOM
- []添加组件库(正在进行中)
- []添加其他编程语言的SDK(正在进行中;Ruby、Python可用)
- []支持其他前端框架
- []探索提供UI SDK(除了客户端和服务器端)
- []添加声明性UI内容类型
- []是否支持生成式用户界面?
核心团队
mcp-ui 是一个项目 伊多·所罗门,与 利亚德·约瑟夫.
🤝 贡献
欢迎投稿、想法和bug报告!看 贡献指南 开始吧。
📄 许可证
Apache许可证2.0© MCP-UI作者
免责声明
本项目按“原样”提供,不提供任何形式的保修。这个 mcp-ui 作者和贡献者不对因使用本软件而产生的任何损害、损失或问题承担责任。使用风险自负。
