MCP Python SDK客户端开发指南:构建智能MCP客户端应用

MCP Python SDK客户端开发指南:构建智能MCP客户端应用

【免费下载链接】python-sdk The official Python SDK for Model Context Protocol servers and clients 【免费下载链接】python-sdk 项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk

在当今的智能应用开发中,与Model Context Protocol(MCP)服务器进行高效交互变得越来越重要。MCP Python SDK为开发者提供了构建强大MCP客户端应用的全套工具,让您能够轻松连接、认证并利用MCP服务器的各种功能。本文将带您一步步了解如何使用MCP Python SDK开发客户端应用,从环境搭建到高级功能实现,助您快速掌握MCP客户端开发的核心技能。

准备工作:安装与环境配置

开始使用MCP Python SDK前,您需要先完成安装和基础环境配置。MCP Python SDK已发布到PyPI,可通过简单的包管理命令安装。

安装MCP SDK

MCP Python SDK在PyPI上以mcp包形式提供,安装命令如下:

pip install mcp

如果您使用uv包管理器,也可以执行:

uv add mcp

安装过程会自动处理所有依赖项,包括HTTP客户端、数据验证工具和Web框架等核心组件。完整的安装指南可参考官方文档:docs/installation.md

系统要求

  • Python 3.8或更高版本
  • 网络连接(用于安装依赖和连接MCP服务器)
  • 支持的操作系统:Windows、macOS或Linux

建立连接:MCP客户端基础

MCP客户端应用的核心是与MCP服务器建立并维护连接。MCP Python SDK提供了多种连接方式和传输协议,以适应不同的应用场景。

连接方式概述

MCP SDK支持以下几种主要连接方式:

  1. Streamable HTTP:基于HTTP的流式传输,适合大多数网络环境
  2. SSE (Server-Sent Events):服务器推送事件,适合实时通知场景
  3. 标准输入输出:本地进程间通信,适合桌面应用集成

创建基础客户端连接

以下是使用Streamable HTTP传输创建MCP客户端连接的基础代码:

from mcp.client.streamable_http import streamablehttp_client
from mcp.client.session import ClientSession

async def connect_to_mcp_server(server_url):
    # 创建Streamable HTTP传输连接
    async with streamablehttp_client(url=server_url) as (read_stream, write_stream, get_session_id):
        # 创建客户端会话
        async with ClientSession(read_stream, write_stream) as session:
            # 初始化会话
            await session.initialize()
            print(f"成功连接到MCP服务器: {server_url}")
            print(f"会话ID: {get_session_id()}")
            
            # 这里可以添加与服务器交互的代码
            
            return session

这段代码展示了MCP客户端连接的基本流程:创建传输层连接,建立会话,然后初始化会话。会话创建后,您就可以与MCP服务器进行各种交互操作了。

身份验证:安全访问MCP服务器

大多数MCP服务器都要求客户端进行身份验证。MCP Python SDK提供了完整的OAuth认证流程支持,让您的应用能够安全地与受保护的MCP服务器进行交互。

OAuth认证流程

MCP客户端的OAuth认证流程主要包括以下步骤:

  1. 客户端注册:向MCP服务器注册客户端信息
  2. 授权请求:引导用户完成授权
  3. 令牌获取:使用授权码获取访问令牌
  4. 令牌刷新:在令牌过期前自动刷新

实现OAuth认证客户端

下面是一个完整的OAuth认证客户端实现示例:

from mcp.client.auth import OAuthClientProvider, TokenStorage
from mcp.client.streamable_http import streamablehttp_client
from mcp.client.session import ClientSession
from mcp.shared.auth import OAuthClientMetadata

class InMemoryTokenStorage(TokenStorage):
    """简单的内存令牌存储实现"""
    def __init__(self):
        self._tokens = None
        self._client_info = None
        
    async def get_tokens(self):
        return self._tokens
        
    async def set_tokens(self, tokens):
        self._tokens = tokens
        
    async def get_client_info(self):
        return self._client_info
        
    async def set_client_info(self, client_info):
        self._client_info = client_info

async def create_auth_client(server_url):
    # 客户端元数据
    client_metadata = OAuthClientMetadata(
        client_name="我的MCP客户端",
        redirect_uris=["http://localhost:3030/callback"],
        grant_types=["authorization_code", "refresh_token"],
        response_types=["code"],
        token_endpoint_auth_method="client_secret_post"
    )
    
    # 创建OAuth认证提供器
    oauth_auth = OAuthClientProvider(
        server_url=server_url.replace("/mcp", ""),
        client_metadata=client_metadata,
        storage=InMemoryTokenStorage(),
        redirect_handler=lambda url: webbrowser.open(url),
        callback_handler=your_callback_handler  # 您需要实现回调处理逻辑
    )
    
    # 使用OAuth认证创建传输连接
    async with streamablehttp_client(
        url=server_url,
        auth=oauth_auth,
        timeout=300
    ) as (read_stream, write_stream, get_session_id):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()
            print("已通过OAuth认证并连接到MCP服务器")
            return session

