前言
最近在搞 AI Agent 项目的时候,发现一个问题特别头疼:每个大模型(Claude、GPT、Gemini)的工具调用方式都不一样,写了一堆适配代码,换一个模型又得重写。
后来发现了 MCP(Model Context Protocol)这个协议,说白了就是 Anthropic 搞的一个标准,让 AI 模型和外部工具之间的通信有个统一规范。用了一圈下来,确实香。
今天就带大家从零用 Python 搭一个 MCP Server,实现一个能查天气、能搜网页的工具服务器。

什么是 MCP?
MCP 全称 Model Context Protocol,是 Anthropic 在 2024 年底开源的一个协议。你可以把它理解成 AI 世界的 USB-C ------ 不管你用什么模型,只要支持 MCP,就能无缝对接各种外部工具。
它的工作方式其实很简单:
- MCP Server:工具提供方,比如你写的天气查询服务、数据库查询服务
- MCP Client:AI 模型侧,负责调用这些工具
- 通信协议:基于 JSON-RPC 2.0,支持 stdio 和 HTTP 两种传输方式

环境准备
先装好需要的依赖:
bash
# 创建虚拟环境
python -m venv mcp-env
source mcp-env/bin/activate # Windows: mcp-env\Scripts\activate
# 安装 MCP SDK
pip install mcp httpx
注意:Python 版本需要 3.10+,低版本会报错。
第一步:创建基础 MCP Server
先搭一个最简单的骨架:
python
# server.py
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server
# 创建 MCP Server 实例
server = Server("my-weather-server")
@server.tool()
async def get_weather(city: str) -> str:
"""查询指定城市的天气信息"""
# 这里先用模拟数据,后面接真实 API
mock_data = {
"北京": "晴天,25°C,湿度 40%",
"上海": "多云,22°C,湿度 65%",
"深圳": "阵雨,28°C,湿度 80%",
}
return mock_data.get(city, f"暂无 {city} 的天气数据")
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
if __name__ == "__main__":
asyncio.run(main())
就这么几行代码,一个 MCP Server 就搞定了。核心就是 @server.tool() 这个装饰器,它会自动把函数注册成一个可被 AI 调用的工具。
第二步:接入真实天气 API
模拟数据没意思,我们来接一个真实的天气服务。这里用和风天气的免费 API:
python
# weather_api.py
import httpx
API_KEY = "你的API密钥" # 去 dev.qweather.com 注册拿
BASE_URL = "https://devapi.qweather.com/v7"
async def fetch_weather(city: str) -> dict:
"""调用和风天气 API 获取实时天气"""
async with httpx.AsyncClient() as client:
# 先查城市 ID
geo_url = "https://geoapi.qweather.com/v2/city/lookup"
geo_resp = await client.get(geo_url, params={
"location": city,
"key": API_KEY
})
geo_data = geo_resp.json()
if not geo_data.get("location"):
return {"error": f"找不到城市: {city}"}
city_id = geo_data["location"][0]["id"]
# 再查天气
weather_url = f"{BASE_URL}/weather/now"
weather_resp = await client.get(weather_url, params={
"location": city_id,
"key": API_KEY
})
return weather_resp.json()
然后在 server 里调用它:
python
@server.tool()
async def get_weather(city: str) -> str:
"""查询指定城市的实时天气"""
from weather_api import fetch_weather
data = await fetch_weather(city)
if "error" in data:
return data["error"]
now = data.get("now", {})
return f"{city}当前天气:{now.get('text', '未知')},温度 {now.get('temp', '?')}°C,体感 {now.get('feelsLike', '?')}°C,风向 {now.get('windDir', '无')}"
第三步:加一个网页搜索工具
一个工具太单调了,再来一个网页搜索功能:
python
@server.tool()
async def search_web(query: str, num_results: int = 5) -> str:
"""搜索网页内容,返回标题和摘要"""
async with httpx.AsyncClient() as client:
# 用 DuckDuckGo 的即时搜索(国内可能需要代理)
resp = await client.get(
"https://api.duckduckgo.com/",
params={"q": query, "format": "json", "no_redirect": 1},
timeout=10.0
)
data = resp.json()
results = []
if data.get("Abstract"):
results.append(f"摘要:{data['Abstract']}")
for topic in data.get("RelatedTopics", [])[:num_results]:
if "Text" in topic:
results.append(f"- {topic['Text']}")
return "\n".join(results) if results else "未找到相关结果"
第四步:测试你的 MCP Server
写好了服务,怎么测试呢?最简单的方式是用 Claude Desktop 连接它。
编辑 Claude Desktop 的配置文件:
json
{
"mcpServers": {
"my-weather-server": {
"command": "python",
"args": ["/path/to/server.py"]
}
}
}
重启 Claude Desktop,你就能在对话里直接问天气了。比如输入"北京今天天气怎么样",Claude 会自动调用你写的 get_weather 工具。

常见问题 Q&A
Q1:报错 ModuleNotFoundError: No module named 'mcp'
确认你激活了虚拟环境,然后重新 pip install mcp。如果还是不行,试试 pip install mcp[cli]。
Q2:Claude Desktop 连不上 Server
检查配置文件路径是否正确。macOS 在 ~/Library/Application Support/Claude/claude_desktop_config.json,Windows 在 %APPDATA%\Claude\claude_desktop_config.json。
Q3:工具注册了但 AI 不调用
确保函数的 docstring 写清楚了,AI 靠它理解工具的用途。描述越精确,调用越准确。
Q4:想支持 HTTP 传输而不是 stdio?
MCP 也支持 SSE(Server-Sent Events)传输,适合远程部署。把 stdio_server 换成 sse_server 就行,不过配置会复杂一些。
总结
MCP 这个协议确实解决了 AI 工具调用碎片化的问题。几行 Python 代码就能把任何服务包装成 AI 可调用的工具,而且换模型不用改代码。
目前 MCP 生态还在早期,但已经有大量社区贡献的 Server(数据库、文件系统、GitHub、Slack 等等)。如果你在做 AI Agent 相关的项目,强烈建议现在就开始用起来。
下一步可以看看:
- MCP 官方文档:spec.modelcontextprotocol.io
- 社区 Server 列表:github.com/modelcontextprotocol/servers
- 自己动手写一个连接你公司内部系统的 MCP Server
有问题欢迎评论区交流 👇