開發者從零構建 MCP Server 連接 AI 客戶端與外部工具的架構示意圖

從 0 開發一個 MCP Server:手把手教你構建 AI 工具調用能力

大模型再聰明,也無法直接查你的資料庫、呼叫內部 API 或讀取本機檔案——這不是模型「不夠聰明」,而是缺少標準化的工具調用通道Model Context Protocol(MCP) 正是 Anthropic 開源的解法:讓 Claude、Cursor、GPT 透過統一協議存取外部能力。讀完本文,你將能獨立開發、除錯並部署一個生產可用的 MCP Server,涵蓋 Tools、Resources、Prompts 三大核心能力與 HTTP 遠端傳輸。

1. 三大痛點:為什麼 AI 需要 MCP Server

在寫第一行碼之前,先對齊你要解決的實際問題:

  1. 工具孤島:Function Calling、Plugins、LangChain Tools 各寫各的格式,換一個模型供應商就要重寫整合層——典型的 N×M 困境
  2. 資料不可達:模型訓練資料有截止日期,無法讀取你的即時配置、內部文件或資料庫狀態。
  3. 動作不可執行:純對話 AI 不能替你發 HTTP 請求、寫檔案或跑 SQL——除非透過標準化工具層暴露這些能力。

若你已讀過《MCP 為何會成為 AI 時代的 HTTP 協議》,本文不再重複協議選型論證,而是直接進入程式實作。適合人群:具 Python 或 TypeScript 基礎的後端/AI 開發者。

2. 什麼是 MCP:協議原理與架構概覽

2.1 MCP 的誕生背景

大模型工具調用能力經歷了三代演進:Function Calling(OpenAI 私有格式)→ Plugins(ChatGPT 生態封閉)→ MCP(2024 年 11 月 Anthropic 開源的開放協議)。MCP 解決的核心問題是:標準化 AI 與外部工具之間的通訊,一次實作、多客戶端複用。

2.2 協議架構:Client ↔ Server ↔ 三大能力

┌────────────────────┐         ┌─────────────────────┐
│   MCP Client       │ ◄─────► │   MCP Server        │
│  (Claude / Cursor) │  JSON   │  (你要開發的部分)    │
│                    │  -RPC   │                     │
└────────────────────┘         └─────────────────────┘
                                        │
                          ┌─────────────┼─────────────┐
                          ▼             ▼             ▼
                       Tools       Resources      Prompts
                    (工具呼叫)    (資源讀取)    (提示詞模板)
  • Client:AI 模型側——Claude Desktop、Cursor、VS Code、自訂 Agent。
  • Server:你開發的能力提供方,暴露 Tools / Resources / Prompts。
  • Tools:AI 可呼叫的函式(搜尋、計算、資料庫查詢、寫檔案)。
  • Resources:AI 可讀取的資源(檔案、URL、配置串流),透過 URI 尋址。
  • Prompts:預定義的提示詞模板,支援動態參數注入。

2.3 通訊機制

MCP 基於 JSON-RPC 2.0。傳輸方式有兩種:

  • stdio:本機子進程,Client 啟動 Server 並透過標準輸入/輸出通訊,延遲極低。
  • HTTP + SSE / Streamable HTTP:遠端服務,支援多客戶端並發連線。

生命週期:初始化握手能力協商(tools/list、resources/list)→ 請求/回應(tools/call)→ 關閉

2.4 MCP 與其他方案對比

對比維度 MCP OpenAI Function Calling LangChain Tools
標準化程度 開放協議標準 廠商私有 框架綁定
傳輸方式 stdio / HTTP HTTP HTTP
跨模型支援 是(Claude、GPT、Gemini 等) 部分
Resources / Prompts 原生支援 不支援 不支援
生態規模(2026) 10,000+ Server,AAIF 治理 成熟但封閉 成熟但綁定 Python

3. 開發環境準備與專案結構

3.1 選擇開發語言

  • Python(本文主語言):官方 SDK mcpFastMCP 裝飾器簡潔易上手。
  • TypeScript(對照):官方 SDK @modelcontextprotocol/sdk,適合 Node/全端開發者。

3.2 環境搭建

# Python 環境
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install mcp httpx pydantic

