# 如何建立你的第一個 MCP 伺服器：逐步教學指南

學習從頭開始建立模型上下文協議 (MCP) 伺服器。這份實用教學將展示如何建立工具，讓 AI 助手（如 Claude）能夠存取外部 API。

Canonical URL: https://a2a-mcp.org/blog/how-to-build-mcp-server-zh-TW

Language: zh-TW

Published: 2026-04-06

Updated: 2026-04-06

## 前置準備

開始前，請確保您已準備好以下項目：

- 已安裝 **Python 3.10 或更高版本**。
- 基本熟悉 Python 函式與非同步程式碼。
- [uv](https://docs.astral.sh/uv/getting-started/installation/)（快速的 Python 套件管理工具） – 使用 `curl -LsSf https://astral.sh/uv/install.sh | sh` 指令安裝。
- 一個 MCP 客戶端，例如 **Claude Desktop**（從 claude.ai/download 下載並保持更新）。
- 一個文字編輯器或整合開發環境（IDE）。

無需事先具備 MCP 經驗。我們將建立一個實用的 **天氣 MCP 伺服器**，讓 AI 能透過國家氣象局（NWS）API 查詢即時的美國天氣警報與預報。

## 步驟 1：設定環境

建立一個乾淨的專案目錄，並使用 uv 進行初始化：

```bash
mkdir weather-mcp-server
cd weather-mcp-server
uv init
uv venv
source .venv/bin/activate  # 在 Windows 上：.venv\Scripts\activate
uv add "mcp[cli]" httpx
```

這將安裝官方的 MCP Python SDK（FastMCP）以及用於 API 呼叫的 httpx。您的專案現在應包含 `pyproject.toml` 檔案與虛擬環境。

**預期輸出：** 新的 `.venv` 資料夾，以及列在 `uv.lock` 中的相依套件。

## 步驟 2：建立 MCP 伺服器程式碼

建立主要檔案：

```bash
touch weather.py
```

將以下完整、可立即執行的程式碼貼到 `weather.py` 中：

```python
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP

# 初始化 MCP 伺服器
mcp = FastMCP("weather")

NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"

# 輔助函式：安全地呼叫 NWS API
async def make_nws_request(url: str) -> dict[str, Any] | None:
    headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(url, headers=headers, timeout=30.0)
            response.raise_for_status()
            return response.json()
        except Exception:
            return None

# 將天氣警報格式化，以便 AI 清晰閱讀
def format_alert(feature: dict) -> str:
    props = feature["properties"]
    return f"""
Event: {props.get("event", "Unknown")}
Area: {props.get("areaDesc", "Unknown")}
Severity: {props.get("severity", "Unknown")}
Description: {props.get("description", "No description available")}
Instructions: {props.get("instruction", "No specific instructions provided")}
"""

# 工具 1：取得美國某個州的現行天氣警報
@mcp.tool()
async def get_alerts(state: str) -> str:
    """Get current weather alerts for a U.S. state (e.g., "CA" or "TX")."""
    url = f"{NWS_API_BASE}/alerts/active/area/{state.upper()}"
    data = await make_nws_request(url)
    if not data or "features" not in data:
        return "Unable to fetch alerts or no alerts found."
    if not data["features"]:
        return f"No active alerts for {state.upper()}."
    alerts = [format_alert(f) for f in data["features"]]
    return "\n---\n".join(alerts)
```

# 工具 2：取得任意緯度/經度的 5 天預報
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """取得特定緯度和經度的天氣預報。"""
    points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
    points_data = await make_nws_request(points_url)
    if not points_data:
        return "無法取得此位置的天氣預報數據。"
    forecast_url = points_data["properties"]["forecast"]
    forecast_data = await make_nws_request(forecast_url)
    if not forecast_data:
        return "無法取得詳細預報。"
    periods = forecast_data["properties"]["periods"][:5]
    forecasts = []
    for period in periods:
        forecast = f"""
{period["name"]}:
溫度：{period["temperature"]}°{period["temperatureUnit"]}
風速：{period["windSpeed"]} {period["windDirection"]}
預報：{period["detailedForecast"]}
"""
        forecasts.append(forecast)
    return "\n---\n".join(forecasts)

def main():
    mcp.run(transport="stdio")

if __name__ == "__main__":
    main()
```

**關鍵概念說明：**
- `@mcp.tool()` 裝飾器將普通的 async 函數轉換為 AI 能夠發現並呼叫的 MCP 工具。
- 伺服器透過 **stdio**（標準輸入/輸出）運行 — 這是本地 MCP 伺服器的預設方式。
- 所有日誌記錄應輸出到 stderr（FastMCP 會自動處理）。

## 步驟 3：在本地測試伺服器

執行伺服器：

```bash
uv run weather.py
```

**預期輸出：**
終端機保持開啟且無輸出（這是 stdio 伺服器的正常現象）。只有當 MCP 客戶端連接時，您才會看到 JSON-RPC 訊息。

請保持此終端機運行，以進行下一步。

## 步驟 4：將 MCP 伺服器連接至 Claude Desktop

1. 開啟 Claude Desktop。
2. 建立或編輯位於以下位置的設定檔：
   - **macOS**：`~/Library/Application Support/Claude/claude_desktop_config.json`
   - **Windows**：`%APPDATA%\Claude\claude_desktop_config.json`

加入以下確切項目（請將 `/ABSOLUTE/PATH/TO/weather-mcp-server` 替換為您的實際資料夾路徑）：

```json
{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/weather-mcp-server",
        "run",
        "weather.py"
      ]
    }
  }
}
```

3. 完全退出 Claude Desktop（macOS 為 Cmd+Q，Windows 為從系統匣關閉），然後重新啟動它。
4. 在 Claude 中，點擊 **「Add files, connectors, and more」** → 懸停在 **Connectors** 上 → 您應該會看到 **「weather」** 列出。

## 步驟 5：與 AI 一起使用您的 MCP 伺服器

在 Claude Desktop 中嘗試這些提示：

-
「德州有哪些活躍的天氣警報？」
- 「給我舊金山的天氣預報（使用緯度 37.77，經度 -122.41）。」
- 「檢查加州的警報，並告訴我是否需要準備任何事項。」

Claude 將自動發現這些工具，第一次使用時會徵求您的同意，然後返回格式化的結果。

**預期行為：** AI 將在後台呼叫您的工具，並以自然語言顯示答案。

## 常見問題與疑難排解

- **伺服器未出現在 Claude 中**：
  - 再次確認 JSON 格式是否有效（無多餘的逗號）。
  - 在配置中使用**絕對路徑**。
  - 完全重新啟動 Claude。
  - 檢查日誌：`~/Library/Logs/Claude/mcp*.log`（macOS）或 Windows 上的等效位置。

- **API 錯誤或無資料**：
  - NWS API 僅適用於美國境內地點。
  - 請使用兩個字母的州代碼（例如 CA、TX 等）。
  - 座標必須是有效的緯度/經度。

- **「指令未找到」**：
  - 確保 uv 已在您的 PATH 中且虛擬環境已啟用。
  - 執行 `uv --version` 來驗證安裝。

- **逾時或回應緩慢**：
  - 如有需要，可在 `make_nws_request` 中增加逾時設定。
  - NWS 有速率限制——避免在正式環境中頻繁請求。

- **權限問題**：
  - 在 macOS 上，請前往系統設定 → 隱私與安全性，授予 Claude Desktop 完整的磁碟存取權限。

## 後續步驟

- **新增更多工具**：使用相同的 `@mcp.tool()` 模式，建立適用於資料庫、GitHub、Slack 或您自己的 API 的工具。
- **新增資源與提示**：使用 `mcp.resource()` 和 `mcp.prompt()` 來處理檔案類資料及可重複使用的指令。
-a **遠端部署**：切換到 HTTP/SSE 傳輸協定，並在 AWS Lambda、Vercel 或任何伺服器上部署（FastMCP 支援 `stateless_http=True`）。
- **支援多種語言**：嘗試使用官方的 TypeScript、Go 或 Rust SDK 以實現相同的功能。
- **分享您的伺服器**：將倉儲發佈出去，讓其他人可以透過 `npx` 或 Docker 來新增它。

您現在已擁有一個功能完整的 MCP 伺服器，任何相容的 AI 用戶端皆可使用。立即開始試驗、擴充工具，並著手建構強大的 AI 整合吧！
