Python-MCPServer開發

Python-MCPServer開發

使用FastMCP開發【SSE模式的MCPServer】,熟悉【McpServer編碼過程】+【McpServer調試方法】


1-核心知識點

  • 1-熟悉【SSE模式的MCPServer】開發
  • 2-熟悉【stdio模式的MCPServer】開發
  • 3-熟悉【啟動MCPServer】的三種方式
    • 3.1-直接啟動:python mcp_server.py
    • 3.2-代碼中uv使用:subprocess.Popen([“uv”, “run”, server_file])
    • 3.3-使用mcpInspector網頁:mcp dev mcp_server.py
  • 4-熟悉【Agent增強外部能力】的兩種方式
    • 4.1-調用tool:Agent(name=“Assistant”, instructions=“用中文回復”, tools=[get_weather])
    • 4.2-調用tool:Agent(name=“Assistant”, instructions=“用中文回復”, mcp_servers=[mcp_server])

2-思路整理

1-McpServer須知

  • 1-MCPServer已經可以對外提供服務了,這個不同于傳統的API,雖然也運行在特殊端口了,但是不能通用postman進行調用

  • 2-那有人質疑這個說法了,為什么使用mcpInspector網頁調試就可以連通?

    • 可以理解為:mcpInspector聯通的是Agent,只是查看Agent上有哪些Resources/Prompts/Tools…并且可以通過Agent和McpServer進行交互,而不是Rest請求
  • 3-MCPServer_SSE和MCPServer_stdio如何進行快速區分:

    • 1-stdio-適用于同一臺機器上(進程間通訊,通訊不經過HTTP協議,超級快)->要求:你要有可運行文件【Python文件】或者【Java的Jar包】
    • 2-SSE適用于所有環境,通過IP進行HTTP通訊->基本沒有要求,無腦就全部使用這種
  • 4-再次澄清:MCPServer_SSE雖然可以部署,有大網IP或者域名,但是依然不能通用postman進行調用

    • post調用的接口->要求是@Controller標記或者FastAPI開發的API接口
    • agent調用的接口->要求是@mcp.tool標記(可能對外就不是API接口)
    • 總結:可以理解@mcp.tool標記后是一種特殊的API,只能被Agent調用
  • 5-SSE和stdio在代碼上有什么區別?

    • 1-McpServer的編寫上只有一個區別【mcp.run(transport=“sse/stdio”)】
    • 2-Agent在連接的時候使用【McpServerstdio】和【McpServerSSE】進行McpServer構建
    • 3-【mcp.run(transport=“sse”)】后,服務【可以被任何遠程】的Agent進行訪問(此時先不談鑒權的問題)
    • 4-【mcp.run(transport=“stdio”)】后,服務【只可以被本地進程】的Agent進行訪問(此時先不談鑒權的問題)


2-McpServer核心思路

1-【mcp.run(transport=“sse”)】后,服務【可以被任何遠程】的Agent進行訪問(此時先不談鑒權的問題)

2-【mcp.run(transport=“stdio”)】后,服務【只可以被本地進程】的Agent進行訪問(此時先不談鑒權的問題)

  • 1-編寫傳統的Service業務代碼
  • 2-在Service業務代碼頭上添加@tool裝飾器,即可實現FastMCP的Tool功能
  • 3-在Service業務代碼頭上添加@mcp.tool()裝飾器,即可實現FastMCP的McpServer功能
  • 4-主程序指定運行方法-stdio進程啟動(此時MCPServer已經可以對外提供服務了,這個不同于傳統的API,雖然也運行在特殊端口了,但是不能通用postman進行調用)
    • 1-直接啟動:python mcp_server.py
    • 2-代碼中uv使用:subprocess.Popen([“uv”, “run”, server_file])
    • 3-使用mcpInspector網頁:mcp dev mcp_server.py
  • 5-Agent調試McpServer
    • 1-指定LLM
    • 2-指定Agent(McpServerList+角色定位)
    • 3-Runner.run(Agent+LLM+問題)交互


3-McpServer和McpClient關系

  • 1-McpClient只是一個概念,在使用Python進行開發的時候根本就沒有任何關于McpClient的類
  • 2-McpClient就是McpServer連接過程的過程