# TypeScript 環境(對照)
npm init -y
npm install @modelcontextprotocol/sdk

3.3 推薦專案結構

my-mcp-server/
├── server.py            # 主服務入口
├── tools/
│   ├── __init__.py
│   ├── calculator.py
│   └── web_search.py
├── resources/
│   └── file_reader.py
├── prompts/
│   └── templates.py
├── tests/
│   └── test_tools.py
├── pyproject.toml
└── README.md

3.4 除錯工具

  • MCP Inspector:官方除錯 UI,可視化測試 Tools / Resources / Prompts。
  • Claude Desktop:編輯 claude_desktop_config.json 聯調。
  • Cursor:在 Settings → MCP 或專案 .cursor/mcp.json 中配置。

4. 第一個 MCP Server:Hello World

4.1 最簡 Server 程式碼

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("my-first-server")

@mcp.tool()
def say_hello(name: str) -> str:
    """向指定的人打招呼"""
    return f"Hello, {name}! 這是你的第一個 MCP 工具。"

if __name__ == "__main__":
    mcp.run()

4.2 執行與驗證

python server.py
# 或使用 MCP Inspector 除錯
npx @modelcontextprotocol/inspector python server.py

Inspector 啟動後,在瀏覽器中查看 tools/list 是否回傳 say_hello,並用 tools/call 傳入 {"name": "開發者"} 驗證回傳。

4.3 在 Cursor / Claude Desktop 中接入

Cursor.cursor/mcp.json):

{
  "mcpServers": {
    "my-first-server": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"]
    }
  }
}

Claude Desktop(macOS ~/Library/Application Support/Claude/claude_desktop_config.json):結構相同。重啟客戶端後,在 Agent 對話中應能看到 say_hello 工具出現在上下文中。

5. Tools:開發可被 AI 呼叫的工具

5.1 工具基本結構

函式簽名即文件:參數型別、回傳型別、docstring 會被自動轉為 JSON Schema 供 AI 理解。命名建議用 snake_case,動詞開頭(search_webread_file)。

5.2 輸入參數型別(Pydantic)

from pydantic import BaseModel, Field

class SearchInput(BaseModel):
    query: str = Field(description="搜尋關鍵字")
    max_results: int = Field(default=5, description="最多回傳結果數")
    language: str = Field(default="zh", description="結果語言")

@mcp.tool()
def web_search(input: SearchInput) -> list[dict]:
    """執行網路搜尋,回傳相關結果列表"""
    # 實作搜尋邏輯
    ...

5.3 五個實用工具實戰

  1. 計算機eval 安全子集或 ast.literal_eval,處理數學運算式。
  2. 檔案讀寫:限定白名單目錄,防止路徑穿越。
  3. HTTP 請求:用 httpx 呼叫外部 API,回傳 JSON 或文字。
  4. 資料庫查詢:唯讀 SQL + 參數化查詢,禁止 DDL。
  5. 時間工具datetime.now(timezone.utc) 與時區轉換。

5.4 非同步工具

import httpx

@mcp.tool()
async def fetch_url(url: str) -> str:
    """取得指定 URL 的內容"""
    async with httpx.AsyncClient(timeout=30.0) as client:
        response = await client.get(url)
        response.raise_for_status()
        return response.text

5.5 錯誤處理最佳實踐

  • 業務錯誤回傳結構化 JSON({"error": "...", "code": 404}),而非裸拋例外。
  • 所有外部呼叫設定逾時(建議 30 秒以內)。
  • 檔案/資料庫操作做權限校驗,最小權限原則。

6. Resources:讓 AI 讀取動態內容

6.1 Resource 與 Tool 的區別

Resource 是資料提供者,Tool 是動作執行者。 AI 透過 URI 讀取 Resource 內容,不會觸發副作用。

6.2 靜態與動態資源

import json

@mcp.resource("config://app-settings")
def get_app_settings() -> str:
    """回傳應用配置"""
    return json.dumps({"version": "1.0", "env": "production"})

@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    """根據使用者 ID 回傳使用者資料"""
    user = db.query_user(user_id)
    return json.dumps(user)

URI 方案支援 file://http://custom:// 等自訂前綴。

