交互式UI组件SDK

mcp-ui是一个为Model Context Protocol(MCP)提供交互式Web组件的SDK集合,支持在服务器端定义UI片段并在客户端安全渲染,适用于AI交互增强场景。

  • by jkk75
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 katherinek727/mcp-ui

使用说明

📦 模型上下文协议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-server python:在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仅使用第一个有效URL http/s URL,并在发现其他URL时发出警告
  • text vs。 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使用第一个有效URL http/s URL。

远程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

  1. 服务器端:构建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',
    });
    
  2. 客户端:在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
  • 红宝石:白骨 演示服务器 这展示了如何使用 mcp_ui_server 和 mcp 宝石在一起。
  • python:一个简单的 演示服务器 这展示了如何使用 mcp-ui-server Python包。
  • 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 作者和贡献者不对因使用本软件而产生的任何损害、损失或问题承担责任。使用风险自负。