4-Agent+LLM+McpServers

  • 1-LLM和Agent最初是獨立創建的,兩者之間沒有關系

    • LLM指明用哪家大模型
    • Agent指明用哪些McpServerList
  • 2-LLM和Agent是通過Runner.run(Agent+LLM+問題)進行關聯

  • 3-Agent+LLM如何進行交互(要不要進行最后的總結)是通用(result.output獲取的時候進行邏輯編排的)

    • 如果我們自己做MCP編排,可能就是在這個地方進行核心邏輯編寫


5-MCPServer核心代碼

  • 1-在Service業務代碼頭上添加@tool裝飾器,即可實現FastMCP的Tool功能
# 假設 mcp 已經正確導入
try:from mcp import tool
except ImportError:# 如果 mcp 未找到,模擬一個 tool 裝飾器def tool(func):return func# 在 Service 業務代碼頭上添加 @tool 裝飾器
@tool
async def get_city_list(self) -> list:"""獲取所有的城市信息。返回:str: 所有的城市信息列表"""logging.info(f"獲取所有的城市信息")city_list = []for city in self.CITY_WEATHER_DATA:city_list.append(city)return city_list
  • 2-在Service業務代碼頭上添加@mcp.tool()裝飾器,即可實現FastMCP的McpServer功能
from mcp.server.fastmcp import FastMCPfrom city_01_service import CityDataServer# 1-初始化 MCP 服務器
mcp = FastMCP("CityDataServer")# 2-初始化城市信息服務器(業務代碼+@tool裝飾器)
city_server = CityDataServer()# 3-在 Service 業務代碼頭上添加@mcp.tool()裝飾器
@mcp.tool()
# 獲取所有城市列表
async def get_city_list():"""獲取所有城市列表。返回:str: 所有城市列表"""city_list = await city_server.get_city_list()return city_list# 4-主程序指定運行方法-stdio/sse進程啟動
if __name__ == "__main__":mcp.run(transport='stdio/sse')

3-參考網址

  • MCP官網的開發樣例:https://github.com/openai/openai-agents-python/blob/main/examples/mcp/sse_example/main.py
  • 個人代碼實現倉庫:https://gitee.com/enzoism/python_mcp_client_server

4-上手實操

1-空工程初始化環境

mkdir my_project
cd my_project
python -m venv .venv

2-激活環境

# Windows
source .venv/Scripts/activate# Mac
source .venv/bin/activate

3-添加依賴

對應的依賴是在激活的環境中

# uv用于后續MCP Inspector的連接
pip install uv httpx mcp

4-ToolFunction核心代碼

import asyncio
import osfrom agents import (Agent,RunConfig,Runner,function_tool,set_tracing_disabled,
)
from dotenv import load_dotenvfrom model_providers.deepseek import DeepSeekModelProvider# 1-環境變量加載相關
load_dotenv()
BASE_URL = os.getenv("BASE_URL") or ""
API_KEY = os.getenv("API_KEY") or ""
MODEL_NAME = os.getenv("MODEL_NAME") or ""
if not BASE_URL or not API_KEY or not MODEL_NAME:raise ValueError("請通過環境變量或代碼設置EXAMPLE_BASE_URL、EXAMPLE_API_KEY、EXAMPLE_MODEL_NAME。")# 2-跳過大模型的鏈路追蹤
set_tracing_disabled(disabled=True)"""
本例使用自定義提供程序調用Runner.run()的部分,并直接調用OpenAI進行其他操作。
步驟:
1. 【實例化LLM】ModelProvider對象-并構建RunConfig
2. 【實例化Agent】創建一個Agent。
3. 在調用Runner.run()結合【LLM】+【Agent】進行問答
注意,在本例中,我們假設您沒有從platform.openai.com獲取API密鑰,因此禁用了跟蹤。
如果您有API密鑰,您可以選擇設置`OPENAI_API_KEY`環境變量或調用set_tracing_export_api_key()來設置跟蹤特定的密鑰。
"""# 3-定義一個工具函數
@function_tool
def init_weather_tool_function(city: str):print(f"[debug] getting weather for {city}")return f"The weather in {city} is sunny."async def run_mcp_tool_function():# 1-【實例化LLM】ModelProvider對象-并構建RunConfigrun_config = RunConfig(model_provider=DeepSeekModelProvider(BASE_URL, API_KEY, MODEL_NAME))# 2-【實例化Agent】創建一個Agentagent = Agent(name="Assistant",instructions="使用工具回答大模型的問題",tools=[init_weather_tool_function])# 3.1-調用工具回答問題message = "杭州的天氣怎么樣?"print(f"\n\n【大模型請求案例】-> {message}")result = await Runner.run(starting_agent=agent, input=message, run_config=run_config)print(result.final_output)# 3.2-獲取Agent對話的結果-沒有配置RunConfig使用的是OpenAI的默認模型# result = await Runner.run(#     agent,#     "給我講一個笑話吧!",# )# print(result.final_output)if __name__ == "__main__":asyncio.run(run_mcp_tool_function())

