🚀 Remix 3 MCP 演示項目
本項目展示瞭如何構建交互式的 MCP(模型上下文協議)小部件,這些小部件可在 Cloudflare Workers 上運行,並能嵌入到像 ChatGPT 這樣的 AI 聊天界面中。它展示了將 MCP 與現代 Web 技術相結合的強大能力,能在 AI 對話中創造豐富、有狀態的交互體驗。
🎥 演示視頻
觀看計算器小部件在 ChatGPT 中的實際運行效果,其中還包含隱藏的《創:戰紀》彩蛋:
https://github.com/user-attachments/assets/5df110d8-f40b-4c6a-8820-c2dbf3ff79c8
在 X/Twitter 上觀看演示
🔍 演示原理
架構概述
本演示實現了一個計算器小部件,作為可由 AI 助手調用的 MCP 工具。該架構包含以下幾個關鍵組件:
- MCP 服務器:一個實現了模型上下文協議的 Cloudflare 持久對象。
- 小部件系統:使用 Remix 3 構建的交互式 UI 組件,可嵌入到 AI 聊天中。
- 雙向通信:小部件既能從 AI 接收初始狀態,也能向 AI 發送消息。
- 靜態資源:從 Cloudflare 的 CDN 提供的小部件捆綁包。
計算器小部件
這是一個功能完備、設計精美的計算器,其復古未來主義的美學風格靈感源自《創:戰紀》。以下是它的獨特之處:
初始狀態配置
當 AI 助手調用計算器工具時,它可以傳遞初始狀態參數:
display:初始顯示值
previousValue:已輸入的值(例如,“我想給一個數加 5”)
operation:待執行的操作(+、-、*、/)
waitingForNewValue:計算器是否準備好接收新輸入
errorState:是否以錯誤狀態啟動
這意味著 AI 可以根據用戶的請求預先配置計算器。例如,如果用戶說“我想給某個數加 5”,AI 可以使用 previousValue: 5、operation: '+' 和 waitingForNewValue: true 來調用計算器。
交互式 UI
計算器小部件是一個完全交互式的 Remix 應用程序,具備以下特點:
- 使用 JSX/TSX 和 CSS-in-JS 樣式進行渲染。
- 支持鍵盤快捷鍵(Enter、Escape、數字鍵、運算符等)。
- 具有《創:戰紀》風格的初始化序列和動畫加載消息。
- 用戶交互時即時更新。
- 使用 Remix 3 的實驗性 DOM 渲染器進行高效更新。
彩蛋:主控程序
計算器中有一個隱藏功能:當計算結果等於 1982(即原版《創:戰紀》電影上映的年份)時,計算器會向 AI 助手發送一條 MCP 提示消息,指示它採用《創:戰紀》中的主控程序(MCP)角色。
這展示了小部件通過向 AI 發送消息動態影響對話的能力。
技術實現
使用持久對象的 MCP 服務器
MathMCP 類繼承自 McpAgent,並使用 Cloudflare 的持久對象來維護狀態:
export class MathMCP extends McpAgent<Env, State, Props> {
server = new McpServer(
{
name: 'MathMCP',
version: '1.0.0',
},
{
instructions: `Use this server to solve math problems reliably and accurately.`,
},
)
async init() {
await registerTools(this)
await registerWidgets(this)
}
}
服務器註冊了兩種類型的功能:
- 工具:一個在服務器端執行算術運算的
do_math 工具。
- 小部件:可嵌入聊天中的交互式 UI 資源。
小部件註冊
小部件既作為 MCP 資源(用於 HTML/JS 捆綁包)又作為 MCP 工具(用於調用)進行註冊。註冊內容包括:
- 輸入模式:Zod 模式,定義小部件接受的參數。
- 輸出模式:Zod 模式,定義小部件可以返回的內容。
- HTML 捆綁包:包含腳本引用的渲染後的 HTML。
- OpenAI 元數據:特殊元數據,告知 ChatGPT 如何顯示小部件。
agent.server.registerResource(name, uri, {}, async () => ({
contents: [
createUIResource({
content: {
type: 'rawHtml',
htmlString: await widget.getHtml(),
},
metadata: {
'openai/widgetDescription': widget.description,
'openai/widgetCSP': {
connect_domains: [],
resource_domains: [baseUrl],
},
},
}).resource,
],
}))
獨立構建過程
該項目使用兩個獨立的構建過程:
- 小部件構建(Vite):將計算器 UI 構建為獨立的 JavaScript 捆綁包。
- 輸入:
worker/widgets/calculator/index.tsx
- 輸出:
dist/public/widgets/calculator.js
- 格式:包含所有依賴項的 ES 模塊
- Worker 構建(Wrangler):構建帶有 MCP 服務器的 Cloudflare Worker。
- 輸入:
worker/index.tsx
- 輸出:部署到 Cloudflare 的 Worker 捆綁包
- 包含:MCP 協議處理程序、工具註冊、小部件服務
通信協議
小部件使用 postMessage 與父框架(AI 聊天界面)進行通信:
- 初始化:小部件掛載時發送
ui-lifecycle-iframe-ready。
- 渲染數據:小部件接收包含初始狀態的
ui-lifecycle-iframe-render-data。
- 工具調用:小部件可以通過發送
tool 消息調用其他 MCP 工具。
- 提示:小部件可以使用
prompt 消息向 AI 發送新提示。
- 鏈接:小部件可以使用
link 消息打開鏈接。
sendMcpMessage('prompt', { prompt: MCP_PROMPT })
const renderData = await waitForRenderData(renderDataSchema)
用戶體驗
當用戶在 ChatGPT 中與這個 MCP 服務器交互時,會發生以下情況:
- 用戶詢問:“我能使用計算器嗎?”
- ChatGPT 通過 MCP 調用
calculator 工具。
- 服務器響應:
- 文本內容:“計算器已渲染”
- UI 資源:包含初始狀態的計算器 HTML
- 結構化內容:當前計算器狀態
- ChatGPT 在 iframe 中渲染計算器小部件。
- 小部件加載,顯示《創:戰紀》風格的初始化序列,然後顯示計算器。
- 用戶與計算器交互(點擊按鈕或使用鍵盤)。
- 如果計算結果為 1982,小部件向 ChatGPT 發送提示。
- ChatGPT 採用 MCP 角色並相應回覆。
🏃♂️ 本地運行
前提條件
- Node.js(v18 或更高版本)
- npm 或 yarn
- 一個 Cloudflare 賬戶(用於部署)
本地開發
- 克隆項目並安裝依賴
npm install
- 啟動開發服務器
npm run dev
這將同時運行兩個進程:
- 小部件構建的監聽模式(Vite)
- 帶有本地持久對象的 Worker(Wrangler)
- 測試計算器小部件
訪問
http://localhost:8787/__dev/widgets 以單獨查看計算器小部件。
- 連接到 MCP 檢查器
使用 MCP 檢查器測試 MCP 服務器:
npm run inspect
然後在檢查器中連接到 http://localhost:8787/mcp。
部署
- 生產環境構建
npm run build
- 部署到 Cloudflare
npm run deploy
- 在 ChatGPT 中使用
部署完成後,你可以通過提供部署 URL +
/mcp 端點將此 MCP 服務器添加到 ChatGPT 中。
項目結構
├── worker/
│ ├── index.tsx # 主 Worker 入口點
│ ├── tools.ts # MCP 工具定義 (do_math)
│ ├── widgets.tsx # 小部件註冊系統
│ ├── utils.ts # CORS 和實用函數
│ └── widgets/
│ ├── utils.ts # 小部件通信實用工具
│ └── calculator/
│ ├── index.tsx # 計算器 UI 組件
│ ├── calculator.ts # 計算器業務邏輯
│ └── mcp-prompt.ts # MCP 彩蛋提示
├── dist/
│ └── public/
│ └── widgets/
│ └── calculator.js # 構建後的計算器捆綁包
├── vite.config.widgets.ts # 小部件構建的 Vite 配置
└── wrangler.jsonc # Cloudflare Workers 配置
關鍵技術
環境與配置
wrangler.jsonc 配置了以下內容:
- 持久對象綁定 (
MATH_MCP_OBJECT)
- 用於提供小部件捆綁包的資產綁定
- MCP SDK 的 Node.js 兼容性
- 生產環境監控的可觀測性
開發提示
- 小部件開發:小部件代碼的更改將自動熱重載。
- Worker 更改:Wrangler 會在文件更改時重啟 Worker。
- 類型安全:運行
npm run typecheck 驗證 TypeScript。
- 代碼檢查:運行
npm run lint 檢查代碼風格。
🙏 致謝
本演示展示了前沿的 Web 技術,包括實驗性的 Remix 3 功能、MCP 小部件和 Cloudflare 的邊緣計算平臺。計算器的設計向《創:戰紀》的美學風格致敬,具有獨特的橙色光芒和復古未來主義風格。