完整的带回调处理的OAuth客户端示例可参考:examples/clients/simple-auth-client/mcp_simple_auth_client/main.py

核心功能:与MCP服务器交互

成功建立连接并通过认证后,您就可以利用MCP客户端的各种功能与服务器进行交互了。MCP Python SDK提供了丰富的API,支持工具调用、资源访问、消息发送等核心功能。

会话管理

ClientSession类是MCP客户端的核心,负责与服务器的所有交互。创建会话后,您需要先调用initialize()方法进行初始化:

async with ClientSession(read_stream, write_stream) as session:
    # 初始化会话
    result = await session.initialize()
    print(f"服务器协议版本: {result.protocolVersion}")
    print(f"服务器实现: {result.serverInfo.name} v{result.serverInfo.version}")

会话初始化后,您可以获取服务器信息、支持的协议版本等关键信息,为后续交互做准备。会话的核心实现代码可参考:src/mcp/client/session.py

工具调用

MCP服务器通常提供各种工具供客户端使用。使用MCP SDK,您可以轻松列出服务器可用工具并调用它们。

列出可用工具
# 列出所有可用工具
tools_result = await session.list_tools()
print("可用工具:")
for tool in tools_result.tools:
    print(f"- {tool.name}: {tool.description}")
    if tool.parameters:
        print("  参数:")
        for param in tool.parameters:
            print(f"    {param.name}: {param.description} (必填: {param.required})")
调用工具
# 调用工具
result = await session.call_tool(
    name="weather_tool",
    arguments={"location": "北京", "date": "2023-10-01"}
)

# 处理工具返回结果
if result.isError:
    print(f"工具调用错误: {result.error.message}")
else:
    print("工具调用结果:")
    print(f"天气: {result.structuredContent['weather']}")
    print(f"温度: {result.structuredContent['temperature']}°C")
    print(f"建议: {result.content[0].text}")

工具调用是MCP客户端的核心功能之一,SDK会自动处理参数验证、结果解析和错误处理,让您能够专注于业务逻辑实现。

资源访问

MCP协议支持资源的列表、读取和订阅操作。您可以通过以下方法与服务器资源交互:

# 列出资源
resources = await session.list_resources()
for resource in resources.resources:
    print(f"资源: {resource.uri} - {resource.description}")

# 读取资源内容
resource_content = await session.read_resource(uri="mcp://server/data/news")
print(f"资源内容: {resource_content.content}")

# 订阅资源更新
await session.subscribe_resource(uri="mcp://server/data/updates")
print("已订阅资源更新")

资源系统为客户端提供了灵活的数据访问方式,适用于需要实时数据更新的场景。

实战案例:构建智能聊天机器人客户端

为了更好地理解MCP客户端开发,我们以一个简单的智能聊天机器人客户端为例,展示如何综合运用MCP SDK的各项功能。

应用架构

这个聊天机器人客户端将实现以下功能:

  • 连接到MCP服务器
  • 处理用户输入
  • 调用服务器工具获取信息
  • 使用LLM生成自然语言响应

核心实现代码

import asyncio
import json
import logging
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

# 配置日志
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

class ChatSession:
    def __init__(self, servers, llm_client):
        self.servers = servers
        self.llm_client = llm_client
        self.messages = []
        
    async def initialize(self):
        """初始化所有服务器连接"""
        for server in self.servers:
            await server.initialize()
        
        # 获取所有可用工具并构建系统提示
        all_tools = []
        for server in self.servers:
            tools = await server.list_tools()
            all_tools.extend(tools)
            
        tools_description = "\n".join([tool.format_for_llm() for tool in all_tools])
        
        # 初始化系统消息
        self.messages = [{"role": "system", "content": 
            f"你是一个 helpful assistant,可以使用以下工具:\n{tools_description}\n"
            "根据用户问题选择合适的工具,如果不需要工具则直接回答。"
        }]
    
    async def process_user_input(self, user_input):
        """处理用户输入并生成响应"""
        self.messages.append({"role": "user", "content": user_input})
        
        # 获取LLM响应
        llm_response = self.llm_client.get_response(self.messages)
        
        # 检查是否需要调用工具
        try:
            tool_call = json.loads(llm_response)
            if "tool" in tool_call and "arguments" in tool_call:
                # 调用工具
                result = await self.call_appropriate_tool(
                    tool_call["tool"], tool_call["arguments"]
                )
                self.messages.append({"role": "system", "content": f"工具执行结果: {result}"})
                
                # 根据工具结果生成最终响应
                final_response = self.llm_client.get_response(self.messages)
                self.messages.append({"role": "assistant", "content": final_response})
                return final_response
            else:
                # 直接返回LLM响应
                self.messages.append({"role": "assistant", "content": llm_response})
                return llm_response
        except json.JSONDecodeError:
            # 不是工具调用,直接返回
            self.messages.append({"role": "assistant", "content": llm_response})
            return llm_response
    
    async def call_appropriate_tool(self, tool_name, arguments):
        """调用合适的工具"""
        for server in self.servers:
            tools = await server.list_tools()
            if any(tool.name == tool_name for tool in tools):
                return await server.execute_tool(tool_name, arguments)
        return f"未找到工具: {tool_name}"
    
    async def run(self):
        """运行聊天会话"""
        print("欢迎使用MCP智能聊天助手!输入'quit'退出。")
        while True:
            user_input = input("你: ").strip()
            if user_input.lower() in ["quit", "exit"]:
                print("再见!")
                break
            response = await self.process_user_input(user_input)
            print(f"助手: {response}")

