FastMCP 客户端服务器通信示例:从入门到实战(STDIO 传输)

引言

在现代分布式系统和AI应用中,模型上下文协议(MCP)扮演着重要角色,它负责协调客户端与服务器之间的通信,尤其是在需要频繁交互的场景中。本文将介绍如何使用FastMCP库快速实现客户端与服务器之间的通信,并通过实战案例展示其核心用法。

项目概述

本项目使用FastMCP库实现了一个简单的客户端-服务器通信示例,包含基本的工具注册与调用功能。通过本示例,你将了解FastMCP的核心概念、使用方法以及常见问题的解决方案。

项目结构

复制代码
├── .venv/         # Python虚拟环境
├── client.py      # 客户端代码
├── server.py      # 服务器代码
└── README.md      # 项目说明文档

实现步骤

步骤1: 创建虚拟环境并安装依赖

首先,我们需要创建一个独立的Python虚拟环境并安装必要的依赖:

  1. 创建Python虚拟环境:

    bash 复制代码
    python -m venv .venv
  2. 激活虚拟环境:

    bash 复制代码
    # Linux/Mac系统
    source .venv/bin/activate
    
    # Windows系统
    .venv\Scripts\activate
  3. 安装FastMCP库:

    bash 复制代码
    pip install fastmcp

步骤2: 编写服务器代码

创建server.py文件,实现一个简单的MCP服务器,该服务器将提供一个hello工具供客户端调用:

python 复制代码
# 导入FastMCP类,用于创建MCP服务器
from fastmcp import FastMCP

# 创建FastMCP服务器实例,命名为"Demo"
mcp = FastMCP("Demo")

# 使用装饰器注册一个名为"hello"的工具函数
@mcp.tool
def hello(name: str) -> str:
    """
    向指定名称的用户发送问候
    
    参数:
        name: 字符串,要问候的用户名称
    
    返回:
        字符串,包含问候语的响应
    """
    return f"Hello, {name}!"

# 当脚本作为主程序运行时
if __name__ == "__main__":
    # 启动MCP服务器
    # 默认使用STDIO传输方式,通过标准输入输出与客户端通信
    mcp.run()

代码解析

  • 我们通过FastMCP类创建了一个服务器实例,并命名为"Demo"
  • 使用@mcp.tool装饰器注册了一个名为hello的工具函数
  • 该工具函数接收一个name参数,并返回相应的问候语
  • 服务器默认使用STDIO(标准输入输出)作为传输方式
  • 最后通过mcp.run()启动服务器

步骤3: 编写客户端代码

创建client.py文件,实现一个连接到服务器的客户端:

python 复制代码
# 导入asyncio模块,用于支持异步操作
import asyncio
# 导入Client类,用于创建MCP客户端
from fastmcp import Client

# 创建Client实例,连接到名为"server.py"的服务器脚本
# 客户端会自动推断使用STDIO传输方式与服务器通信
client = Client("server.py")

# 定义异步函数call_tool,用于调用服务器上的工具
async def call_tool(name: str):
    """
    异步调用服务器上的hello工具
    
    参数:
        name: 字符串,要传递给hello工具的名称参数
    
    返回:
        无返回值,但会打印服务器的响应结果
    """
    # 使用异步上下文管理器连接到服务器
    async with client:
        # 调用服务器上的hello工具,传递name参数
        result = await client.call_tool("hello", {"name": name})
        # 打印服务器返回的结果
        print(result)

# 运行异步函数call_tool,传入默认名称"Ford"
asyncio.run(call_tool("Ford"))

代码解析

  • 我们创建了一个Client实例,指定要连接的服务器脚本
  • 定义了异步函数call_tool用于调用服务器上的工具
  • 使用异步上下文管理器async with client来管理与服务器的连接
  • 通过await client.call_tool()方法调用服务器上的hello工具
  • 最后使用asyncio.run()运行异步函数,启动客户端

步骤4: 解决通信问题

在实现过程中,我们遇到了几个典型问题并成功解决:

  1. 传输方式识别问题

    • 问题:最初客户端无法自动识别"stdio"传输方式
    • 解决:通过查看源码了解到FastMCP使用PythonStdioTransport类处理标准输入输出通信,客户端会根据服务器类型自动选择合适的传输方式
  2. 连接管理问题

    • 问题:不清楚如何正确管理客户端与服务器的连接状态
    • 解决:FastMCP Client采用异步上下文管理器模式进行连接管理,替代了显式的connect()disconnect()方法,使用async with client即可自动管理连接的建立和关闭
  3. 工具调用参数问题

    • 问题:工具调用时参数传递不正确
    • 解决:call_tool方法需要使用name参数指定工具名称,第二个参数为工具所需的参数字典
  4. 工具名称匹配问题

    • 问题:客户端调用工具时提示找不到工具
    • 解决:确保客户端调用的工具名称与服务器注册的工具名称完全匹配,包括大小写

步骤5: 运行和测试

完成代码编写后,我们可以按照以下步骤运行和测试:

  1. 首先启动服务器,在终端中执行:

    bash 复制代码
    python server.py
  1. 打开另一个终端,激活相同的虚拟环境,运行客户端:

    bash 复制代码
    python client.py
  2. 客户端将输出服务器的响应结果:

    复制代码
    CallToolResult(content=[TextContent(type='text', text='Hello, Ford!', annotations=None, meta=None)], structured_content={'result': 'Hello, Ford!'}, data='Hello, Ford!', is_error=False)

步骤6: trae中集成MCP

  1. 在trae ide中点击手动添加MCP

  2. 把这段json输入进去

    {
    "mcpServers": {
    "local-mcp-server": {
    "command": "bash",
    "args": [
    "-c",
    "source /mcp-test/.venv/bin/activate && python /mcp-test/server.py"
    ],
    "cwd": "/mcp-test"
    }
    }
    }

  1. 看到这个小绿对钩就是成功了

  2. 在对话中输入"张三",可以看到正常调用我们自定义的MCP服务

技术要点总结

  1. FastMCP库核心概念

    • FastMCP提供了简单易用的API,简化了MCP客户端-服务器通信的实现
    • 服务器通过装饰器注册工具,客户端通过名称调用这些工具
  2. STDIO传输方式

    • 默认使用标准输入输出进行进程间通信
    • 无需网络配置,适合本地进程间的简单通信场景
  3. 异步编程模型

    • 客户端基于asyncio实现异步操作
    • 使用异步上下文管理器管理连接生命周期
    • 通过await关键字处理异步工具调用
  4. 工具注册与调用

    • 服务器使用@mcp.tool装饰器注册工具函数
    • 客户端使用call_tool方法调用服务器上的工具
    • 工具参数以字典形式传递,支持复杂数据结构

扩展与优化建议

  1. 对于生产环境,可以考虑:

    • 使用更可靠的传输方式(如TCP)
    • 添加身份验证和数据加密
    • 实现错误重试机制
    • 添加日志记录和监控
  2. 功能扩展:

    • 注册多个工具函数,实现更复杂的业务逻辑
    • 添加工具调用的超时处理
    • 支持更复杂的参数类型和返回值
    • 实现批量工具调用功能

结论

通过本文的示例,我们展示了如何使用FastMCP库快速实现客户端与服务器之间的通信。FastMCP提供了简洁的API和灵活的扩展能力,使开发者能够专注于业务逻辑的实现,而无需过多关注底层通信细节。无论是在AI模型交互、分布式系统协调还是普通的进程间通信场景,FastMCP都是一个值得尝试的优秀选择。

希望本文能帮助你快速入门FastMCP的使用,如果有任何问题或建议,欢迎在评论区留言讨论!