Model Context Protocol 是一個開放標準,它的目標是給 LLM 一種干凈、統一的方式去發現和調用外部工具。不用再寫自定義解析、不用再維護脆弱的膠水代碼,就是一個好用的協議。
大多數 MCP 教程上來就講 JSON-RPC 規范、傳輸層協議,搞得很復雜。其實用 MCP 不需要理解協議內部構造就像寫 Web 應用不需要去讀 HTTP 規范一樣。
真正需要掌握的東西就三個概念,花 15 分鐘就夠了。
![]()
三個核心概念
MCP 的核心就三樣東西:
Server:對外暴露工具的服務端,本質上是一個 Python 腳本,聲明"這些函數可以被 LLM 調用",跑起來之后就在監聽請求。
Tool:希望 LLM 使用的函數,可以是任何東西:查天氣、查數據庫、發郵件。這跟寫普通 Python 函數沒什么區別,加個裝飾器剩下的交給 MCP。
Client:連接 Server 并調用工具的客戶端。生產環境里一般就是 LLM 應用本身。測試階段可以用 FastMCP 自帶的客戶端,開箱即用。
Server 暴露工具,Client 調用工具。就這么簡單。
傳輸方式、JSON-RPC、能力協商這些都是實現細節,上生產之前不用管。
步驟 1:安裝 FastMCP
FastMCP 是讓 MCP 用起來簡單的 Python 框架。裝一下就行,不需要任何配置。
pip install fastmcp
本教程不需要虛擬環境,生產環境建議還是用一個。
步驟 2:創建 Server
新建一個 my_server.py 文件:
from fastmcp import FastMCP
# Initialize the server with a name
mcp = FastMCP("my-first-server")
# Define a tool using the @mcp.tool decorator
@mcp.tool
def get_weather(city: str) -> dict:
"""Get the current weather for a city."""
# In production, you'd call a real weather API
# For now, we'll return mock data
weather_data = {
"new york": {"temp": 72, "condition": "sunny"},
"london": {"temp": 59, "condition": "cloudy"},
"tokyo": {"temp": 68, "condition": "rainy"},
}
city_lower = city.lower()
if city_lower in weather_data:
return {"city": city, **weather_data[city_lower]}
else:
return {"city": city, "temp": 70, "condition": "unknown"}
# Run the server
if __name__ == "__main__":
mcp.run(transport="stdio")
FastMCP("my-first-server") 創建一個帶名稱的服務器實例。@mcp.tool 裝飾器把普通函數注冊為 MCP 工具。函數的 docstring 會變成工具描述——LLM 靠這個來判斷什么時候該調用它。類型提示(city: str、-> dict)告訴 MCP 輸入輸出的類型。transport="stdio" 表示通過標準輸入輸出通信,本地測試夠用了。
整個 Server 就這些,實際代碼 15 行。
步驟 3:寫個 Client 測試一下
新建 test_client.py:
import asyncio
from fastmcp import Client
async def main():
# Point the client at your server file
client = Client("my_server.py")
# Connect to the server
async with client:
# List available tools
tools = await client.list_tools()
print("Available tools:")
for tool in tools:
print(f" - {tool.name}: {tool.description}")
print("\n" + "="*50 + "\n")
# Call the weather tool
result = await client.call_tool(
"get_weather",
{"city": "Tokyo"}
)
print(f"Weather result: {result}")
if __name__ == "__main__":
asyncio.run(main())
Client("my_server.py") 指定要連接的 Server 文件;async with client: 自動管理連接生命周期;list_tools() 負責動態發現可用工具,這是 MCP 的核心能力之一;call_tool("get_weather", {"city": "Tokyo"}) 帶參數調用具體工具。
步驟 4:跑起來
終端里執行:
python test_client.py
輸出應該是這樣的:
Available tools:
- get_weather: Get the current weather for a city.
==================================================Weather result: {'city': 'Tokyo', 'temp': 68, 'condition': 'rainy'}
到這里就完成了。一個 MCP Server 搭好了Client 也成功調用了它。
步驟 5:增加更多工具
MCP 真正好用的地方在于擴展成本極低,再往 Server 里再加兩個工具:
from fastmcp import FastMCP
from datetime import datetime
mcp = FastMCP("my-first-server")
@mcp.tool
def get_weather(city: str) -> dict:
"""Get the current weather for a city."""
weather_data = {
"new york": {"temp": 72, "condition": "sunny"},
"london": {"temp": 59, "condition": "cloudy"},
"tokyo": {"temp": 68, "condition": "rainy"},
}
city_lower = city.lower()
if city_lower in weather_data:
return {"city": city, **weather_data[city_lower]}
return {"city": city, "temp": 70, "condition": "unknown"}
@mcp.tool
def get_time(timezone: str = "UTC") -> str:
"""Get the current time in a specified timezone."""
# Simplified - in production use pytz or zoneinfo
return f"Current time ({timezone}): {datetime.now().strftime('%H:%M:%S')}"
@mcp.tool
def calculate(expression: str) -> dict:
"""Safely evaluate a mathematical expression."""
try:
# Only allow safe math operations
allowed_chars = set("0123456789+-*/.() ")
if not all(c in allowed_chars for c in expression):
return {"error": "Invalid characters in expression"}
result = eval(expression) # Safe because we validated input
return {"expression": expression, "result": result}
except Exception as e:
return {"error": str(e)}
if __name__ == "__main__":
mcp.run(transport="stdio")
再跑一次測試客戶端,三個工具全部自動發現:
Available tools:
- get_weather: Get the current weather for a city.
- get_time: Get the current time in a specified timezone.
- calculate: Safely evaluate a mathematical expression.
不需要改配置,不需要寫路由。加了工具就直接可用。
最后:接入 LLM
前面寫的 Client 是測試用的。生產環境里,LLM 框架本身充當 Client 角色。概念上大概是這樣:
![]()
How MCP connects your LLM to external tools: the framework calls the client, which discovers and invokes tools from your server.
Server 端的代碼完全不用動,這正是 MCP 的價值所在——工具寫一次,任何兼容 MCP 的客戶端都能用。
生產部署時需要把傳輸方式從 stdio 換成 http:
if __name__ == "__main__":
mcp.run(transport="http", host="0.0.0.0", port=8000)
這樣 MCP Server 就以 HTTP 端點的形式對外暴露,遠程客戶端可以直接連接。
總結
現在你手頭已經有一個能跑的 MCP Server 了,前后也就 15 分鐘。下一步就是把它接到實際的 LLM 上,做點真正有用的東西出來。
https://avoid.overfit.cn/post/c9314c34543a4ed1a1bb15b92d1c6ca2
by Paolo Perrone
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.