运行聊天机器人

完整的聊天机器人实现可参考:examples/clients/simple-chatbot/mcp_simple_chatbot/main.py

运行聊天机器人的步骤如下:

  1. 准备配置文件servers_config.json,指定MCP服务器信息
  2. 设置环境变量LLM_API_KEY(如果需要调用外部LLM)
  3. 运行聊天机器人:
python -m mcp_simple_chatbot.main

这个聊天机器人示例展示了MCP客户端的核心使用模式:连接服务器、调用工具、处理结果,以及如何将这些功能与LLM结合,构建智能应用。

高级技巧与最佳实践

为了帮助您构建更健壮、高效的MCP客户端应用,我们总结了一些高级技巧和最佳实践。

错误处理与重试

网络不稳定或服务器暂时不可用时,适当的错误处理和重试机制非常重要:

async def call_tool_with_retry(session, tool_name, arguments, retries=3, delay=1):
    """带重试机制的工具调用"""
    for attempt in range(retries):
        try:
            return await session.call_tool(tool_name, arguments)
        except Exception as e:
            if attempt < retries - 1:
                logging.warning(f"工具调用失败,将在{delay}秒后重试: {str(e)}")
                await asyncio.sleep(delay)
                delay *= 2  # 指数退避
            else:
                logging.error(f"工具调用失败,已达最大重试次数: {str(e)}")
                raise

连接管理与心跳

长时间运行的客户端应用应实现连接管理和心跳机制,确保连接稳定性:

async def keep_alive(session, interval=30):
    """保持连接活跃的心跳任务"""
    while True:
        try:
            await session.send_ping()
            logging.debug("发送心跳包成功")
        except Exception as e:
            logging.warning(f"心跳发送失败: {str(e)}")
            # 可以在这里实现重连逻辑
        await asyncio.sleep(interval)

# 在应用启动时启动心跳任务
async def start_client():
    # 创建会话...
    # 启动心跳任务
    asyncio.create_task(keep_alive(session))
    # 其他应用逻辑...

性能优化

对于需要高频交互的客户端应用,可以通过以下方式优化性能:

  1. 批量操作:尽量合并多个请求,减少网络往返
  2. 异步并发:合理使用异步并发,同时处理多个任务
  3. 数据缓存:缓存工具定义、资源元数据等不常变化的信息
  4. 连接池:对于多个会话,考虑使用连接池复用连接

总结与后续学习

通过本文的介绍,您已经掌握了MCP Python SDK客户端开发的基础知识和核心技能,包括环境搭建、连接建立、认证授权、工具调用和资源访问等。我们还通过一个实战案例展示了如何综合运用这些知识构建智能聊天机器人应用。

后续学习路径

  1. 深入协议规范:了解MCP协议的底层细节,有助于理解SDK的工作原理
  2. 探索高级功能:学习流式响应处理、生命周期管理等高级功能
  3. 服务端开发:了解MCP服务器开发,全面掌握MCP生态系统
  4. 示例应用:研究更多示例应用,学习实际项目中的最佳实践

MCP Python SDK为构建智能客户端应用提供了强大支持,无论您是开发简单的工具调用客户端,还是复杂的智能助手,MCP SDK都能满足您的需求。开始您的MCP客户端开发之旅吧!

如果您在开发过程中遇到问题,可以参考官方文档或查看SDK源代码,也欢迎参与MCP社区讨论,分享您的经验和见解。

【免费下载链接】python-sdk The official Python SDK for Model Context Protocol servers and clients 【免费下载链接】python-sdk 项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值