6.3 資源型別

  • 文字text/plainapplication/json
  • 二進位:圖片、PDF(Base64 或 Blob URI)
  • 串流:即時資料推送(SSE 訂閱)

6.4 檔案系統資源伺服器

實戰模式:列出目錄 → 讀取檔案內容 → 可選監聽檔案變化(watchfiles)觸發資源更新通知。務必配置允許存取的根目錄白名單,避免 AI 讀取敏感路徑。

7. Prompts:定義可複用的提示詞模板

7.1 什麼是 MCP Prompt

預定義的提示詞片段,AI 客戶端可直接複用,支援動態參數注入,提升團隊一致性與可維護性。

7.2 建立提示詞模板

from mcp.types import PromptMessage, TextContent

@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[PromptMessage]:
    """程式碼審查提示詞模板"""
    return [
        PromptMessage(
            role="user",
            content=TextContent(
                type="text",
                text=f"""請對以下 {language} 程式碼進行審查,重點關注:
1. 程式碼品質與可讀性
2. 潛在的 Bug 與安全隱患
3. 效能優化建議

程式碼內容:
```{language}
{code}
```"""
            )
        )
    ]

7.3 多輪對話提示詞

可定義包含 userassistant 的多輪模板,適用於面試模擬、程式碼除錯助手等場景。每條 PromptMessage 指定 rolecontent,Client 按序注入對話上下文。

8. HTTP 傳輸模式:遠端 MCP Server

8.1 stdio vs HTTP + SSE

特性 stdio HTTP + SSE
部署方式 本機子進程 遠端伺服器
延遲 極低(<1ms) 依賴網路(10–200ms)
多客戶端 不支援 支援
適用場景 本機開發、個人工具 SaaS、團隊共享、7×24 服務

8.2 實作 HTTP 傳輸

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("remote-server", transport="streamable-http")

if __name__ == "__main__":
    mcp.run(host="0.0.0.0", port=8000)

8.3 認證與安全

  • Bearer Token:Client 請求標頭攜帶 Authorization: Bearer <token>
  • API Key 中介層:校驗密鑰 + IP 白名單。
  • CORS:僅允許可信 Origin。
  • 頻率限制:防止工具被濫用(如每秒 10 次 tools/call)。

9. 除錯、測試與常見錯誤

9.1 MCP Inspector 除錯流程

  1. 啟動:npx @modelcontextprotocol/inspector python server.py
  2. 在 UI 中查看 Tools / Resources / Prompts 列表。
  3. 手動觸發 tools/call,檢查請求/回應 JSON。
  4. 模擬錯誤場景(逾時、非法參數)驗證錯誤處理。

9.2 單元測試範例

import pytest
from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client

@pytest.mark.asyncio
async def test_calculator_tool():
    server_params = StdioServerParameters(
        command="python",
        args=["server.py"]
    )
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool("calculate", {"expression": "2 + 2"})
            assert result.content[0].text == "4"

9.3 常見錯誤排查

錯誤現象 常見原因 解決方案
工具未出現在 AI 中 配置路徑錯誤、Client 未重啟 檢查 config.json 絕對路徑,重啟 Cursor/Claude
JSON 序列化失敗 回傳型別不支援(如 datetime 物件) 轉為字串或 dict
逾時斷開 工具執行超過 Client 預設逾時 改用 async + 設定 timeout,或拆分長任務
權限拒絕 檔案路徑超出白名單 配置允許存取的目錄根路徑

10. 生產部署:Docker、雲服務與監控

10.1 Docker 容器化

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]

10.2 雲服務選型(2026 參考)

  • Railway / Render:一鍵部署,適合個人專案(月費約 $5–20)。
  • AWS Lambda / Google Cloud Run:Serverless,按呼叫計費。
  • 自建 VPS / 遠端 Mac:配合 Nginx 反向代理 + launchd 守護,適合需要 Apple 生態或長期 7×24 運行的 Agent 工具鏈。

10.3 監控與可觀測性

  • 結構化日誌:每次 tools/call 記錄 tool 名、耗時、狀態碼。
  • Prometheus 指標:呼叫次數、P99 延遲、錯誤率。
  • Sentry:未捕獲例外告警。
  • 健康檢查GET /health 回傳 200 + 協議版本號。

