MCP协议实战:用Python从零搭建一个AI Agent工具服务器(保姆级教程)

前言

最近在搞 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 相关的项目,强烈建议现在就开始用起来。

下一步可以看看:

有问题欢迎评论区交流 👇

相关推荐
AI袋鼠帝1 小时前
文本/图片/视频模型API全免费!这次真遇到赛博活菩萨了
人工智能
万能的知了1 小时前
服务器托管 vs 云主机 vs 裸金属:一个决策故事
运维·服务器·云计算
winlife_2 小时前
在 Unity 里用 AI 做游戏:funplay-unity-mcp 从安装到第一次让 AI 改场景
人工智能·游戏·unity·ai编程·claude·mcp
岁月宁静2 小时前
驾驭 AI 这匹野马:深入解析智能体 Harness 工程
vue.js·python
虫无涯2 小时前
大模型工程实现全解:5大落地路径从入门到实战
人工智能
cxr8282 小时前
高分子复合材料 AI 逆向设计合——工业交付、系统自重构与范式演进
人工智能·重构·材料逆向设计合成
冬奇Lab2 小时前
每日一个开源项目(第119篇):Darwin Skill - 受 Karpathy 启发,让 AI 技能无限进化的“棘轮”系统
人工智能·开源
Black蜡笔小新2 小时前
企业私有化AI训练推理一体工作站DLTM重构企业AI模型训练的全流程模式
人工智能·机器学习·重构