什麼是 MCP:從 Function Calling 到業界標準,以及它解決的核心痛點
給 AI 接「手腳」的訴求從 2023 年起爆發,但整合方式經歷了三代演進——每一代都在解決上一代留下的碎片問題。
Function Calling 時代(2023):OpenAI 率先在 API 層引入 tools 參數,模型輸出結構化 JSON 呼叫外部函式。問題是格式綁定 OpenAI,換 Claude 或 Gemini 需重寫適配層。
Plugins 時代(2023 中):ChatGPT Plugins 用 OpenAPI 描述 REST 端點,使用者透過 Plugin Store 安裝。問題是僅限 ChatGPT 生態,且每個 Plugin 需單獨審核上架。
MCP 時代(2024 至今):Anthropic 於 2024 年 11 月開源 Model Context Protocol,定義 Client/Server 雙向 JSON-RPC 通訊標準。一次編寫,Claude Desktop、Cursor、VS Code、Gemini CLI 均可接入——AI 工具整合領域的 USB-C。
Anthropic 設計 rationale:將「工具發現」「參數校驗」「有狀態會話」從各 LLM 廠商私有格式中抽離,Server 只關心暴露什麼能力,Client 只關心如何路由給模型——解耦 LLM 與工具層。
三大能力原語:Tools(模型可呼叫的函式)、Resources(模型可讀取的上下文資料)、Prompts(預置多輪對話範本)——三者構成 MCP Server 的完整暴露面。
Client/Server 架構:Host(如 Cursor)內嵌 MCP Client,與每個 MCP Server 維護獨立 1:1 會話。Server 封裝資料庫、檔案系統、HTTP API 等外部系統,透過 tools/list、resources/list、prompts/list 讓 AI 在執行時動態發現能力——無需硬編碼工具清單。
| 傳輸方式 | 通訊模型 | 典型場景 |
|---|---|---|
| stdio | stdin/stdout 管道,JSON-RPC 2.0 幀 | Claude Desktop、Cursor 本機子程序 |
| HTTP + SSE | HTTP POST 發請求,SSE 串流收回應 | 遠端雲端 Server、多客戶端共享 |
| Streamable HTTP | 單一 HTTP 端點雙向串流(2025 規範更新) | 簡化部署、相容 Serverless |
生命週期:Client 發起 initialize 握手 → Server 回傳能力清單 → Client 發 initialized 通知 → 進入正常工作流(tools/call、resources/read 等)→ 會話結束或 Client 斷開。全程基於 JSON-RPC 2.0,請求/回應一一對應,通知無需回應。
| 維度 | MCP | OpenAI FC | LangChain Tools |
|---|---|---|---|
| 標準化程度 | 開放規範,跨廠商 | OpenAI 私有格式 | 框架內部抽象,無統一 wire 協定 |
| 工具發現 | 執行時 tools/list 動態取得 | 編譯時寫入 system prompt | 程式碼註冊,需重啟 |
| 資源讀取 | 原生 Resources 原語 | 無,需自訂 Retrieval | Retrieval 鏈,非標準 |
| 提示詞範本 | 原生 Prompts 原語 | 無 | PromptTemplate,框架綁定 |
| 傳輸層 | stdio / HTTP+SSE / Streamable HTTP | HTTPS API 內嵌 | 程序內呼叫 |
| 換 LLM 成本 | Server 零改動 | 重寫 tools 格式 | 重寫 Tool 包裝層 |
MCP 不是取代 Function Calling,而是把 FC 從「各家 LLM 私有方言」升級為「AI 工具整合的 HTTP」——Server 寫一次,Client 到處接。
環境準備與 Hello World:Python FastMCP 從零到 Inspector 驗證
2026 年 MCP 官方 SDK 已覆蓋 Python 與 TypeScript 兩大生態。本文以 Python FastMCP 為主(程式碼更短),TypeScript 對照見文末說明。
| 語言 | SDK 套件 | 特點 |
|---|---|---|
| Python | mcp(含 FastMCP) | 裝飾器註冊工具,Pydantic 自動校驗,async 原生 |
| TypeScript | @modelcontextprotocol/sdk | 與 Node/IDE 外掛同棧,型別安全 |
建立虛擬環境:python3 -m venv .venv && source .venv/bin/activate(Windows 用 .venv\Scripts\activate)。Python 建議 3.10+。
安裝相依套件:pip install "mcp[cli]"——含 FastMCP 框架與 MCP Inspector 啟動器。
專案結構:
my-mcp-server/
├── pyproject.toml
├── server.py
├── tools/
│ ├── __init__.py
│ └── calculator.py
└── tests/
└── test_tools.py
FastMCP Hello World:最小可執行 Server,暴露一個 greet 工具。
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-mcp")
@mcp.tool()
def greet(name: str) -> str:
return f"Hello, {name}! MCP Server is running."
if __name__ == "__main__":
mcp.run()
MCP Inspector 除錯:終端機執行 npx @modelcontextprotocol/inspector python server.py,瀏覽器開啟 Inspector UI,可手動呼叫 tools/list 與 tools/call,無需接 Claude。
Claude Desktop 設定:編輯 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"hello-mcp": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}
Cursor 設定:Settings → MCP → 加入上述 JSON 片段(Cursor 與 Claude Desktop 共用 mcpServers 格式)。重啟 IDE 後在 Agent 模式輸入「用 greet 工具向 KVMNODE 問好」驗證。
提示:路徑必須用絕對路徑;虛擬環境的 python 也需寫全路徑(如 /path/.venv/bin/python),否則 Claude Desktop 找不到相依套件。
Tools、Resources 與 Prompts:五類實戰工具與知識庫原語
MCP Server 的價值在於暴露真實業務能力。下面從工具結構出發,實作五類常見工具,再擴展到 Resources 與 Prompts。
Tool 結構:每個工具包含 name、description(供 LLM 理解何時呼叫)、inputSchema(JSON Schema 描述參數)。FastMCP 用 Python 型別註解 + Pydantic 自動產生 Schema——參數型別錯誤在 Server 端即被攔截,不會浪費 Token。
from pydantic import Field
import httpx
import sqlite3
from datetime import datetime, timezone
@mcp.tool()
def calculator(expression: str) -> str:
allowed = set("0123456789+-*/(). ")
if not all(c in allowed for c in expression):
raise ValueError("Invalid characters in expression")
return str(eval(expression))
@mcp.tool()
def read_file(path: str) -> str:
with open(path, "r", encoding="utf-8") as f:
return f.read()
@mcp.tool()
def write_file(path: str, content: str) -> str:
with open(path, "w", encoding="utf-8") as f:
f.write(content)
return f"Written {len(content)} chars to {path}"
@mcp.tool()
async def fetch_url(url: str) -> str:
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.get(url)
resp.raise_for_status()
return resp.text[:8000]
@mcp.tool()
def query_db(sql: str, db_path: str = "data.db") -> str:
if not sql.strip().upper().startswith("SELECT"):
raise ValueError("Only SELECT queries allowed")
conn = sqlite3.connect(db_path)
rows = conn.execute(sql).fetchall()
conn.close()
return str(rows)
@mcp.tool()
def current_time(tz: str = "UTC") -> str:
return datetime.now(timezone.utc).isoformat()
| 工具 | 類型 | 關鍵設計點 |
|---|---|---|
| calculator | 同步 | 白名單字元校驗,防注入 |
| read_file / write_file | 同步 I/O | 路徑沙箱建議限制在 workspace 目錄 |
| fetch_url | async + httpx | 逾時 30s,截斷 8000 字元防 Token 爆炸 |
| query_db | 同步 | 僅允許 SELECT,防刪庫 |
| current_time | 同步 | 解決 LLM 訓練資料截止問題 |
錯誤處理:工具內 raise ValueError(...) 或 raise httpx.HTTPStatusError,FastMCP 自動包裝為 JSON-RPC error 回傳 Client——LLM 收到錯誤描述後可修正參數重試。生產環境建議統一錯誤碼對應,避免洩露內部路徑。
Resources(資源):與 Tools 不同,Resources 是唯讀上下文,AI 透過 resources/read 拉取內容注入對話。分靜態與動態兩類:
| 類型 | URI 範例 | 說明 |
|---|---|---|
| 靜態 | file:///docs/api-guide.md | 啟動時註冊,內容不變 |
| 動態 | metrics://cpu/current | 每次 read 即時產生 |
| 範本 URI | db://tables/{name}/schema | 參數化,Client 填佔位符 |
@mcp.resource("config://app/settings")
def app_settings() -> str:
return open("settings.json").read()
@mcp.resource("logs://recent/{lines}")
def recent_logs(lines: str) -> str:
n = min(int(lines), 500)
with open("/var/log/app.log") as f:
return "".join(f.readlines()[-n:])
社群 @modelcontextprotocol/server-filesystem 是 Resources 最佳實踐——按目錄樹暴露檔案,Client 先 resources/list 瀏覽再 resources/read 按需載入,比一次性塞全文進 prompt 省 Token。
Prompts(提示詞範本):預置多輪 PromptMessage 序列,Client 透過 prompts/get 取得後直接注入對話——適合標準化工作流(程式碼審查、SQL 產生、Incident 報告)。
from mcp.types import PromptMessage, TextContent
@mcp.prompt()
def code_review(language: str, focus: str = "security") -> list[PromptMessage]:
return [
PromptMessage(role="user", content=TextContent(
type="text",
text=f"Review this {language} code focusing on {focus}. "
f"Use read_file tool to load the target, then list issues by severity."
)),
PromptMessage(role="assistant", content=TextContent(
type="text",
text=f"I'll review the {language} code with emphasis on {focus}. "
f"Please provide the file path."
)),
]
HTTP 傳輸、鑑權、除錯與單元測試
本機 stdio 驗證通過後,上線需切換到 HTTP 傳輸以支援遠端 Client、多實例與鑑權。
| 維度 | stdio | HTTP + SSE | Streamable HTTP |
|---|---|---|---|
| 部署複雜度 | 零設定 | 需 Web 伺服器 + SSE 端點 | 單端點,更簡單 |
| 網路可達 | 僅本機子程序 | 跨網路 | 跨網路 |
| 鑑權 | 程序隔離即安全邊界 | Bearer Token / API Key | 同左 |
| 水平擴展 | 不支援 | 支援負載平衡 | 支援 |
| 適用階段 | 開發除錯 | 生產(傳統) | 生產(2025+ 推薦) |
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-server", host="0.0.0.0", port=8080)
if __name__ == "__main__":
mcp.run(transport="streamable-http")
鑑權與安全:生產 HTTP Server 必須加防護層——
Bearer Token:Client 請求標頭 Authorization: Bearer <token>,Server middleware 校驗 JWT 或靜態 Token。
API Key:Header X-API-Key 或 query param,適合服務間呼叫。
CORS:若 Browser-based Client 直連,設定 Access-Control-Allow-Origin 白名單。
Rate Limit:nginx 或 middleware 限制每 IP/Token 每分鐘請求數,防 LLM 迴圈呼叫打爆後端。
MCP Inspector 除錯技巧:① 先用 Inspector 單獨測 Server,確認 tools/list 回傳預期;② 檢查 inputSchema 是否與函式簽名一致;③ 用 Inspector 的 Notifications 面板觀察 Server 主動推送;④ 對照 Claude Desktop 日誌(~/Library/Logs/Claude/)定位連線失敗。
import pytest
from server import calculator
def test_calculator_basic():
assert calculator("2 + 3") == "5"
def test_calculator_rejects_injection():
with pytest.raises(ValueError):
calculator("__import__('os').system('rm -rf /')")
def test_calculator_division():
assert calculator("10 / 4") == "2.5"
| 常見錯誤 | 原因 | 解決方案 |
|---|---|---|
| Server 啟動後立即退出 | 未呼叫 mcp.run() 或 import 報錯 | 終端機直接 python server.py 看 stderr |
| Claude Desktop 看不到工具 | config.json 路徑錯誤或 JSON 語法錯 | 校驗絕對路徑;重啟 Claude |
| tools/call 回傳 schema 錯誤 | 參數型別與註解不符 | Inspector 查看 inputSchema vs 實際傳參 |
| HTTP 502 / 連線逾時 | 連接埠未暴露或防火牆攔截 | curl localhost:8080/mcp 先測連通 |
| Permission denied 讀檔案 | 程序使用者無權限 | 調整檔案權限或限制 sandbox 目錄 |
| Token 超限 | 工具回傳過大 payload | 截斷輸出(如 fetch_url 限 8000 字元) |
生產部署、個人知識庫 MCP 與 2026 生態展望
從 Hello World 到生產級 Server,差距在可靠性、觀測性與安全邊界。下面給出 Docker 化部署、監控方案、知識庫實戰專案與生態推薦。
| 部署平台 | 適合場景 | 注意事項 |
|---|---|---|
| Docker + VPS | 完全掌控、內網存取 | 自行管理 TLS 與備份 |
| Railway / Render | 快速上線、按量計費 | 冷啟動延遲、無持久卷 |
| AWS ECS / GCP Cloud Run | 企業級 SLA | 設定複雜,適合已有雲帳號團隊 |
| KVMNODE 雲 Mac | Apple 生態工具 + MCP 同池 | 獨佔節點、7×24、快照回滾 |
監控四件套:結構化日誌(JSON Lines + 請求 ID)、Prometheus metrics(tools_call_total、tools_call_duration_seconds)、Sentry 例外追蹤、/health 端點供負載平衡探活。
版本管理:Server 版本號寫入 initialize 回應的 serverInfo.version;Breaking change 時遞增 major,Client 可據此決定是否相容。Git tag 與 Docker image tag 對齊。
實戰專案:個人知識庫 MCP——將本機 Markdown/程式碼庫向量化,暴露 search、index、write 三個工具,讓 Cursor Agent 直接檢索你的私有文件。
import chromadb
from watchfiles import awatch
from sentence_transformers import SentenceTransformer
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.get_or_create_collection("knowledge")
embedder = SentenceTransformer("all-MiniLM-L6-v2")
@mcp.tool()
def search_knowledge(query: str, top_k: int = 5) -> str:
embedding = embedder.encode(query).tolist()
results = collection.query(query_embeddings=[embedding], n_results=top_k)
return str(results["documents"])
@mcp.tool()
def index_document(path: str) -> str:
content = open(path).read()
doc_id = path.replace("/", "_")
collection.upsert(
ids=[doc_id],
documents=[content],
embeddings=[embedder.encode(content).tolist()],
)
return f"Indexed {path} ({len(content)} chars)"
async def watch_and_reindex(directory: str):
async for changes in awatch(directory):
for change in changes:
if change[1].endswith((".md", ".py", ".ts")):
index_document(change[1])
向量庫可選 ChromaDB(嵌入式、零維運)或 Qdrant(分散式、高效能)。watchfiles 監聽目錄變更自動 re-index——Agent 寫入新文件後立即可搜。
2026 推薦 MCP Server 清單:
| Server | 能力 | 場景 |
|---|---|---|
| @modelcontextprotocol/server-filesystem | 檔案讀寫 | 本機程式碼庫操作 |
| @modelcontextprotocol/server-github | PR/Issue/Repo | DevOps 自動化 |
| @modelcontextprotocol/server-brave-search | Web 搜尋 | 即時資訊檢索 |
| @modelcontextprotocol/server-postgres | SQL 查詢 | 資料分析 Agent |
| @modelcontextprotocol/server-slack | 訊息發送 | 團隊通知 Bot |
2026 趨勢:MCP Marketplace(Anthropic 與社群目錄已收錄 10,000+ Server)、企業 SSO + RBAC 鑑權層、Streamable HTTP 成為預設遠端傳輸、Multi-server orchestration(一個 Agent 同時連 GitHub + Postgres + 自研 Server)。
容器化打包:編寫 Dockerfile,pip install 相依套件,CMD ["python", "server.py"],本機 docker build && docker run -p 8080:8080 驗證。
切換 Streamable HTTP:mcp.run(transport="streamable-http"),設定 host="0.0.0.0" 監聽所有介面。
加鑑權中介層:部署前接入 Bearer Token 校驗與 Rate Limit,拒絕未授權 tools/call。
部署到目標平台:Railway/Render 一鍵 Docker 部署;企業內網上 VPS 或 KVMNODE 雲 Mac,設定 TLS 反向代理(Caddy/nginx)。
接入監控:掛載 Prometheus exporter、Sentry DSN、結構化日誌輸出;設定 /health 探活。
Client 設定與灰度:Claude Desktop / Cursor MCP 設定改為 HTTP URL;先小流量驗證 tools/list 與核心工具,再全量切換。操作細節見 說明中心。
MCP 生態規模(2026 年 6 月):社群目錄已收錄 10,000+ MCP Server,覆蓋檔案、資料庫、搜尋、DevOps 等 200+ 類別(來源:modelcontextprotocol.io / PulseMCP 2026-06)。
四大廠商全面入局:Anthropic 開源規範、OpenAI 2025 年 3 月宣布 Agents SDK 原生支援 MCP、Google Gemini CLI 內建 MCP Client、Microsoft Copilot Studio 2025 Q4 接入——N×M 困境正式進入收斂期(來源:各廠商官方部落格 2025–2026)。
企業安全要求:Gartner 2026 預測 40% 的企業 AI Agent 部署將在 Q4 前引入 MCP 標準化工具層,同時 80% 的企業 IT 部門將 MCP Server 納入零信任稽核範圍(來源:Gartner AI Infrastructure 2026 展望)。
| 方案 | 生產 MCP Server | 主要短板 |
|---|---|---|
| 筆電 7×24 跑 Server | 零額外成本 | 合蓋即斷、系統更新中斷會話 |
| Serverless 冷啟動 | 按量計費 | Agent 首次工具呼叫延遲 5–15 秒 |
| 與 iOS CI 共用一台 Mac | 看似省事 | 連接埠與相依套件衝突風險高 |
| KVMNODE 雲 Mac + MCP | 獨佔節點、launchd、快照回滾 | 需規劃租期 |
攤開替代方案:在筆電上 7×24 跑 MCP Server 合蓋即斷、系統更新中斷會話;Serverless 冷啟動 導致 Agent 首次工具呼叫延遲 5–15 秒;與 iOS CI 共用一台 Mac 連接埠與相依套件衝突風險高。對需要 Apple Silicon 宿主、內網資源存取、以及把 MCP Server 與 Cursor Agent / Xcode CI 分開的團隊,在 KVMNODE 租用獨佔 Mac Mini M4 / M4 Pro 往往是更優解:Docker 化 Server 跑在獨佔節點,按天/週/月彈性、快照回滾。檔位見 定價頁,訂購入口 可在本週把 MCP 實驗環境從個人筆電遷出。