1. 前言
這篇文章將通過一個集成高德天氣查詢的 MCP Server 用例,帶你上手開發自己的 MCP Server ,文章將通過以下三種方式(自己編寫 Client 端代碼,使用 mcp-cli 自帶頁面,集成到 Claude 桌面版等)帶你測試自己的 MCP Server。
PS:文章中的每一步都經過自己親自上手。整理不易,請不要令色你的贊和收藏。
2. MCP介紹
2.1 什么是MCP?
MCP (Model Context Protocol) 是一個開放協議,由 Anthropic 公司推出的開放標準,用于標準化應用程序如何向 LLM 提供上下文。它可以比作 AI 應用程序的 USB-C 接口,提供了一種標準化方式將 AI 模型連接到不同的數據源和工具。
2.2 架構介紹
MCP 遵循 client-server (客戶端-服務端) 架構,并允許一個主機應用程序同時連接多個服務器。下面是其核心架構圖:
2.3 傳輸機制
MCP 中 Server 和 Client 之間主要支持以下兩種通信方式,并且都使用 JSON-RPC 2.0 (一種輕量級的遠程過程調用(RPC)協議) 交換消息:
-
Stdio 傳輸:使用標準輸入/輸出,適合本地通信。
-
SSE 傳輸:使用 Server-Sent Events 和 HTTP POST 請求,實現響應式輸出,適合遠程通信。
2.4 你的疑問?
2.4.1 什么是MCP Servers?
MCP Servers 是提供上下文、工具和提示給 AI 客戶端的系統。它們可以暴露數據源,如文件、文檔、數據庫和 API 集成,允許 AI 助手以安全的方式訪問實時信息
2.4.2?MCP Servers能提供什么?
MCP Servers 可以共享資源(文件、文檔、數據)、暴露工具(API 集成、操作)并提供提示(模板交互)。它們控制自己的資源并維護清晰的系統邊界以保障安全。
2.4.3 MCP Servers是如何工作的?
MCP Servers 通過簡單的客戶端-服務器架構工作。它們通過標準協議公開數據和工具,與主機應用程序(如 Claude 桌面)中的客戶端保持安全的 1:1 連接。
2.4.4 MCP Servers安全嗎?
是的,安全性已內置到 MCP 協議中。服務器控制自己的資源,無需與LLM提供商共享 API 密鑰,并且系統保持清晰的邊界。每個服務器管理自己的身份驗證和訪問控制。
3. 前提條件
這篇文章使用 Python 來開發 MCP Server ,使用高德地圖的 API 來查詢天氣。閱讀之前,你需要具備以下條件:
-
已安裝 Python 3.10 或更高版本。
-
已申請高德 web 服務?API_KEY,訪問??高德開放平臺?申請。
我使用的 Python 版本是 3.12,我的系統是 win11。
拓展:目前官方已提供以下幾種語言的 SDK:Python、TypeScript、Java、C#、Kotlin等,詳情可訪問文末的參考文檔。
4. 開發
4.1 創建一個Pyhon項目
推薦使用 uv 做為 Python 包管理工具。
1. 安裝 uv:
pip install uv
?2. 使用uv創建一個 mcp-demo 項目:
uv init mcp-demo
?3. 創建uv虛擬環境:
# 進入到剛創建的項目目錄下
cd .\mcp-demo\# 創建uv虛擬環境
uv venv .venv
執行完上述命令后,當前目錄下會創建一個名為 .venv 的虛擬環境文件夾。?
4.??激活虛擬環境:
.\.venv\Scripts\activate
5.?安裝 python mcp 依賴:?
uv add "mcp[cli]"
6.?PyCharm中引入該項目:
使用 PyCharm 打開這個項目,并在【Settings - Python Interpreter】中查看python解釋器是否正確(地址為項目路徑下的".venv\Scripts\python.exe")。
4.2 MCP Server開發
4.2.1 核心功能
MCP 主要提供一下三種功能:
-
資源(Resources):客戶端可讀取的文件類數據(如 API 響應或文件內容)。
-
工具(Tools):LLM 可調用的函數(需要用戶批準)。
-
提示(Prompts):幫助用戶完成特定任務的預編寫模板。
通過這篇文章,你可以快速構建一個 MCP Server,使 LLM 能夠訪問實時天氣數據。?MCP 提供了統一的接口,可以簡化?LLM 與外部數據源的集成過程。
4.2.2 代碼
這篇文章主要關注工具(Tools)的使用。
4.2.2.1 創建.env文件
首先在項目路徑下創建一個 .env 的文件,用來存儲配置信息:
AMAP_API_KEY=<你的高德API_KEY>
4.2.2.2 創建weather-mcp-server.py文件
這篇文章使用官方的 FastMCP 框架構建 MCP 服務端和客戶端。
完整代碼:
import os
from typing import Dict, Any, Optionalimport httpx
from dotenv import load_dotenv
from mcp.server.fastmcp import FastMCP# 定義一個 FastMCp 實例
mcp = FastMCP("LocalWeatherServer")# 高德天氣API配置信息
load_dotenv()
AMAP_WEATHER_API_BASE_URL = "https://restapi.amap.com/v3/weather/weatherInfo"
AMAP_API_KEY = os.getenv("AMAP_API_KEY")async def get_amap_weather(city: str) -> Optional[Dict[str, Any]]:"""調用高德天氣接口,獲取天氣數據"""params = {"city": city,"key": AMAP_API_KEY,"extensions": "all", # all:預報天氣,base:實況天氣"output": "JSON",}try:async with httpx.AsyncClient(timeout=5.0) as client:response = await client.get(AMAP_WEATHER_API_BASE_URL, params=params)response.raise_for_status()return response.json()except httpx.HTTPError as e:return {"error": f"天氣服務請求失敗:{e}"}def parse_forecast(cast: Dict[str, str]) -> str:""" 格式化單日天氣信息 """return (f"日期:{cast.get('date', '未知')},"f"星期:{cast.get('week', '未知')},"f"白天天氣:{cast.get('dayweather', '未知')},"f"夜晚天氣:{cast.get('nightweather', '未知')},"f"溫度:{cast.get('nighttemp', '未知')}~{cast.get('daytemp', '未知')}℃,"f"風向:{cast.get('daywind', '未知')}~{cast.get('nightwind', '未知')},"f"白天風力:{cast.get('daypower', '未知')}級,"f"夜晚風力:{cast.get('nightpower', '未知')}級。")def format_weather_data(weather_data: Dict[str, Any]) -> str:"""格式化天氣響應數據"""if "error" in weather_data:return weather_data["error"]forecasts = weather_data.get("forecasts", [])if not forecasts:return "未找到該城市的天氣信息。"forecast = forecasts[0]city = forecast.get("city", "未知城市")casts = forecast.get("casts", [])if not casts:return "未找到該城市的天氣信息。"today = parse_forecast(casts[0])future = "\n".join(parse_forecast(c) for c in casts[1:])result = [f"{city}今天的天氣:{today}"]if future:result.append(f"未來幾天天氣:\n{future}")return "\n".join(result)@mcp.tool()
async def fetch_weather(city: str) -> str:"""獲取城市天氣"""weather_data = await get_amap_weather(city)return format_weather_data(weather_data)if __name__ == "__main__":# 運行 MCP 服務器,默認傳輸協議 stdiomcp.run(transport="stdio")
5. 測試
5.1 通過編寫Client端代碼測試
5.1.1 客戶端實現完整代碼:
創建一個 mcp-client.py 的文件:
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client# 創建標準輸入輸出(stdio)連接的服務器參數配置
server_params = StdioServerParameters(command="python", # 要執行的命令/可執行文件args=["weather-mcp-server.py"], # 傳遞給命令的參數列表env=None,
)async def run():"""主運行函數,處理客戶端會話邏輯"""# 使用stdio_client建立連接,獲取讀寫通道async with stdio_client(server_params) as (read, write):# 創建客戶端會話async with ClientSession(read, write) as session:# 初始化連接(握手協議等)await session.initialize()# 列出所有可用的提示模板# prompts = await session.list_prompts()# 獲取特定提示模板,可傳入參數# prompt = await session.get_prompt(# "example-prompt", # 提示模板名稱# arguments={"arg1": "value"} # 模板參數# )# 列出所有可用資源# resources = await session.list_resources()# 列出所有可用工具tools = await session.list_tools()print(f"工具列表:{tools}")# 讀取特定資源內容# content, mime_type = await session.read_resource(# "file://some/path" # 資源URI# )# 調用指定工具result = await session.call_tool("fetch_weather", # 工具名稱arguments={"city": "南京"} # 工具參數)print(f"查詢結果:{result}")if __name__ == "__main__":import asyncio# 運行主異步函數asyncio.run(run())
5.1.2? 啟動服務端
首先需要啟動 MCP 服務端,PyCharm 中右鍵啟動:
5.1.3 測試
以同樣的方式運行客戶端測試,其結果如下:
5.2?使用mcp-cli自帶頁面測試
該方式需要安裝 node.js 。
5.2.1 啟動服務端
命令行鍵入:
mcp dev weather-mcp-server.py
運行結果:
5.2.2 測試
瀏覽器打開?http://127.0.0.1:6274?
?5.3 集成到 Claude 桌面端測試
首先你需要?下載?Claude 桌面端?。
5.3.1 啟動服務端
同 5.2.1?
5.3.2?配置claude_desktop_config.json文件
打開 Claude 桌面端 - File- Settings - Developer - Edit Config(我這里已經配置,這個界面會不同)。
點擊 Edit Config,進入 Claude 運行目錄,找到?claude_desktop_config.json 文件,鍵入以下配置,將 AMAP_API_KEY 值替換為你的高德 API_KEY:
{"mcpServers": {"LocalWeatherServer": {"command": "uv","args": ["--directory","F:\\workspace\\python\\demos\\mcp-demo","run","weather-mcp-server.py"],"env": {"AMAP_API_KEY": "<your_api_key>"}}}
}
配置完成后,重啟 Claude 桌面端(需要在任務管理器殺掉 Calude 進程)。
重啟后,對話框下方會出現如下錘子按鈕。
5.3.3 測試
在聊天對話框輸入 ‘ 南京天氣 ’,首次調用會出現如下是否使用工具的提示,點擊同意即可。
結果:
到這里,MCP的簡單用例就開發完了。如果你想發現、分享和學習各種適用于 AI 應用的 MCP 服務器,可以訪問?MCP Servers?。
6. 參考文檔
- Model Context Protocol 官網
- MCP Python SDK