用最简单的方式教你用Python搭建第一个MCP服务器(附详细代码示例)

6,446 阅读3分钟

下面为你提供一份基于最新官方MCP Python SDK的完整、更新且实用的教程,涵盖环境搭建、服务器实现、客户端调用及示例扩展,帮助你快速上手MCP服务开发。

MCP完整教程(基于官方Python SDK)

1. 环境准备与安装

  • Python版本:建议3.10及以上
  • 安装MCP SDK及依赖

使用pip安装:

pip install "mcp[cli]" httpx python-dotenv uv
  • mcp[cli]:MCP核心SDK及命令行工具
  • httpx:异步HTTP请求库,用于调用第三方API
  • python-dotenv:环境变量管理
  • uv:推荐的Python项目管理工具(可选)

2. MCP服务器实现

2.1 创建一个简单的MCP服务器

# server.py
import asyncio
from mcp.server.fastmcp import FastMCP
from mcp.types import TextContent

# 创建FastMCP服务器实例,名称为"My MCP Server"
mcp = FastMCP("My MCP Server")

# 注册一个简单的工具,功能是接收字符串并返回处理后的文本
@mcp.tool()
async def my_tool(input_text: str) -> TextContent:
    return TextContent(type="text", text=f"Processed: {input_text}")

# 启动服务器,监听stdio(标准输入输出)通信
async def main():
    from mcp.server.stdio import stdio_server
    async with stdio_server() as (read_stream, write_stream):
        await mcp.run(read_stream, write_stream, mcp.create_initialization_options())

if __name__ == "__main__":
    asyncio.run(main())
  • 该服务器使用标准输入输出通信(stdio),适合本地调试和客户端启动服务器进程的场景。

2.2 运行服务器

python server.py

3. MCP客户端调用示例

# client.py
import asyncio
from mcp.client.stdio import stdio_client
from mcp import ClientSession

async def main():
    # 配置启动服务器的命令和参数
    server_params = {
        "command": "python",
        "args": ["server.py"],
    }

    # 启动服务器进程并建立通信通道
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 调用工具"my_tool",传入字符串参数
            result = await session.call_tool("my_tool", "Hello, MCP!")

            # result是Content对象列表,遍历打印文本内容
            for content in result:
                print(content.text)

if __name__ == "__main__":
    asyncio.run(main())

运行:

python client.py

输出:

Processed: Hello, MCP!

4. 进阶示例:多工具服务器

下面示例展示如何定义多个工具,包括异步调用第三方API的天气查询工具和计算工具。

# advanced_server.py
import asyncio
import os
import httpx
from mcp.server.fastmcp import FastMCP
from mcp.types import TextContent
from dotenv import load_dotenv

load_dotenv()  # 加载.env中的环境变量
API_KEY = os.getenv("OPENWEATHER_API_KEY")

mcp = FastMCP("Advanced MCP Server")

@mcp.tool()
async def add_numbers(a: int, b: int) -> TextContent:
    return TextContent(type="text", text=f"结果: {a + b}")

@mcp.tool()
async def get_weather(city: str) -> TextContent:
    url = "https://api.openweathermap.org/data/2.5/weather"
    params = {"q": city, "appid": API_KEY, "units": "metric"}
    async with httpx.AsyncClient() as client:
        resp = await client.get(url, params=params)
        data = resp.json()
        weather_desc = data["weather"][0]["description"]
        temp = data["main"]["temp"]
        return TextContent(type="text", text=f"{city}天气:{weather_desc},温度:{temp}°C")

async def main():
    from mcp.server.stdio import stdio_server
    async with stdio_server() as (read_stream, write_stream):
        await mcp.run(read_stream, write_stream, mcp.create_initialization_options())

if __name__ == "__main__":
    asyncio.run(main())
  • 需要在项目根目录创建.env文件,写入:
OPENWEATHER_API_KEY=你的OpenWeather API密钥

5. 客户端调用多工具示例

# advanced_client.py
import asyncio
from mcp.client.stdio import stdio_client
from mcp import ClientSession

async def main():
    server_params = {
        "command": "python",
        "args": ["advanced_server.py"],
    }

    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 调用加法工具
            res_add = await session.call_tool("add_numbers", {"a": 10, "b": 20})
            print("加法工具返回:", res_add[0].text)

            # 调用天气查询工具
            res_weather = await session.call_tool("get_weather", "Beijing")
            print("天气工具返回:", res_weather[0].text)

if __name__ == "__main__":
    asyncio.run(main())

运行:

python advanced_client.py

示例输出:

加法工具返回: 结果: 30
天气工具返回: Beijing天气:clear sky,温度:18°C

6. MCP服务器常用功能

  • 资源(Resource) :暴露静态或动态数据,类似RESTful GET接口
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    return f"Hello, {name}!"
  • 提示(Prompt) :定义结构化提示模板,提升LLM响应质量
@mcp.prompt()
def greet_prompt(name: str):
    return [
        {"role": "user", "content": f"请向{name}打招呼。"}
    ]

7. 运行总结

  • 启动服务器:
python server.py
  • 另开终端运行客户端:
python client.py
  • 服务器和客户端通过标准输入输出通信,客户端负责启动服务器进程。

8. 安全与性能建议

  • 安全

    • 生产环境建议使用HTTPS代理MCP服务器,保障传输安全。
    • 实施访问控制和身份认证,限制调用权限。
    • 记录访问日志,便于审计。
  • 性能

    • 工具函数尽量异步实现,提升并发处理能力。
    • 对频繁访问的数据使用缓存策略。
    • 结合负载均衡和多实例部署,提升可用性。