10.4 版本管理與相容性

在初始化握手時宣告 MCP 協議版本;工具升級採用向後相容策略——新增可選參數而非刪除必填欄位。重大變更時並行運行 v1/v2 Server,Client 透過能力協商選擇。

11. 實戰專案:個人知識庫 MCP Server

11.1 專案需求

  • 讓 AI 能搜尋你的本機 Markdown 筆記。
  • 支援語意搜尋(向量檢索,而非純關鍵字)。
  • 支援建立與更新筆記。

11.2 技術選型

  • 向量資料庫:ChromaDB 或 Qdrant(本機嵌入式,零運維)。
  • 嵌入模型text-embedding-3-small(OpenAI)或本機 nomic-embed-text
  • 檔案監聽watchfiles 自動重建索引。

11.3 核心工具設計

  1. index_notes:掃描筆記目錄,分塊嵌入並寫入向量庫。
  2. search_notes:語意搜尋,回傳 Top-K 片段 + 源檔案路徑。
  3. write_note:建立或追加 Markdown 檔案(白名單目錄內)。
  4. notes://{path} Resource:直接讀取指定筆記全文。

11.4 效果演示

在 Cursor 中直接問:「我上週記錄了什麼關於 MCP 的筆記?」—— AI 呼叫 search_notes 工具,回傳相關片段並引用源檔案。這比把整庫筆記塞進 Context Window 節省 90%+ Token,且支援即時更新。

12. MCP 生態與未來展望

12.1 優質 MCP Server 推薦

  • mcp-server-filesystem:檔案系統讀寫與目錄列表。
  • mcp-server-github:GitHub 倉庫操作、Issue、PR。
  • mcp-server-brave-search:網路搜尋。
  • mcp-server-postgres:PostgreSQL 唯讀查詢。
  • mcp-server-slack:Slack 訊息發送與讀取。

官方文件:modelcontextprotocol.io;Python SDK:github.com/modelcontextprotocol/python-sdk;TypeScript SDK:github.com/modelcontextprotocol/typescript-sdk

12.2 2026 生態趨勢

  • 主流 AI 客戶端(Cursor、Claude Desktop、VS Code Copilot、Gemini CLI)均已原生支援 MCP。
  • MCP Marketplace 與 AAIF 治理推動 Server 品質認證。
  • 企業級安全標準:OAuth 2.1、細粒度 Tool 權限、稽核日誌。

12.3 下一步學習路徑

  • 深入學習 MCP 協議規範全文。
  • 開發並發布你的第一個公開 MCP Server 到 GitHub。
  • 探索 MCP + Agent 組合(參考《Cursor Agent Skill》與 OpenClaw MCP 整合)。
  • 向開源生態貢獻 Tools 或 Resources 實作。

13. 總結:從本機實驗到 7×24 生產節點的決策

本文涵蓋了 MCP Server 開發的完整鏈路:協議原理 → 環境搭建 → Hello World → Tools / Resources / Prompts → HTTP 遠端傳輸 → Inspector 除錯 → Docker 部署 → 個人知識庫實戰。MCP 是 AI 工具化的標準協議,掌握它是 2026 年 AI 工程師的核心競爭力之一。

然而,本機 stdio 模式有明確邊界:筆電合蓋即斷鏈、向量庫與嵌入模型佔用本機記憶體、多 Server 並發時 CPU 搶占。個人知識庫 MCP、HTTP 遠端 Server、以及需要 ChromaDB + 嵌入 API 的長時會話,在常線上 Apple Silicon 節點上運行更穩定——統一記憶體架構對向量檢索友善,macOS 原生支援 launchd 守護與 Cursor/Claude 同構工具鏈。

SFTPMAC 遠端 Mac 租賃提供面向 MCP Server 與 AI Agent 工作流的 7×24 Apple Silicon 環境:低延遲 HTTP+SSE 回調、原生 Python/Node 執行環境、SFTP/rsync 同步筆記目錄與配置,比「家用電腦兼 MCP 宿主」更適合把個人知識庫或團隊工具層當生產入口。你打算用 MCP 開發什麼工具?從 Hello World 開始,今天就能跑起來。