模型 / 資料集
MCP-UI-Org/mcp-ui avatar
MCP-UI-Org/mcp-ui

mcp-ui:把工具介面塞進 MCP 協定裡的 SDK,以及它留給你的兩個選擇

UI over MCP. Create next-gen UI experiences with the protocol and SDK!

5,159 個 Star396 個 ForkTypeScriptApache-2.0

秒懂

它是什麼?
mcp-ui 用 _meta.ui.resourceUri 把工具和它的 HTML 介面綁在一起,讓 Host 在工具回傳結果時順便抓一份 UI 來渲染。它同時維護 MCP Apps 與舊版 MCP-UI 兩套渲染路徑,選哪一條會決定你的 Host 要不要自己處理資源抓取。
適合誰用?
如果你正在寫 MCP Apps Host,@mcp-ui/client 的 AppRenderer 是 README 明確推薦的路徑,它會依 client 自動抓取資源,你只要處理 sandbox 與 onOpenLink、onMessage 三個接口。若你的 Host 還在舊版 MCP-UI 模式、把 UI 直接塞在工具回應裡,就繼續用 UIResourceRenderer,兩者不是同一條管線,不要混用。
可以商用嗎?
可以。Apache-2.0 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
還在維護嗎?
有在維護。儲存庫最近一次提交在 70 天前。
用什麼語言寫的?
主要是 TypeScript(依據 GitHub 的語言統計)。

以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。

開源專案深度解析

mcp-ui 要解的問題,是工具回傳值沒有地方放介面

MCP 的工具呼叫回傳的是內容陣列,文字、圖片、資源。這些型別適合把資料交出去,不適合把一個可點擊的介面交出去。模型看得到文字,使用者看到的是模型轉述後的文字。如果工具本質上需要使用者操作,例如填一張表、挑一個候選、確認一筆交易,純文字回傳就得多繞一圈。mcp-ui 的作法是把介面本身當成一種資源,掛在工具上。README 的定位很直接:它是實作 MCP Apps 標準的 SDK,並在開頭說明這個專案「pioneered the concept of interactive UI over MCP」,其模式影響了後來的 MCP Apps 規格。讀者該注意的對象因此有兩層。一層是寫 MCP server 的人,他們要讓自己的工具長出 UI。另一層是寫 Host 的人,他們要決定怎麼把收到的 UI 安全地渲染出來。這兩層拿的是不同的套件,@mcp-ui/server 與 @mcp-ui/client,另外 Ruby 的 mcp_ui_server 與 Python 的 mcp-ui-server 只涵蓋 server 端建立資源。

_meta.ui.resourceUri 是整條管線的樞紐

MCP Apps 模式下,工具和它的介面不是靠命名慣例或回傳內容綁定,而是靠工具定義裡的 _meta 欄位。README 的範例寫得很清楚:先呼叫 createUIResource 產生一個 UI 資源,參數包含 uri、content 與 encoding;接著用 registerAppResource 把這個資源註冊成 server 的資源處理器;最後用 registerAppTool 註冊工具,並在 _meta 裡放 { ui: { resourceUri: widgetUI.resource.uri } }。Host 端偵測到這個欄位之後,會透過 resources/read 去抓 UI,再用 AppRenderer 渲染。這代表 UI 的傳遞走的是既有的資源讀取通道,不是新的協定擴充。對 server 作者來說,好處是工具回傳值可以保持乾淨,只放模型要看的內容,介面則由 Host 另外拉取。代價是多一次往返,而且 Host 必須實作這個偵測行為,否則 _meta 只是一個被忽略的欄位,介面永遠不會出現。

UIResource 的線格式:mimeType 與 text/blob 二選一

底層承載 UI 內容的結構是 UIResource,型別為 resource,內含 uri、mimeType,以及 text 或 blob 其中之一。uri 使用 ui:// 這個 scheme,例如 ui://my-server/widget。mimeType 固定為 text/html;profile=mcp-app,README 稱之為 MCP Apps 的標準 MIME type。內容可以是純文字 HTML,也可以是 Base64 編碼的 blob。這個設計把「介面」壓縮成一個資源物件,好處是它跟 MCP 既有的資源模型完全同構,Host 不需要為 UI 另外寫一套解析邏輯。限制也來自同一個地方:目前 README 列出的支援型別只有 HTML 一種,透過內部的 HTMLResourceRenderer 放進 iframe。也就是說,你得到的是沙箱化的網頁,不是原生元件,任何需要存取宿主環境狀態的介面都得靠事件通道繞出去。

AppRenderer 與 UIResourceRenderer 是兩代不同的渲染路徑

client 端有兩個元件,README 把它們分得很清楚。AppRenderer 對應 MCP Apps,props 包含 client、toolName、sandbox、toolInput、toolResult,以及 onOpenLink 與 onMessage 兩個處理器。其中 client 是 optional,但說明寫著「Optional MCP client for automatic resource fetching」,意思是你給了 client,抓取資源這件事就由元件代勞;不給,就得自己把資源準備好。UIResourceRenderer 對應舊版 MCP-UI,吃的是 resource 物件本身,搭配 onUIAction 回呼處理 tool、prompt、link、notify 與 intent 這幾類動作。它另外提供 Web Component 形式,用法是 <ui-resource-renderer resource='...'>。兩者的差異不只是 API 命名。舊路徑假設 UI 已經隨工具回應一起送達,新路徑假設 UI 是 Host 主動去讀的獨立資源。如果你的 Host 還在舊模式,改用 AppRenderer 不會自動生效,因為沒有東西會去觸發 resources/read。

