
mcp-apps-builder
熱門**所有 MCP 伺服器工作的必讀指南** - mcp-use 框架的最佳實踐與模式。 **在進行任何 MCP 伺服器工作前,請先閱讀此文件**,包括: - 建立新的 MCP 伺服器 - 修改現有 MCP 伺服器(新增/更新工具、資源、提示、小工具) - 除錯 MCP 伺服器問題或錯誤 - 審查 MCP 伺服器程式碼的品質、安全性或效能 - 回答關於 MCP 開發或 mcp-use 模式的問題 - 對 server.tool()、server.resource()、server.prompt() 或小工具進行任何變更 此技能包含關鍵的架構決策、安全模式與常見陷阱。 在實作 MCP 功能前,請務必先查閱相關的參考檔案。
**所有 MCP 伺服器工作的必讀指南** - mcp-use 框架的最佳實踐與模式。 **在進行任何 MCP 伺服器工作前,請先閱讀此文件**,包括: - 建立新的 MCP 伺服器 - 修改現有 MCP 伺服器(新增/更新工具、資源、提示、小工具) - 除錯 MCP 伺服器問題或錯誤 - 審查 MCP 伺服器程式碼的品質、安全性或效能 - 回答關於 MCP 開發或 mcp-use 模式的問題 - 對 server.tool()、server.resource()、server.prompt() 或小工具進行任何變更 此技能包含關鍵的架構決策、安全模式與常見陷阱。 在實作 MCP 功能前,請務必先查閱相關的參考檔案。
重要:如何使用此技能
此檔案僅提供導覽指南。在實作任何 MCP 伺服器功能前,你必須:
- 閱讀此概覽以了解哪些參考檔案相關
- 務必閱讀你正在實作功能的特定參考檔案
- 將這些檔案中的詳細模式套用至你的實作
請勿僅依賴此檔案中的快速參考範例 - 它們僅為最小範例。參考檔案包含關鍵的最佳實踐、安全考量與進階模式。
MCP 伺服器最佳實踐
使用 mcp-use 建構生產就緒 MCP 伺服器(包含工具、資源、提示與小工具)的全面指南。
⚠️ 首先:新專案還是現有專案?
在執行任何操作之前,請先確認你是否位於現有的 mcp-use 專案中。
檢測方式: 檢查工作區中是否有 package.json 將 "mcp-use" 列為相依套件,或是否有任何 .ts 檔案從 "mcp-use/server" 匯入。
├─ 找到 mcp-use 專案 → 請勿重新建立。你已在專案中。
│ └─ 跳至下方「快速導覽」以新增功能。
│
├─ 無 mcp-use 專案(空目錄、不相關專案或全新專案)
│ └─ 先使用 npx create-mcp-use-app 建立專案,再新增功能。
│ 請參閱下方「建立新專案」。
│
└─ 位於不相關的專案中(例如 Next.js 應用程式)且使用者想要 MCP 伺服器
└─ 詢問使用者要在哪裡建立,然後在該目錄中建立專案。
請勿在現有不相關專案的根目錄中建立。
絕對不要手動建立 MCPServer 樣板、package.json 或專案結構。 CLI 會設定 TypeScript 配置、開發腳本、檢查器整合、熱重載與小工具編譯,這些都很難手動複製。
建立新專案
npx create-mcp-use-app my-server
cd my-server
npm run dev
完整的建立細節與 CLI 旗標,請參閱 quickstart.md。
快速導覽
根據你要建構的內容選擇路徑:
🚀 基礎
時機: 在新對話中開始 MCP 工作時,務必先閱讀這些。後續可參考以釐清架構/概念。
- concepts.md - MCP 基本元件(工具、資源、提示、小工具)及其使用時機
- architecture.md - 伺服器結構(基於 Hono)、中介軟體系統、server.use() 與 server.app
- quickstart.md - 建立專案、設定與第一個工具範例
- deployment.md - 部署至 Manufact Cloud、自架、Docker、管理部署
在深入工具/資源/小工具章節前,請先載入這些檔案。
🔐 加入驗證?
時機: 使用 OAuth(Auth0、Better Auth、Clerk、WorkOS、Supabase、Keycloak 或其他供應商)保護你的伺服器
-
- 時機:首次加入驗證、了解
ctx.auth,或選擇供應商/整合模式 - 涵蓋:遠端驗證與 OAuth 代理、
oauth配置、ctx.auth結構、供應商比較、常見錯誤
- 時機:首次加入驗證、了解
-
- 時機:使用 Auth0 — DCR(搶先體驗)或透過
oauthProxy的標準 Regular Web App - 涵蓋:兩種模式的設定、
extraAuthorizeParams.audience、透過rfc9068_profile_authz的權限
- 時機:使用 Auth0 — DCR(搶先體驗)或透過
-
- 時機:使用 Better Auth 搭配
@better-auth/oauth-provider外掛(自架 OAuth 2.1) - 涵蓋:
oauthBetterAuthProvider、驗證 URL / 元資料路由、登入與同意流程
- 時機:使用 Better Auth 搭配
-
- 時機:使用 Clerk(基於 DCR 的 OAuth)
- 涵蓋:
oauthClerkProvider、啟用 DCR、Frontend API URL、組織上下文
-
- 時機:使用 WorkOS AuthKit(僅 DCR)
- 涵蓋:設定、環境變數、角色/權限、多租戶組織過濾、WorkOS API 呼叫
-
- 時機:使用 Supabase 的 OAuth 2.1 伺服器
- 涵蓋:設定、可發布金鑰、ES256 與 HS256、託管同意 UI、RLS 感知 SDK 呼叫
-
- 時機:透過原生 DCR 使用 Keycloak
- 涵蓋:DCR 信任主機 + 網頁來源、受眾強制執行、領域與資源角色、userinfo
-
- 時機:任何其他供應商 — 可透過
oauthCustomProvider使用 DCR,或透過oauthProxy使用預先註冊的供應商(Google、GitHub、Okta、Azure AD) - 涵蓋:
oauthCustomProvider、oauthProxy+jwksVerifier、供應商範例、不透明權杖驗證
- 時機:任何其他供應商 — 可透過
🔧 建構伺服器後端(無 UI)?
時機: 實作 MCP 功能(動作、資料、範本)。閱讀你正在建構的基本元件的特定檔案。
-
- 時機:建立 AI 可呼叫的後端動作(發送郵件、擷取資料、建立使用者)
- 涵蓋:工具定義、結構描述、註解、上下文、錯誤處理
-
- 時機:公開用戶端可擷取的唯讀資料(配置、使用者設定檔、文件)
- 涵蓋:靜態資源、動態資源、參數化資源範本、URI 補全
-
- 時機:建立可重複使用的訊息範本,供 AI 互動使用(程式碼審查、摘要)
- 涵蓋:提示定義、參數化、引數補全、提示最佳實踐
-
- 時機:格式化工具/資源的回應(文字、JSON、Markdown、圖片、錯誤)
- 涵蓋:
text()、object()、markdown()、image()、error()、mix()
-
- 時機:將多個 MCP 伺服器組合成一個統一的聚合伺服器
- 涵蓋:
server.proxy()、配置 API、明確工作階段、取樣路由
-
- 時機:加入橫切邏輯(記錄、驗證檢查、速率限制、工具過濾),涵蓋多個工具/資源
- 涵蓋:
server.use('mcp:...')中介軟體、MiddlewareContext(方法、參數、驗證、狀態)、模式匹配、HTTP 與 MCP 中介軟體
🎨 建構視覺小工具(互動式 UI)?
時機: 建立基於 React 的視覺介面,用於瀏覽、比較或選取資料
-
- 時機:建立你的第一個小工具,或為現有工具加入 UI
- 涵蓋:小工具設定、
useWidget()鉤子、isPending檢查、props 處理
-
- 時機:管理小工具內的 UI 狀態(選取、篩選、分頁)
- 涵蓋:
useState、setState、狀態持久化、何時使用工具與小工具狀態
-
- 時機:在小工具內加入按鈕、表單或呼叫工具
- 涵蓋:
useCallTool()、表單處理、動作按鈕、樂觀更新
-
- 時機:為小工具設定樣式以支援主題、響應式佈局或無障礙功能
- 涵蓋:
useWidgetTheme()、淺色/深色模式、autoSize、佈局模式、CSS 最佳實踐
-
- 時機:建構具有非同步資料、錯誤邊界或效能最佳化的複雜小工具
- 涵蓋:載入狀態、錯誤處理、記憶化、程式碼分割
-
- 時機:讓 AI 模型了解使用者目前看到的內容(作用中分頁、懸停項目、選取的產品),無需工具呼叫
- 涵蓋:
<ModelContext>元件、modelContext.set/remove命令式 API、巢狀結構、樹狀序列化、生命週期規則
-
- 時機:從小工具上傳或下載檔案(僅限 ChatGPT Apps SDK)
- 涵蓋:
useFiles()鉤子、isSupported防護、模型可見性(modelVisible)、儲存fileId、臨時下載 URL
📚 需要完整範例?
時機: 想要查看常見使用案例的完整實作
- common-patterns.md
- 端到端範例:天氣應用程式、待辦事項清單、食譜瀏覽器
- 展示:伺服器程式碼 + 小工具程式碼 + 上下文中的最佳實踐
🔁 從終端機測試(代理回饋迴圈)
時機: 想要在沒有檢查器 UI 的情況下驗證工具或小工具 — AI 代理在 MCP 伺服器上迭代的標準流程。
-
mcp-use client— 從終端機驅動 MCP 伺服器。在收到 401 時自動執行 OAuth,將已儲存的伺服器以簡短名稱持久化,單次子命令會乾淨退出,因此從 harness 中安全地產生。npx mcp-use client connect dev http://localhost:3000/mcp npx mcp-use client dev tools list npx mcp-use client dev tools call get-weather city=Tokyo --screenshot每個伺服器命令都將儲存的名稱作為第一個位置引數(
mcp-use client <name> <scope> <action>)— 沒有「作用中工作階段」。引數使用key=value(巢狀值使用key:='<json>')或單一 JSON 物件。當工具渲染小工具時,傳遞--screenshot也會儲存 PNG(預設為./<view>-<timestamp>.png,或使用--screenshot-output <path>覆蓋)。 -
mcp-use client screenshot— 將小工具工具無頭渲染為 PNG。當你想要在沒有開啟檢查器的情況下視覺驗證小工具變更時使用,特別是在你呼叫工具、截圖、目視檢查輸出並編輯的迴圈中。兩種形式:# 已儲存伺服器形式 — 重複使用來自 `mcp-use client connect` 的驗證 npx mcp-use client dev screenshot --tool get-weather city=Tokyo \ --width 800 --height 600 --theme light \ --output ./weather.png # 臨時形式 — 內聯連線(對已驗證的伺服器使用 -H 標頭) npx mcp-use client screenshot --mcp http://localhost:3000/mcp \ --tool get-weather city=Tokyo加入
--device-scale-factor 2以獲得 Retina 輸出,或使用--cdp-url <ws>加上--inspector <publicly-reachable-url>從沒有本機 Chrome 安裝的沙盒驅動遠端 Chromium(例如 Notte)。
兩個命令的完整文件位於 docs/typescript/client/cli。
決策樹
你需要什麼?
├─ 從頭開始的新專案
│ └─> quickstart.md(建立 + 設定)
│
├─ OAuth / 使用者驗證
│ └─> authentication/overview.md → 特定供應商指南
│
├─ 簡單的後端動作(無 UI)
│ └─> 使用工具:server/tools.md
│
├─ 用戶端的唯讀資料
│ └─> 使用資源:server/resources.md
│
├─ 可重複使用的提示範本
│ └─> 使用提示:server/prompts.md
│
├─ 橫切邏輯(記錄、驗證檢查、速率限制、工具過濾)
│ └─> 使用中介軟體:architecture.md#mcp-middleware
│
├─ 視覺/互動式 UI
│ └─> 使用小工具:widgets/basics.md
│
├─ 讓模型了解使用者在小工具中看到的內容
│ └─> widgets/model-context.md
├─ 在小工具中上傳/下載檔案
│ └─> widgets/files.md(僅限 ChatGPT Apps SDK)
│
├─ 從終端機驗證工具或小工具(代理回饋迴圈)
│ └─> 參閱上方「從終端機測試」— `mcp-use client` 用於工具執行,
│ `mcp-use client <server> screenshot --tool <tool>` 用於無頭小工具 PNG
│
└─ 部署到生產環境
└─> deployment.md(雲端部署、自架、Docker)
核心原則
- 工具用於動作 - 具有輸入/輸出的後端操作
- 資源用於資料 - 用戶端可擷取的唯讀資料
- 提示用於範本 - 可重複使用的訊息範本
- 小工具用於 UI - 在有用時提供視覺介面
- 先使用模擬資料 - 快速原型,稍後再連接 API
❌ 常見錯誤
避免這些在生產 MCP 伺服器中發現的反模式:
工具定義
- ❌ 回傳原始物件而非使用回應輔助函式
- ✅ 使用
text()、object()、widget()、error()輔助函式
- ✅ 使用
- ❌ 跳過每個欄位的 Zod 結構描述
.describe()- ✅ 為所有結構描述欄位加入描述,以利 AI 理解
- ❌ 無輸入驗證或清理
- ✅ 使用 Zod 驗證輸入,清理使用者提供的資料
- ❌ 擲回錯誤而非回傳
error()輔助函式- ✅ 使用
error("message")進行優雅的錯誤回應
- ✅ 使用
小工具開發
- ❌ 在未檢查
isPending的情況下存取props- ✅ 務必檢查
if (isPending) return <Loading/>
- ✅ 務必檢查
- ❌ 小工具處理伺服器狀態(篩選、選取)
- ✅ 小工具使用
useState管理自己的 UI 狀態
- ✅ 小工具使用
- ❌ 缺少
McpUseProvider包裝或autoSize- ✅ 包裝根元件:
<McpUseProvider autoSize>
- ✅ 包裝根元件:
- ❌ 內聯樣式未考慮主題
- ✅ 使用
useWidgetTheme()支援淺色/深色模式
- ✅ 使用
安全性與生產環境
- ❌ 在程式碼中硬編碼 API 金鑰或機密
- ✅ 使用
process.env.API_KEY,在.env.example中記錄
- ✅ 使用
- ❌ 工具處理程式中無錯誤處理
- ✅ 包裝在 try/catch 中,失敗時回傳
error()
- ✅ 包裝在 try/catch 中,失敗時回傳
- ❌ 昂貴的操作未使用快取
- ✅ 使用 TTL 快取 API 呼叫、計算
- ❌ 缺少 CORS 配置
- ✅ 為生產部署配置 CORS
🔒 黃金法則
有觀點的架構指南:
1. 一個工具 = 一個能力
將廣泛的動作拆分為專注的工具:
- ❌
manage-users(太模糊) - ✅
create-user、delete-user、list-users
2. 一次回傳完整資料
工具呼叫成本高昂。避免延遲載入:
- ❌
list-products+get-product-details(2 次呼叫) - ✅
list-products回傳包含詳細資料的完整資料
3. 小工具擁有自己的狀態
UI 狀態存在於小工具中,而非獨立的工具:
- ❌
select-item工具、set-filter工具 - ✅ 小工具使用
useState或setState管理
4. exposeAsTool 預設為 false
小工具預設僅註冊為資源。使用自訂工具(建議)或設定 exposeAsTool: true 將小工具暴露給模型:
// ✅ 需要所有 4 個步驟以獲得正確的型別推論:
// 步驟 1:分別定義結構描述
const propsSchema = z.object({
title: z.string(),
items: z.array(z.string())
});
// 步驟 2:在元資料中引用結構描述變數
export const widgetMetadata: WidgetMetadata = {
description: "...",
props: propsSchema, // ← 不是內聯 z.object()
exposeAsTool: false
};
// 步驟 3:從結構描述變數推論 Props 型別
type Props = z.infer<typeof propsSchema>;
// 步驟 4:使用帶型別的 Props 搭配 useWidget
export default function MyWidget() {
const { props, isPending } = useWidget<Props>(); // ← 加入 <Props>
// ...
}
⚠️ 常見錯誤: 只做步驟 1-2 但跳過步驟 3-4(失去型別安全)
5. 僅在邊界驗證
- 信任內部程式碼與框架保證
- 驗證使用者輸入、外部 API 回應
- 不要為不可能發生的情境加入錯誤處理
6. 瀏覽/比較時偏好使用小工具
有疑問時,加入小工具。視覺 UI 改善:
- 瀏覽多個項目
- 並排比較資料
- 互動式選取工作流程
快速參考
最小伺服器
import { MCPServer, text } from "mcp-use/server";
import { z } from "zod";
const server = new MCPServer({
name: "my-server",
title: "My Server",
version: "1.0.0"
});
server.tool(
{
name: "greet",
description: "向使用者打招呼",
schema: z.object({ name: z.string().describe("使用者的名稱") })
},
async ({ name }) => text("哈囉 " + name + "!"),
);
server.listen();
回應輔助函式
| 輔助函式 | 使用時機 | 範例 |
|---|---|---|
text() |
簡單字串回應 | text("Success!") |
object() |
結構化資料 | object({ status: "ok" }) |
markdown() |
格式化文字 | markdown("# Title\nContent") |
widget() |
視覺 UI | widget({ props: {...}, output: text(...) }) |
mix() |
多個內容 | mix(text("Hi"), image(url)) |
error() |
錯誤回應 | error("Failed to fetch data") |
resource() |
嵌入資源參考 | resource("docs://guide", "text/markdown") |
伺服器方法:
server.tool()- 定義可執行工具server.resource()- 定義靜態/動態資源server.resourceTemplate()- 定義參數化資源server.prompt()- 定義提示範本server.proxy()- 組合/代理多個 MCP 伺服器server.uiResource()- 定義小工具資源server.listen()- 啟動伺服器server.use('mcp:tools/call', fn)- MCP 中介軟體(工具、資源、提示、列表操作)server.use('mcp:*', fn)- 攔截所有 MCP 中介軟體server.use(fn)- HTTP 中介軟體(Hono)





