目錄
一、使用Trae編輯器配置高德MCP Server?
1.1 Trae介紹
1.2 從mcp.so中獲取配置高德地圖mcp server配置信息
1.3 高德地圖開發者配置
1.4 添加Filesystem 到Trae
1.5 使用結果展示
1.6 MCP常見命令行工具和包管理說明
1.7?Function Call工具和MCP技術對比
二、本地開發自己的MCP Server
2.1 MCP Server開發
?將 MCP 添加到Python 項目中,使用 uv 來管理Python 項目。
創建虛擬環境和激活
?將 MCP 添加到項目依賴中
創建weather.py
?AI編輯器配置MCP
測試mcp server
2.2 MCP Client 開發
配置項
環境搭建?
?創建?client.py
2.3 整合測試
本文介紹如何使用Trae編輯器與MCP協議配置高德地圖服務并開發定制化MCP Server
一、使用Trae編輯器配置高德MCP Server?
1.1 Trae介紹
Trae是字節跳動于2025年推出的AI原生集成開發環境,提供 Claude 3.5、GPT-4o 等模型免費不限量調用
與 Cursor 對比:Trae 更側重中文支持、企業級協作及全流程自動化,Cursor 則強于代碼調試和復雜項目優化
官網地址:https://www.trae.com.cn/
進入官網直接下載 然后next next 安裝即可:
下載后 登錄 然后打開長這樣:
1.2 從mcp.so中獲取配置高德地圖mcp server配置信息
訪問https://mcp.so/?找到高德地圖官方MCP server?
需要copy這個配置出來
然后在Trae中手動添加
添加到這里就可以? 高德key的獲取在下面章節
1.3 高德地圖開發者配置
地址:https://lbs.amap.com/ 訪問后進入控制臺?
進入控制臺后 初次使用需要個人信息認證 按步驟操作就可以
?先創建應用 (初次使用頁面上有新手指引)
然后創建key
copy這個key 放到剛才Trae手動添加mcp server的地方
配置成功會有 √ 可使用標識 。出現紅色的×? 可以點×圖標進去看看錯誤log
注意:安裝(有node環境即可,即npm存在就可以)
npm沒裝 手動配置這步是會錯誤的!!!
1.4 添加Filesystem 到Trae
從Trae中添加
現在已經加好了2個
1.5 使用結果展示
選擇Builder with MCP? 然后再輸入問題:
我后天去安徽合肥玩3天的旅行。你規劃下攻略 ,需要將行程和天氣放一起進行規劃 再加上交通工具 然后生成kmTravel.html
查看最后結果:
1.6 MCP常見命令行工具和包管理說明
?npx:Node.js 的 “即跑即用” 執行工具
?npx是npm命令的升級版本,功能強大, 側重于執行命令的,執行某個模塊命令,會自動安裝模塊,但是重在執行某個命令。在 MCP 開發中,npx主要用于調試 MCP 服務器或執行與 MCP 協議相關的 Node.js 工具
uv:Rust 編寫的 Python 極速包管理器
uv是用 Rust 開發的 Python 包與項目管理器,主打極速創建虛擬環境和依賴隔離。在 MCP 開發中,uv主要用于管理 Python 實現的 MCP 服務器或工具的依賴環境,適合需要快速創建、切換開發環境的場景
uvx:uv 的 “臨時環境執行” 擴展工具
uvx是uv工具鏈的擴展命令,定位為臨時環境執行器。
無需提前創建環境,直接為單次命令創建臨時虛擬環境,執行后自動清理,適合一次性工具調用
在 MCP 中,uvx主要用于臨時運行 Python 實現的 MCP 工具(如官方的mcp-server-fetch)
1.7?Function Call工具和MCP技術對比
MCP解決的核心問題
協議標準化:?通過定義統一的通信規范(類似 USB-C 接口),將傳統 Tool/Function Call 的 “定制化適配” 轉化為 “標準化接入”
例如,開發一個 MCP 兼容的數據庫服務器后,可被 千問、GPT-4 等所有支持 MCP 的模型調用,無需重復開發效率提升:傳統集成中,開發者需為每個工具編寫 API 調用代碼(如天氣查詢需處理 HTTP 請求、JSON 解析等)
MCP 提供標準化 SDK,開發者只需關注業務邏輯,接口適配成本趨近于零。Function Call
每個工具獨立開發接口,形成 “煙囪式” 架構(如為 每個API,數據庫、 分別編寫適配代碼)。
手動串聯多個工具調用(如先調用天氣 API,再調用地圖 API),流程硬編碼且難以維護。
綁定特定模型,遷移成本高(如從 GPT-3.5 遷移至 Claude 需重寫所有工具調用邏輯)。
優先選擇 MCP 的場景
復雜企業級應用:需集成多個異構系統(如 ERP、CRM、郵件、數據庫),且未來可能擴展新工具。
跨模型部署:需支持多 LLM 供應商(如同時使用 Claude 和 GPT)。
敏感數據處理:涉及醫療、金融等受監管數據,需嚴格權限控制和審計
優先選擇 Function Call 的場景
快速原型開發:簡單功能驗證(如天氣查詢、計算器),追求最短開發周期。
封閉環境應用:工具邏輯完全內置于當前系統(如內部知識庫問答),無需外部交互。
深度依賴特定模型:需利用專有功能(如 GPT-4 的代碼解釋器)。
混合架構策略
對于大型項目,可采用 “MCP+Function Call” 混合架構:
核心業務流程:通過 MCP 協議實現標準化集成(如數據庫、API)。
邊緣功能模塊:使用 Function Call 快速實現輕量級工具調用(如簡單計算器)。
這種策略既能享受 MCP 的擴展性與安全性,又能保留 Function Call 的敏捷性。
二、本地開發自己的MCP Server
基于高德地圖接口,開發定制化的MCP Server
參考官方文檔:https://modelcontextprotocol.io/introduction
@mcp.tool() 裝飾器
用于標記工具函數,將普通Python函數注冊為MCPServer可調用的服務方法。
通常配合協議解析器使用,自動暴露函數到服務接口。
@mcp.resource 裝飾器
用于定義資源型接口(類似RESTful API),處理HTTP請求或自定義協議的資源操作。
通常與URL路由或協議動作綁定,支持CRUD操作。
2.1 MCP Server開發
本節內容是在window11上操作的 。MacOS/Linux 有些命令不一樣 。見官網demo
?將 MCP 添加到Python 項目中,使用 uv 來管理Python 項目。
#安裝uv環境
pip install uv
uv init nnw-mcp-server-demo
cd nnw-mcp-server-demo
?然后再vscode中選擇文件夾打開即可
創建虛擬環境和激活
uv venv
# 激活虛擬環境
# On Windows:
.venv\Scripts\activate
# On Unix or MacOS:
source .venv/bin/activate
?目錄前面是項目名稱就可以
?將 MCP 添加到項目依賴中
uv add mcp[cli] httpx
創建weather.py
from typing import Any, Optional
import httpx
from mcp.server.fastmcp import FastMCPmcp = FastMCP("amap-weather")# 高德地圖API常量 就是上個章節的那個Key
AMAP_API_BASE = "https://restapi.amap.com/v3"
AMAP_API_KEY = "2f92a69cxxxxxxxxxxxxxxxxxxx"
USER_AGENT = "amap-weather-app/1.0"async def make_amap_request(endpoint: str, params: dict) -> dict[str, Any] | None:"""通用高德API請求函數(帶錯誤處理)Args:endpoint: API接口路徑(如"/weather/weatherInfo")params: 請求參數(自動附加key和基礎參數)"""print("正在發起高德API請求...make_amap_request")base_params = {"key": AMAP_API_KEY, "output": "JSON"}full_params = {**base_params, **params}async with httpx.AsyncClient() as client:try:response = await client.get(f"{AMAP_API_BASE}{endpoint}",params=full_params,headers={"User-Agent": USER_AGENT},timeout=30.0,)response.raise_for_status() # 檢查HTTP狀態碼(非200拋異常)data = response.json()# 處理高德API業務錯誤碼(如key無效、參數錯誤)if data.get("status") != "1":err_msg = data.get("info", "未知錯誤")print(f"高德API請求失敗:{err_msg}")return Nonereturn dataexcept Exception as e:print(f"請求異常:{str(e)}")return Nonedef format_realtime_weather(data: dict) -> str:"""格式化實時天氣數據為可讀文本"""realtime = data["lives"][0] # 高德實時天氣數據在lives數組中return f"""城市:{realtime['city']}實時天氣:{realtime['weather']}({realtime['temperature']}°C)濕度:{realtime['humidity']}%風向:{realtime['winddirection']}風速:{realtime['windpower']}級更新時間:{realtime['reporttime']}"""def format_forecast(data: dict) -> str:"""格式化未來天氣預報數據為可讀文本"""forecasts = []for day_data in data["forecasts"][0]["casts"]: # 高德預報數據在casts數組中forecast = f"""日期:{day_data['date']}白天天氣:{day_data['dayweather']}夜間天氣:{day_data['nightweather']}最高溫:{day_data['daytemp']}°C最低溫:{day_data['nighttemp']}°C風向:{day_data['daywind']}風力:{day_data['daypower']}級"""forecasts.append(forecast)return "\n---\n".join(forecasts)@mcp.tool()
async def get_realtime_weather(city_adcode: str) -> str:"""獲取中國城市實時天氣(通過高德地圖API)Args:city_adcode: 城市編碼(如北京110000,上海310000,可通過高德城市編碼表查詢)"""print("正在獲取實時天氣...get_realtime_weather")data = await make_amap_request(endpoint="/weather/weatherInfo",params={"city": city_adcode,"extensions": "base",}, # extensions=base表示實時天氣)if not data or not data.get("lives"):return "無法獲取實時天氣數據(請檢查城市編碼或API Key)"return format_realtime_weather(data)@mcp.tool()
async def get_forecast(city_adcode: str) -> str:"""獲取中國城市未來多天天氣預報(通過高德地圖API)Args:city_adcode: 城市編碼(如北京110000,上海310000,可通過高德城市編碼表查詢)"""data = await make_amap_request(endpoint="/weather/weatherInfo",params={"city": city_adcode, "extensions": "all"}, # extensions=all表示預報)if not data or not data.get("forecasts"):return "無法獲取天氣預報數據(請檢查城市編碼或API Key)"return format_forecast(data)if __name__ == "__main__":# 啟動MCP服務器(通過標準輸入輸出通信)mcp.run(transport="stdio")
?AI編輯器配置MCP
{"mcpServers": {"weather": {"command": "uv","args": ["--directory","C:\\soft\\test\\nnw-mcp-server-demo","run","weather.py"]}}
}
配置成功后是這樣的??
測試mcp server
正常調用實時工具
正常調用預報工具
?到這mcp server demo就開發結束啦 ~
2.2 MCP Client 開發
配置項
DASHSCOPE_API_KEY = "sk-xxx" ?# 阿里云DashScope平臺申請的API Key
TONGYI_MODEL = "qwen-plus" ? ?# 使用的通義千問模型
環境搭建?
同上面mcp server的一致?
?創建?client.py
代碼流程參考MCP官方案例:https://modelcontextprotocol.io/quickstart/client
import asyncio
import json
import sys
from typing import Optional
from contextlib import AsyncExitStack
import httpx# ClientSession:MCP客戶端會話;StdioServerParameters:標準輸入輸出服務端配置參數
from mcp import ClientSession, StdioServerParameters# 標準輸入輸出客戶端,用于通過控制臺與服務端通信(適用于本地進程間通信)
from mcp.client.stdio import stdio_clientDASHSCOPE_API_KEY = "sk-090303xxxxxxxxxxxxxxxx" # 阿里云DashScope平臺API Key
TONGYI_MODEL = "qwen-plus" # 使用qwen-plus模型class MCPClient:"""MCP客戶端,用于連接服務端并通過LLM調用工具"""def __init__(self):"""初始化MCP客戶端和通義千問API連接"""# MCP客戶端會話(用于與服務端通信,初始為None,連接后賦值)self.session: Optional[ClientSession] = None# 異步資源棧(用于自動管理后續創建的異步上下文,如連接、會話等,確保資源正確釋放)self.exit_stack = AsyncExitStack()self.tools = {} # 存儲可用工具的字典self.tool_descriptions = [] # LLM可用的工具描述async def connect_to_server(self, server_script_path: str):"""連接到MCP服務端Args:server_script_path: 服務端腳本路徑(.py或.js)"""# 驗證腳本類型is_python = server_script_path.endswith(".py")is_js = server_script_path.endswith(".js")if not (is_python or is_js):raise ValueError("服務端腳本必須是.py或.js文件")# 確定執行命令command = "python" if is_python else "node"server_params = StdioServerParameters(command=command, args=[server_script_path], env=None)# 建立與服務端的連接print(f"正在連接到服務端: {server_script_path}...")stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))self.stdio, self.write = stdio_transportself.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))await self.session.initialize()# 獲取并展示可用工具response = await self.session.list_tools()self.tools = {tool.name: tool for tool in response.tools}# 美化工具列表輸出print("\n? 已成功連接到服務端")print("🔧 可用工具:")for tool_name in self.tools:print(f" - {tool_name}")# 為LLM準備工具描述self.tool_descriptions = [{"name": tool.name,"parameters": (json.loads(tool.inputSchema)if isinstance(tool.inputSchema, str)else tool.inputSchema),"description": tool.description,}for tool in response.tools]async def call_tool(self, tool_name: str, parameters: dict) -> str:"""調用MCP服務端的工具Args:tool_name: 工具名稱parameters: 工具參數Returns:工具執行結果"""if tool_name not in self.tools:raise ValueError(f"未知工具: {tool_name}")# 調用前顯示進度print(f"🚀 正在調用工具: {tool_name}")print(f"🔧 參數: {json.dumps(parameters, ensure_ascii=False, indent=2)}")result = await self.session.call_tool(tool_name, parameters)return result.contentasync def query_llm(self, user_query: str) -> dict:"""調用通義千問API解析用戶查詢為工具調用指令Args:user_query: 用戶查詢內容Returns:解析后的工具調用指令字典"""print(f"🤖 正在分析查詢: {user_query}")api_url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"# 系統提示詞:指導模型使用工具system_prompt = f"""你是一個天氣信息查詢助手。用戶的問題將由以下工具回答:{json.dumps(self.tool_descriptions, indent=2, ensure_ascii=False)}請直接生成JSON格式的工具調用指令,不要包含其他解釋。示例:用戶輸入:"上海明天的天氣如何?" → {{"name": "get_forecast", "parameters": {{"city_adcode": "310000"}}}}""".strip()headers = {"Authorization": f"Bearer {DASHSCOPE_API_KEY}","Content-Type": "application/json",}payload = {"model": TONGYI_MODEL,"messages": [{"role": "system", "content": system_prompt},{"role": "user", "content": user_query},],"parameters": {"temperature": 0.1, # 極低隨機性"max_tokens": 128, # 限制生成長度},}# 發送請求并處理響應async with httpx.AsyncClient() as client:print("🌐 正在請求LLM服務...")response = await client.post(api_url, headers=headers, json=payload)response.raise_for_status()result = response.json()tool_call = (result.get("choices", [{}])[0].get("message", {}).get("content", "{}"))try:print("? 成功獲取工具調用指令")return json.loads(tool_call)except json.JSONDecodeError:print(f"?? 無效的工具調用格式: {tool_call}")return Noneasync def process_query(self, user_query: str) -> str:"""處理用戶查詢,調用LLM并執行工具Args:user_query: 用戶查詢內容Returns:最終響應結果"""# 獲取工具調用指令tool_call = await self.query_llm(user_query)if not tool_call or "name" not in tool_call or "parameters" not in tool_call:return "抱歉,無法理解您的查詢。"tool_name = tool_call["name"]parameters = tool_call["parameters"]try:return await self.call_tool(tool_name, parameters)except Exception as e:return f"調用工具失敗: {str(e)}"async def chat_loop(self):"""交互式聊天循環"""# 顯示歡迎信息print("\n" + "=" * 30)print("🌦? 天氣查詢助手")print("=" * 30)print("輸入示例:北京明天天氣如何?/ 北京今天天氣怎么樣?")print("輸入'quit'、'退出'或'bye'結束對話")while True:try:query = input("\n查詢: ").strip()if query.lower() in ["quit", "退出", "bye"]:print("👋 感謝使用,再見!")breakif not query:continueresponse = await self.process_query(query)# 美化結果輸出print("\n" + "-" * 30)print("📋 查詢結果:")print("-" * 30)print(response)print("-" * 30)except Exception as e:print(f"\n?? 發生錯誤: {str(e)}")async def cleanup(self):"""清理資源"""print("🧹 正在清理資源...")await self.exit_stack.aclose()print("? 資源清理完成")async def main():"""程序入口點"""if len(sys.argv) < 2:print("使用方法: python client.py <服務端腳本路徑>")sys.exit(1)print("🚀 天氣查詢助手啟動中...")client = MCPClient()try:await client.connect_to_server(sys.argv[1])await client.chat_loop()finally:await client.cleanup()if __name__ == "__main__":asyncio.run(main())
2.3 整合測試
本地運行 python client.py weather.py
提問:合肥明天天氣怎么樣?
輸入自然查詢內容 就會去調用相應的工具? 詢問今天會去調用get_realtime_weather 詢問明天預報類的則會去調用get_forecast
工具的調用流程
用戶輸入 → process_query → 調用query_llm獲取工具調用指令(如get_forecast)
通過 MCP 協議向服務端發送指令,服務端執行具體工具邏輯(如調用天氣 API)
服務端返回結果,客戶端解析并展示
總結:
本文介紹了如何利用Trae編輯器與MCP協議,快速配置并開發基于高德地圖API的定制化服務。通過具體的步驟指導,我們了解了從Trae環境搭建、MCP Server的配置到實際開發應用的全過程。此外,還探討了MCP Server和Client的構建方法,以及如何使用Python進行本地測試和集成。