安裝與最小可跑設定

server 端安裝 @mcp-ui/server,client 端安裝 @mcp-ui/client,兩者都是 npm 上的套件。server 端還需要 @modelcontextprotocol/ext-apps/server 提供的 registerAppTool 與 registerAppResource。最小流程是三步:createUIResource 建資源,registerAppResource 掛上處理器,registerAppTool 帶 _meta 註冊工具。createUIResource 的參數在 README 範例中是 uri、content(內含 type: 'rawHtml' 與 htmlString)以及 encoding: 'text'。client 端則是把 AppRenderer 放進你的元件樹,傳入 toolName、toolInput、toolResult,以及 sandbox 設定。sandbox 的形狀是 { url: sandboxUrl },README 只給了這個欄位名稱,沒有說明這個 proxy URL 由誰架設、要代理什麼。這是整份文件最需要你自己補的一塊,也是採用前該先問清楚的問題。

沙箱與安全:文件把責任交回給 Host

README 有專門的 Security 段落,但從可取得的內容看不出它列出哪些具體威脅模型。可以確認的是渲染走 iframe,sandbox 設定以 url 形式傳入,UI 與宿主之間的互動靠事件,由 onUIAction 或 onMessage 接收。這個架構的含意在於:iframe 裡跑的是伺服器提供的 HTML,它想開連結要透過 onOpenLink,想傳訊息要透過 onMessage,Host 是唯一的出口。因此安全邊界不在 SDK 裡,而在你的 Host 怎麼實作這幾個回呼。onOpenLink 直接 window.open(url) 是範例寫法,不是建議政策。你如果照抄,等於把任意 URL 的開啟權交給遠端 HTML。這不是 SDK 的缺陷,是它刻意留下的決策點,但文件在這方面給的指引偏薄,實作前得自己定規則。

平台轉接層與版本節奏透露的維護成本

README 提到 SDK 內含 platform adapters,用來在 host-specific 實作之間轉譯,讓同一份 MCP-UI widget 在不同 Host 上運作。這段在提供的內容中被截斷,所以轉接層實際涵蓋哪些 Host、轉譯哪些欄位,無法從現有材料確認。版本節奏倒是可查:client 套件在 2026 年 5 月 9 日發布 v7.1.1,5 月 1 日發布 v7.1.0,3 月 12 日發布 v7.0.0。三個月內一次主版本跳躍加上兩次次版本,對照倉庫最後推送時間為 2026 年 7 月 8 日,可以看出 client 端仍在頻繁調整。這對採用者的實際意義是:把 @mcp-ui/client 的版本鎖在 package.json 裡,並且預期每次主版更新都要重讀 client 的 release notes,因為渲染路徑與 props 形狀正是這個套件變動最頻繁的部分。server 端相對穩定,因為 createUIResource 的輸出格式由 MCP Apps 標準定義。

什麼時候不該用 mcp-ui

如果你的工具只需要回傳文字或圖片,讓模型轉述就夠了,加一層 UI 資源只是多一次往返與一個 iframe。如果你的 Host 完全由你控制、且你已經有一套前端渲染流程,直接照 MCP Apps 規格處理 _meta.ui.resourceUri 與 resources/read 也可以,mcp-ui 的價值在於把 createUIResource 的組裝與 AppRenderer 的抓取邏輯包好,不在於它壟斷了這個協定。另一個要考慮的替代是 @modelcontextprotocol/ext-apps 本身:mcp-ui 的 server 端範例就是從那裡匯入 registerAppTool 與 registerAppResource,README 也說明 @mcp-ui/client 是 MCP Apps Host 的推薦 SDK。差別在於 ext-apps 提供的是協定層的註冊原語,mcp-ui 提供的是產生資源與渲染資源的具體實作。你要自己寫 iframe 生命週期、訊息驗證與沙箱配置,就選前者;要現成的 React 元件與 Web Component,就選後者。這個選擇的關鍵不是功能多寡,而是你願不願意接手 sandbox 的維運。

編輯結論

如果你正在寫 MCP Apps Host,@mcp-ui/client 的 AppRenderer 是 README 明確推薦的路徑,它會依 client 自動抓取資源,你只要處理 sandbox 與 onOpenLink、onMessage 三個接口。若你的 Host 還在舊版 MCP-UI 模式、把 UI 直接塞在工具回應裡,就繼續用 UIResourceRenderer,兩者不是同一條管線,不要混用。反過來說,如果你只需要在聊天視窗裡顯示一段靜態 HTML、不需要工具回呼,引入整套 SDK 並不划算。動手前先確認兩件事:你的 Host 會不會偵測 _meta.ui.resourceUri 並主動發出 resources/read,以及 sandbox 的 proxy URL 由誰提供、允許哪些來源。這兩點 README 都只給了介面,沒有給部署答案。

官方來源

  1. License: Apache-2.0
  2. MCP-UI-Org/mcp-ui on GitHub
  3. Project website
  4. README
  5. Releases
社群筆記

社群筆記