建 awesome-llm-apps 的 MCP Apps 讓 MCP 工具在聊天中渲染為可交互界面)
如何構(gòu)建 awesome-llm-apps 的 MCP Apps 讓 MCP 工具在聊天中渲染為可交互界面【免費(fèi)下載鏈接】awesome-llm-apps100 AI Agents, Agent Skills and RAG Apps - Free and Open Source.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/aw/awesome-llm-apps在 awesome-llm-apps 倉庫的generative_ui_agents/mcp-apps-generative-ui-showcase/子項(xiàng)目中有一個(gè)可運(yùn)行的示例MCP 服務(wù)器注冊search-flights、create-portfolio、create-board等工具每個(gè)工具通過_meta[ui/resourceUri]關(guān)聯(lián)一個(gè) HTML/JS 資源。當(dāng) Agent 調(diào)用這些工具時(shí)前端把關(guān)聯(lián)的 HTML 應(yīng)用掛載到聊天里的沙箱 iframe 中iframe 再通過 JSON-RPCpostMessage回調(diào) MCP 工具——最終效果是多步向?qū)?、拖拽看板、?shí)時(shí)圖表這類完整交互界面直接渲染在聊天里。這個(gè)項(xiàng)目基于 CopilotKit、AG-UI 和 MCP Apps ExtensionSEP-1865。本文的任務(wù)是在本地跑通這個(gè)項(xiàng)目并掌握「給一個(gè) MCP 工具掛上交互 UI」的完整模式讓你能照著 server.ts 的結(jié)構(gòu)給自己的工具加 UI。工作原理工具、UI 資源與前端中間件整個(gè)鏈路在 README 中描述為User: Book a flight from JFK to LAX ↓ AI calls search-flights tool ↓ MCPAppsMiddleware intercepts, fetches HTML resource ↓ CopilotKit renders flights-app.html in iframe ↓ User interacts with wizard UI ↓ UI calls MCP tools via postMessage → server拆開看有三個(gè)關(guān)鍵點(diǎn)都在源碼中有對應(yīng)實(shí)現(xiàn)工具聲明 UI 資源server.registerTool()的描述對象里帶_meta: { ui/resourceUri: ui://flights/flights-app.html }。server.ts 中定義了協(xié)議常量RESOURCE_URI_META_KEY ui/resourceUri。資源聲明 MCP App 類型server.registerResource()注冊對應(yīng) URI 的資源mimeType: text/htmlmcp標(biāo)記它是一個(gè) MCP Apphandler 返回{ contents: [{ text: htmlContent }] }。前端中間件Next.js 的 API 路由 route.ts 中BuiltInAgent通過.use(new MCPAppsMiddleware({ mcpServers: [{ type: http, url: ... }] }))連接 MCP 服務(wù)器攔截工具調(diào)用并抓取 HTML 資源交給 CopilotKit 渲染。MCP 服務(wù)器本身是 Express StreamableHTTPServerTransportPOST/GET/DELETE 都掛在/mcp路徑上另有一個(gè)/health健康檢查端點(diǎn)默認(rèn)端口 3001可通過PORT環(huán)境變量修改。準(zhǔn)備條件Node.js 環(huán)境npm 工作區(qū)含next、tsx、vite等依賴無系統(tǒng)級(jí)依賴要求一個(gè) LLM API Key。根據(jù) route.ts 的determineModel()設(shè)置OPENAI_API_KEY時(shí)使用openai/gpt-5.5設(shè)置ANTHROPIC_API_KEY時(shí)使用anthropic/claude-sonnet-4-6設(shè)置GOOGLE_API_KEY時(shí)使用google/gemini-3.1-pro-preview都沒有則默認(rèn)回落到openai/gpt-5.5。安裝與啟動(dòng)以下命令來自 README 的 Quick Start。README 中稱為 “mcp-apps directory”在本倉庫中對應(yīng)generative_ui_agents/mcp-apps-generative-ui-showcase/。1. 安裝依賴項(xiàng)目根目錄 MCP 服務(wù)器兩個(gè)包c(diǎn)d generative_ui_agents/mcp-apps-generative-ui-showcase npm install cd mcp-server npm install cd ..2. 設(shè)置環(huán)境變量在項(xiàng)目根目錄創(chuàng)建.env.localOPENAI_API_KEYsk-...sk-...替換為你自己的 OpenAI Key也可以改用ANTHROPIC_API_KEY或GOOGLE_API_KEY模型選擇見上節(jié)。3. 構(gòu)建并運(yùn)行 MCP 服務(wù)器終端 1cd mcp-server npm run build npm run dev # Server runs at http://localhost:3001/mcpnpm run build會(huì)執(zhí)行tsc npm run build:app先編譯 TypeScript再用 Vite 依次把flights-app、hotels-app、trading-app、kanban-app四個(gè) HTML 應(yīng)用打包為單文件自包含 HTML輸出到mcp-server/apps/dist/。注意 mcp-server/package.json 中build:app腳本第一步是rm -rf dist即每次構(gòu)建會(huì)刪除并重建apps/dist/目錄。npm run dev則用tsx watch server.ts以開發(fā)模式運(yùn)行服務(wù)器。4. 運(yùn)行前端終端 2回到項(xiàng)目根目錄npm run dev # Frontend at http://localhost:3000結(jié)果驗(yàn)證打開http://localhost:3000在聊天框輸入 README 給出的示例 Prompt例如Book a flight from JFK to LAX on January 20th for 2 passengers對應(yīng)search-flights工具、Create a $10,000 tech-focused portfolio對應(yīng)create-portfolio、Create a kanban board for my software project對應(yīng)create-board。成功后聊天中會(huì)渲染出對應(yīng)的交互界面多步預(yù)訂向?qū)А⑼顿Y組合圖表、拖拽看板而不是純文本結(jié)果。健康檢查MCP 服務(wù)器提供GET http://localhost:3001/health返回形如{ status: ok, server: travel-booking-mcp, sessions: 當(dāng)前會(huì)話數(shù) }的 JSON字段來自 server.ts 的/health端點(diǎn)sessions為實(shí)時(shí)數(shù)值。一個(gè)明確的故障信號(hào)如果 iframe 中顯示占位頁The app UI needs to be built. Run: npm run build:app說明apps/dist/下還沒有構(gòu)建產(chǎn)物——loadHtml()在找不到 HTML 時(shí)會(huì)返回這個(gè)占位頁。此時(shí)回到終端 1 重新執(zhí)行npm run build即可。給自己的 MCP 工具掛上交互 UI跑通示例后按 README 的 Tool Registration Pattern 和 server.ts 的實(shí)際代碼擴(kuò)展一個(gè)帶 UI 的工具需要四處改動(dòng)1. 在mcp-server/server.ts中注冊 UI 資源。參照現(xiàn)有registerResource調(diào)用例如航班的寫法server.registerResource( flights-app-template, // 資源名 ui://flights/flights-app.html, // ui:// 開頭的資源 URI { name: flights-app-template, uri: ui://flights/flights-app.html, title: Airline Booking, description: Interactive flight search and booking wizard with seat selection, mimeType: text/htmlmcp, // Marks as MCP App }, async (): PromiseReadResourceResult ({ contents: [{ uri: ui://flights/flights-app.html, mimeType: text/htmlmcp, text: htmlContent }], }), );其中htmlContent由loadHtml(flights-app)從apps/dist/讀取。2. 注冊工具并通過_meta關(guān)聯(lián) URIserver.registerTool( search-flights, { title: Search Flights, description: Searches for available flights between two airports. Returns an interactive booking wizard UI., inputSchema: { origin: z.string().describe(Origin airport code (e.g., JFK, LAX, LHR)), destination: z.string().describe(Destination airport code), departureDate: z.string().describe(Departure date in YYYY-MM-DD format), passengers: z.number().min(1).max(9).describe(Number of passengers (1-9)), cabinClass: z.enum([economy, business, first]).optional(), }, _meta: { ui/resourceUri: ui://flights/flights-app.html, // 指向上面注冊的資源 URI }, }, async ({ origin, destination, departureDate, passengers, cabinClass }) { // 工具邏輯返回 text structuredContent }, );3. 提供 HTML 應(yīng)用。UI 源文件放在mcp-server/apps/下如 flights-app.html用 Vite vite-plugin-singlefile打包成單文件 HTML。vite.config.ts 通過環(huán)境變量選擇要打包的入口# 在 mcp-server/apps/ 下構(gòu)建單個(gè)應(yīng)用 BUILD_APPflights-app vite build新應(yīng)用需要加入mcp-server/package.json的build:app腳本格式參照現(xiàn)有的四個(gè)BUILD_APP... vite build命令否則npm run build不會(huì)打包它。4. 告知 Agent 新應(yīng)用的存在。route.ts 中BuiltInAgent的prompt字段枚舉了 4 個(gè)應(yīng)用及其參數(shù)、示例 Prompt 和 helper 工具模型靠這段提示詞決定何時(shí)調(diào)用哪個(gè)工具。新增工具后應(yīng)把它的名稱、參數(shù)、示例 Prompt 補(bǔ)進(jìn)這段提示詞否則模型不會(huì)主動(dòng)渲染新 UI。驗(yàn)證方式與主路徑相同重啟 MCP 服務(wù)器npm run dev是 watch 模式改動(dòng)server.ts后會(huì)自動(dòng)重載在http://localhost:3000輸入對應(yīng)示例 Prompt確認(rèn)聊天中出現(xiàn)你的交互界面若出現(xiàn) “needs to be built” 占位頁則先執(zhí)行第 3 步的構(gòu)建。限制與注意事項(xiàng)會(huì)話與業(yè)務(wù)狀態(tài)保存在內(nèi)存中server.ts 用Map存activePortfolios、activeBoardsMCP 傳輸使用InMemoryEventStoreMCP 服務(wù)器重啟后這些狀態(tài)會(huì)丟失。CORS 配置為origin: *且暴露Mcp-Session-Id響應(yīng)頭這是本地開發(fā)/演示的配置。前后端分離部署時(shí)需要把MCP_SERVER_URL環(huán)境變量指向部署后的 MCP 服務(wù)器地址route.ts中未設(shè)置該變量時(shí)默認(rèn)連接http://localhost:3001/mcpREADME Deployment 一節(jié)說明線上演示即為 Web 與 MCP Server 兩個(gè)獨(dú)立服務(wù)。四個(gè)示例應(yīng)用的數(shù)據(jù)15 個(gè)機(jī)場、10 個(gè)城市酒店、18 只股票等均為 mcp-server/src/ 下的內(nèi)置模擬數(shù)據(jù)用于演示交互不是真實(shí)交易或預(yù)訂?!久赓M(fèi)下載鏈接】awesome-llm-apps100 AI Agents, Agent Skills and RAG Apps - Free and Open Source.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/aw/awesome-llm-apps創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考