5-McpServer核心代碼

1-【mcp.run(transport=“sse”)】后,服務【可以被任何遠程】的Agent進行訪問(此時先不談鑒權的問題)

2-【mcp.run(transport=“stdio”)】后,服務【只可以被本地進程】的Agent進行訪問(此時先不談鑒權的問題)

import random
import randomfrom mcp.server.fastmcp import FastMCP# Create server
mcp = FastMCP("Echo Server")# 1-MCP工具1-數字加和
@mcp.tool()
def add(a: int, b: int) -> int:"""Add two numbers"""print(f"[MCP工具1-數字加和] add({a}, {b})")return a + b# 2-MCP工具2-隨機選定的字符
@mcp.tool()
def get_secret_word() -> str:"""獲取隨機單詞"""print("[MCP工具2-隨機選定的字符] get_secret_word()")return random.choice(["apple", "banana", "cherry"])if __name__ == "__main__":mcp.run(transport="sse/stdio")

6-Agent調試McpServer

hitokoto_02_api.py:API直接調用service對外暴露rest請求

import asyncio
import osfrom agents import Agent, Runner, RunConfig, set_tracing_disabled
from agents.mcp import MCPServer, MCPServerStdio
from agents.model_settings import ModelSettings
from dotenv import load_dotenvfrom model_providers.deepseek import DeepSeekModelProvider# 1-環境變量加載相關
load_dotenv()
BASE_URL = os.getenv("BASE_URL") or ""
API_KEY = os.getenv("API_KEY") or ""
MODEL_NAME = os.getenv("MODEL_NAME") or ""
if not BASE_URL or not API_KEY or not MODEL_NAME:raise ValueError("請通過環境變量或代碼設置EXAMPLE_BASE_URL、EXAMPLE_API_KEY、EXAMPLE_MODEL_NAME。")# 2-跳過大模型的鏈路追蹤
set_tracing_disabled(disabled=True)"""
本例使用自定義提供程序調用Runner.run()的部分,并直接調用OpenAI進行其他操作。
步驟:
1. 【實例化LLM】ModelProvider對象-并構建RunConfig
2. 【實例化Agent】創建一個Agent。
3. 在調用Runner.run()結合【LLM】+【Agent】進行問答
- 1)直接和大模型對話
- 2)調用MCPServer_SSE模式-[MCP工具1-數字加和]
- 3)調用MCPServer_SSE模式-[MCP工具2-隨機選定的字符]
"""async def run_mcp_server(mcp_server: MCPServer):# 1-【實例化LLM】ModelProvider對象-并構建RunConfigrun_config = RunConfig(model_provider=DeepSeekModelProvider(BASE_URL, API_KEY, MODEL_NAME))# 2-【實例化Agent】創建一個Agentagent = Agent(name="Assistant",instructions="使用工具回答大模型的問題",mcp_servers=[mcp_server],model_settings=ModelSettings(tool_choice="required"),)# 3.1-直接和大模型對話message = "給我講一個笑話吧!"print(f"\n\n【大模型請求案例】-> {message}")result = await Runner.run(starting_agent=agent, input=message, run_config=run_config)print(result.final_output)# 3.2-調用MCPServer_SSE模式-[MCP工具1-數字加和]message = "What's the weather in Tokyo?"print(f"\n\n【大模型請求案例】-> {message}")result = await Runner.run(starting_agent=agent, input=message, run_config=run_config)print(result.final_output)# 3.3-調用MCPServer_SSE模式-[MCP工具2-隨機選定的字符]message = "What's the secret word?"print(f"\n\n【大模型請求案例】-> {message}")result = await Runner.run(starting_agent=agent, input=message, run_config=run_config)print(result.final_output)async def init_mcp_server() -> MCPServerStdio:# 1-創建 MCP 服務器連接實例,但不立即運行(python mcp_server_xx.py)this_dir = os.path.dirname(os.path.abspath(__file__))python_exec_path = os.path.join(this_dir, ".venv/Scripts/python.exe")mcp_server_stdio_file = os.path.join(this_dir, "mcp05_stdio.py")weather_server = MCPServerStdio(name="weather",params={"command": python_exec_path,"args": [mcp_server_stdio_file],"env": {},},# 緩存工具列表以減少延遲,不需要每次連接時重新獲取工具列表cache_tools_list=True)# 2-手動連接到MCP服務器print("正在連接到MCP服務器...")await weather_server.connect()print("MCP服務器連接成功!")# 3-等待服務器連接成功并獲取MCP服務可用工具列表tools = await weather_server.list_tools()print("\n可用工具列表: ")for tool in tools:print(f" - {tool.name}: {tool.description}")return weather_serverif __name__ == "__main__":# 1-獲取McpServerserver = asyncio.run(init_mcp_server())# 2-運行McpServerasyncio.run(run_mcp_server(server))

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78960.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78960.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78960.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

