weather-taipei
台北市中山區 天氣回報 MCP Server
A simple MCP (Model Context Protocol) server that reports the weather for Zhongshan District, Taipei, Taiwan — adapted from the official MCP tutorial, but using the free, key-less, global Open-Meteo API so it works outside the US.
這是一個 MCP 天氣伺服器:裝到 Claude 桌面版(或其他 MCP 客戶端)後,你用中文問 「中山區現在天氣如何?」、「未來三天會下雨嗎?」,AI 就會自動呼叫這個伺服器回報。
本專案改寫自 MCP 官方教學 Build an MCP server。 官方範例用美國國家氣象局 API(只能查美國),本專案改用 Open-Meteo(免費、免申請 金鑰、支援全球),因此可以查到台灣的天氣。
什麼是 MCP?
MCP(Model Context Protocol)是一套讓 AI 助理能「呼叫外部工具」的標準。 你可以把 MCP server 想成幫 AI 裝的外掛:AI 本身不會查天氣,但透過這個外掛, 它就能去 Open-Meteo 拿即時天氣資料回來給你。
一個 MCP server 可提供三種能力,本專案聚焦在 Tools(工具):
能力 | 說明 |
Tools | 可被 AI 呼叫的函式(需使用者同意)← 本專案使用 |
Resources | 可被讀取的類檔案資料 |
Prompts | 預先寫好的提示樣板 |
架構示意圖
整體運作流程:你用自然語言問 Claude,Claude 透過 MCP 協定呼叫本伺服器的工具, 伺服器再去 Open-Meteo 拿即時資料,格式化後一路回傳給你。
flowchart LR
U(["👤 使用者"]) -->|"問:中山區會下雨嗎?"| C["Claude 桌面版<br/>(MCP Host)"]
C -->|"回答"| U
C <-->|"MCP 協定 / stdio"| S
subgraph S ["weather-taipei MCP Server"]
direction TB
T1["get_zhongshan_weather<br/>中山區天氣"]
T2["get_weather_by_city<br/>各縣市天氣"]
T3["get_weather_by_coords<br/>經緯度天氣"]
T4["get_hourly_rain<br/>逐小時降雨"]
end
S -->|"HTTPS 查詢"| A[("🌤️ Open-Meteo API")]
A -->|"天氣 JSON"| SGitHub 會自動把上面的
mermaid區塊渲染成圖。若在不支援 Mermaid 的檢視器, 它會以文字方式呈現,內容一樣看得懂。
提供的工具(Tools)
工具名稱 | 參數 | 功能 |
| 無 | 回報台北市中山區「目前天氣」+「未來 3 天預報」 |
|
| 用台灣縣市名稱查天氣(台北、台中、高雄、宜蘭…,支援關鍵字) |
|
| 依經緯度查任一地點的天氣+未來 3 天預報 |
|
| 逐小時降雨:未來數小時(1~48)的雨量與降雨機率 |
回報內容包含:天氣狀況(中文)、溫度、體感溫度、相對濕度、降雨量、風速, 以及未來三天的高低溫與降雨機率;逐小時降雨則列出每小時的雨量與降雨機率。
支援的縣市:台北市中山區、台北市、新北市、基隆市、桃園市、新竹市/縣、苗栗縣、 台中市、彰化縣、南投縣、雲林縣、嘉義市/縣、台南市、高雄市、屏東縣、宜蘭縣、 花蓮縣、台東縣、澎湖縣、金門縣、連江縣。
輸出範例:
📍 台北市中山區 目前天氣(2026-07-05T16:00)
天氣狀況:毛毛雨(中)
溫度:31.8°C(體感 37.5°C)
相對濕度:63%
降雨量:0.2 mm
風速:1.7 km/h
未來 3 天預報:
2026-07-05:毛毛雨(中),26.7~33.3°C,降雨機率 99%
2026-07-06:毛毛雨(中),25.9~34.1°C,降雨機率 69%
2026-07-07:雷雨,25.1~32.8°C,降雨機率 97%逐小時降雨範例(get_hourly_rain):
📍 台北市中山區 未來 6 小時逐小時降雨
17:00 0.1 mm 降雨機率 98% ☔
18:00 0.1 mm 降雨機率 90% ☔
19:00 0.0 mm 降雨機率 77%
20:00 0.1 mm 降雨機率 63% ☔
21:00 0.0 mm 降雨機率 48%
22:00 0.0 mm 降雨機率 33%
這段期間預估總雨量約 0.3 mm。程式碼解說(weather_taipei.py)
程式很短,分成五個部分。以下逐段說明。
1. 初始化與常數
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather-taipei") # 建立一個名為 weather-taipei 的伺服器
OPEN_METEO_BASE = "https://api.open-meteo.com/v1/forecast"
ZHONGSHAN_LAT = 25.0637 # 中山區大約緯度
ZHONGSHAN_LON = 121.5265 # 中山區大約經度FastMCP 是官方提供的框架,會自動根據函式的型別註記與 docstring 產生工具定義,
不必手寫繁瑣的設定。
2. 天氣代碼轉中文
Open-Meteo 用「WMO 天氣代碼」(數字)表示天氣,例如 0=晴天、61=小雨、95=雷雨。
我們用一個字典把數字翻成中文:
WEATHER_CODES = {0: "晴天", 1: "大致晴朗", 2: "局部多雲", 3: "陰天",
61: "小雨", 63: "中雨", 65: "大雨", 95: "雷雨", ...}
def describe_code(code: int) -> str:
return WEATHER_CODES.get(code, f"未知天氣(代碼 {code})")3. 向 Open-Meteo 發出請求(含錯誤處理)
async def make_request(params: dict) -> dict | None:
async with httpx.AsyncClient() as client:
try:
resp = await client.get(OPEN_METEO_BASE, params=params, timeout=30.0)
resp.raise_for_status() # 若 HTTP 狀態非 2xx 會丟出例外
return resp.json()
except Exception:
return None # 出錯就回 None,交給上層處理用 httpx 的非同步(async)方式連網,速度快且不會卡住整個伺服器。
4. 查詢並排版天氣(核心邏輯)
fetch_weather() 組好查詢參數(座標、時區、要哪些欄位、預報幾天),呼叫 API,
再把結果排成好讀的文字。關鍵在於同時要了「目前(current)」與「每日(daily)」兩組資料:
params = {
"latitude": lat, "longitude": lon, "timezone": "Asia/Taipei",
"current": "temperature_2m,relative_humidity_2m,apparent_temperature,"
"precipitation,weather_code,wind_speed_10m",
"daily": "weather_code,temperature_2m_max,temperature_2m_min,"
"precipitation_probability_max",
"forecast_days": 3,
}5. 縣市名稱查座標 & 逐小時降雨
為了支援「用縣市名稱查天氣」,程式內建一份台灣各縣市的座標表 TAIWAN_LOCATIONS,
再用 resolve_location() 把名稱對應到座標(支援關鍵字,例如「高雄」→「高雄市」):
def resolve_location(name: str) -> tuple[float, float, str] | None:
if name in TAIWAN_LOCATIONS:
lat, lon = TAIWAN_LOCATIONS[name]
return lat, lon, name
for key, (lat, lon) in TAIWAN_LOCATIONS.items():
if name and name in key: # 部分關鍵字也能對應
return lat, lon, key
return None逐小時降雨 fetch_hourly_rain() 則向 API 要 hourly=precipitation,precipitation_probability,
再從「現在」這個時間點往後取 N 小時:
now = data.get("current", {}).get("time", "")
start = next((i for i, t in enumerate(times) if t >= now), 0) # 只看未來時段
for i in range(start, start + hours):
... # 印出每小時的雨量與降雨機率6. 用 @mcp.tool() 把函式變成 AI 可呼叫的工具
只要在函式上加 @mcp.tool(),它就會被登錄為工具;函式的 docstring 會成為
AI 看到的「工具說明」,所以描述要寫清楚。本專案共登錄四個工具:
@mcp.tool()
async def get_zhongshan_weather() -> str:
"""取得台灣台北市中山區目前的天氣與未來 3 天預報。"""
return await fetch_weather(ZHONGSHAN_LAT, ZHONGSHAN_LON, "台北市中山區")
@mcp.tool()
async def get_weather_by_city(city: str) -> str:
"""用台灣縣市名稱查詢天氣與未來 3 天預報。"""
...
@mcp.tool()
async def get_weather_by_coords(latitude: float, longitude: float) -> str:
"""依經緯度取得任一地點的天氣與未來 3 天預報。"""
...
@mcp.tool()
async def get_hourly_rain(city: str = "台北市中山區", hours: int = 12) -> str:
"""取得台灣某地未來數小時的逐小時降雨(雨量與降雨機率)。"""
...最後用 stdio 方式啟動,讓 Claude 桌面版能連上:
if __name__ == "__main__":
mcp.run(transport="stdio")安裝與使用
1. 先決條件
Python 3.10 以上
安裝套件:
pip install "mcp[cli]" httpx
2. 設定 Claude 桌面版
打開(或新建)設定檔:
%APPDATA%\Claude\claude_desktop_config.json(Windows)
把下列內容加入(路徑請改成你電腦上的實際路徑):
{
"mcpServers": {
"weather-taipei": {
"command": "python",
"args": ["C:/路徑/weather-taipei/weather_taipei.py"]
}
}
}存檔後完全關閉並重開 Claude 桌面版,再於對話中詢問天氣即可。
可參考本專案的 claude_desktop_config.sample.json。
設定完成後,可以這樣問 Claude:
「中山區現在天氣如何?」→
get_zhongshan_weather「台中市未來三天會下雨嗎?」→
get_weather_by_city「中山區未來 6 小時會下雨嗎?」→
get_hourly_rain「幫我查緯度 24.15、經度 120.67 的天氣」→
get_weather_by_coords
3. 不透過 Claude、直接用指令測試
python -c "import asyncio, weather_taipei as w; print(asyncio.run(w.fetch_weather(w.ZHONGSHAN_LAT, w.ZHONGSHAN_LON, '台北市中山區')))"資料來源與致謝
天氣資料:Open-Meteo(免費、免金鑰、CC BY 4.0)
架構參考:MCP 官方教學
授權
MIT License,詳見 LICENSE。
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/duncanhuang-5124/weather-taipei-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server