高級項目管理

在信息系統項目管理工作中,組織管理者和項目管理者,有時還會面臨多項目的管理,或組織級的項目管理、項目的量化管理等課題。 其中,項目集管理、項目組合管理和組織級項目管理,為多項目管理和組織級管理提供有效指導&a…

tarjan縮點+強聯通分量

【模板】縮點https://www.luogu.com.cn/problem/P3387 首先我們要理解這道題為什么要用縮點 題目說的是有向圖,如果無環的話就可以用DP來解決了 由于可以走重復的點,所以一個環上的點可以看成是一個點,它的點權就等于該環上所有點的點權之…

OSCP:獲取全交互式 Windows 反向 Shell

簡介 在本文中,我們將探討獲取完全交互式 Windows 反向 Shell 的各種方法,從利用內置工具到采用先進技術以獲得更好的控制和功能。 通過 Invoke-ConPtyShell 我獲取完全交互式 Windows 反向 Shell 的首選方法是通過 Invoke-ConPtyShell 腳本。當 Wind…

免費超好用的電腦操控局域網內的手機(多臺,無線)

使用 第一步 解壓QtScrcpy壓縮包,并運行QtScrcpy.exe 第二步 2.1 手機開啟開發者模式(設置>關于本機>版本信息>連點10下“版本號”) 2.2 開啟 USB調試 和 無線調試(設置>開發者選項> USB調試 無線調試&#xf…

Go語言內存管理

本章節,就來學習一下go語言的內存模型,看一下內存的分配,存儲都是如何實現的,與此同時,在正式開始今天的主題之前,首先先來學習操作系統基于這一方面的內容,來看看是如何管理內存的吧 本章及節…

【docker】啟動臨時MongoDB容器、掛載數據卷運行數據庫服務,并通過備份文件恢復MongoDB數據庫備份數據

?啟動臨時 MongoDB 容器、掛載數據卷運行數據庫服務,并通過備份文件恢復數據 1.命令分解與功能說明1.1.啟動一個臨時 MongoDB 容器?,并進入交互式終端(1)執行命令(2)實現功能?(3)…

【最新 MCP 戰神手冊 08】工具使用詳解:實現 AI 行動

文章目錄 1. 開始啦!2. 第一部分:設計高效且安全的工具3. 第二部分:定義工具藍圖——參數、輸出與約束條件4. 第三部分:彌合差距:LLM 兼容性(函數調用)5. 第四部分:實施與測試的最佳實踐1. 開始啦! 在前幾章中,我們將工具介紹為 AI 模型在 MCP 客戶端引導下向 MCP 服…

介紹 IntelliJ IDEA 快捷鍵操作

IntelliJ IDEA 快捷鍵操作 1. 編輯與導航2. 查找與替換3. 調試與運行4. 導航與視圖5. 重構與生成6. 高級快捷鍵(提高效率)注意事項 IntelliJ IDEA 是一款功能強大的集成開發環境,掌握其常用快捷鍵可以顯著提升開發效率。但是有些小伙伴并不清…

Javascript 中作用域的理解?

一、作用域的類型 1. 全局作用域(公司大門外) 范圍:整個 JavaScript 文件變量:像貼在公告欄上的信息,所有人可見例子:const companyName "阿里"; // 全局變量,任何地方都能訪問 fu…

Leetcode刷題記錄22——滑動窗口最大值

題源:https://leetcode.cn/problems/sliding-window-maximum/description/?envTypestudy-plan-v2&envIdtop-100-liked 題目描述: 思路一: 暴力遍歷法,通過一個長度為k的滑動窗口遍歷nums,將其中最大的數依次記…

Apache Flink的架構設計與運行流程說明

在大數據領域,實時計算的重要性隨著業務需求的爆發式增長愈發凸顯。從電商的實時銷量監控到金融的高頻交易風控,從物聯網設備的實時告警到社交平臺的熱點追蹤,企業對“秒級甚至毫秒級”數據處理能力的需求已成為剛需。在眾多實時計算框架中&a…

經典算法 最長單調遞增子序列

最長單調遞增子序列 問題描述 找出由n個數組成的序列的最長單調遞增子序列。 示例輸入 9 2 1 5 3 6 4 8 9 7示例輸出 5示例輸入 6 5 6 7 1 2 8示例輸出 4c代碼(動態規劃 O(n^2)) #include<bits/stdc.h>using namespace std;int main() {int n, ans 0;cin >&g…

【語法】C++繼承中遇到的問題及解決方法

目錄 1.子類構造函數中初始化父類成員 2.子類顯式調用父類的析構函數 第一種說法&#xff1a;重定義 反駁&#xff1a; 第二種說法&#xff1a;operator~ 3.因編譯器版本過低而出現錯誤 貼主在學習C的繼承時&#xff0c;遇到了很多問題&#xff0c;覺得很變態&#xff0c…

前綴和 后綴和 --- 尋找數組的中心下標

題目鏈接 尋找數組的中心下標 給你一個整數數組 nums &#xff0c;請計算數組的 中心下標 。 數組 中心下標 是數組的一個下標&#xff0c;其左側所有元素相加的和等于右側所有元素相加的和。 如果中心下標位于數組最左端&#xff0c;那么左側數之和視為 0 &#xff0c;因為…

NVIDIA --- 端到端自動駕駛

前言 參加了NVIDIA 高級輔助駕駛開發者實驗室的活動&#xff0c;本次活動基于 NVIDIA 汽車行業的端到端解決方案——DRIVE AGX? 平臺&#xff0c;實現高級別智能和安全性的軟硬件開發工具和 AV 基礎設施。并且NVIDIA自動駕駛實驗室推出了一系列自動駕駛算法最新的前沿研究視頻…

SQL實戰:03之SQL中的遞歸查詢

文章目錄 概述SQL 中的遞歸實現題目一:分析組織層級題解題目二:樹節點求解題解步驟一&#xff1a;通過遞歸查詢出每個節點的上級節點和下級節點分布步驟二&#xff1a;分組統計 概述 最近刷題時遇到了一道需要根據組織層級來統計各個層級的一些數據&#xff0c;當時碰到時的第…

MySQL 語法與基礎完全指南

MySQL 是最流行的開源關系型數據庫管理系統之一&#xff0c;廣泛應用于 Web 應用程序開發。本文將全面介紹 MySQL 的基礎知識和完整語法結構。 一、MySQL 基礎概念 1. 數據庫基本術語 數據庫(Database): 存儲數據的集合 表(Table): 數據以表格形式組織 列(Column): 表中的一…

【Sqlalchemy Model轉換成Pydantic Model示例】

【Sqlalchemy Model轉換成Pydantic Model示例】 由于Sqlalchemy和Pydantic的模型字段類型可能有差異, 所以需要一個通用的裝換類 def sqlalchemy_to_pydantic_v2(sqlalchemy_model, pydantic_model):"""通用函數&#xff0c;將 SQLAlchemy 模型實例轉換為 Pyd…

2025年歐洲西南部大停電

2025年4月28日&#xff0c;歐洲西南部出現大規模停電&#xff0c;西班牙、葡萄牙和法國南部均受到影響。有報道指出停電可能與 歐洲電網出現問題有關&#xff0c;但最終原因尚未確定。由于停電&#xff0c;上述地區的交通和通信服務均受到嚴重影響&#xff0c;交通信號燈停止工…

Java EE初階——計算機是如何工作的

1. cpu 馮諾依曼體系&#xff08;Von Neumann Architecture&#xff09; ? CPU 中央處理器: 進?算術運算和邏輯判斷. ? 存儲器: 分為外存和內存, ?于存儲數據(使??進制?式存儲) ? 輸?設備: ??給計算機發號施令的設備. ? 輸出設備: 計算機個??匯報結果的設…