9.4 单机MCP客户端搭建

邓立国Agent开发入门必读书《AI Agent智能体开发实践》1~11章试读_《ai agent 智能体开发实践》在线阅读-CSDN博客

9.3 单机MCP服务端进阶实现与优化《AI Agent智能体开发实践》-CSDN博客

我们知道MCP是一种用于模型上下文交互的协议,通过Python SDK可以快速搭建单机版MCP客户端。本节介绍MCP客户端详细的搭建步骤。

1. 环境准备

首先需要安装Python 3.8 +环境,以及MCP Python SDK:

pip install mcp-sdk-python

2. 基本客户端结构设计

一个基础的MCP客户端应包含以下核心功能:

  • 协议连接管理。

  • 上下文数据处理。

  • 消息序列化/反序列化。

  • 错误处理机制。

3. 客户端实现代码

【示例9.5】mcp_client_achieve.py。

# mcp_client_achieve.py

import requests

import json

from typing import Dict, Any, Optional

class MCPLocalClient:

    """HTTPMCP客户端实现,适配FastAPI MCP Server"""

    def __init__(self, server_url: str = "http://localhost:8000"):

        """

        初始化MCP客户端

        :param server_url: MCP服务器基础URL(如 http://localhost:8000

        """

        self.server_url = server_url.rstrip("/")

        self.context_id: Optional[str] = None

        self.context_data: Dict[str, Any] = {}

    def create_context(self, model_id: str, context_data: Dict[str, Any], ttl: int = 3600) -> bool:

        """

        创建新的上下文

        :param model_id: 模型标识

        :param context_data: 初始上下文数据

        :param ttl: 过期时间(秒)

        :return: 成功返回True,否则返回False

        """

        url = f"{self.server_url}/mcp/v1/context"

        payload = {

            "model_id": model_id,

            "context_data": context_data,

            "ttl": ttl

        }

        try:

            response = requests.post(url, json=payload)

            response.raise_for_status()

            result = response.json()

            self.context_id = result["context_id"]

            self.context_data = context_data

            print(f"上下文创建成功,ID: {self.context_id}")

            return True

        except requests.RequestException as e:

            print(f" 创建上下文失败: {e}")

            return False

    def get_context(self) -> Optional[Dict[str, Any]]:

        """

        获取当前上下文数据

        :return: 上下文数据字典,失败返回None

        """

        if not self.context_id:

            print("未创建上下文,请先调用 create_context()")

            return None

        url = f"{self.server_url}/mcp/v1/context/{self.context_id}"

        try:

            response = requests.get(url)

            response.raise_for_status()

            result = response.json()

            self.context_data = result["data"]

            return self.context_data

        except requests.RequestException as e:

            print(f"获取上下文失败: {e}")

            return None

    def update_context(self, data: Dict[str, Any], append: bool = True) -> bool:

        """

        更新上下文数据

        :param data: 要更新的数据

        :param append: True=追加合并,False=覆盖

        :return: 更新成功返回True,否则返回False

        """

        if not self.context_id:

            print("未创建上下文,请先调用 create_context()")

            return False

        url = f"{self.server_url}/mcp/v1/context"

        payload = {

            "context_id": self.context_id,

            "context_data": data,

            "append": append

        }

        try:

            response = requests.put(url, json=payload)

            response.raise_for_status()

            result = response.json()

            if append:

                self.context_data.update(data)

            else:

                self.context_data = data

            print(" 上下文更新成功")

            return True

        except requests.RequestException as e:

            print(f" 更新上下文失败: {e}")

            return False

    def delete_context(self) -> bool:

        """

        删除当前上下文

        :return: 删除成功返回True,否则返回False

        """

        if not self.context_id:

            print(" 无上下文可删除")

            return False

        url = f"{self.server_url}/mcp/v1/context/{self.context_id}"

        try:

            response = requests.delete(url)

            response.raise_for_status()

            result = response.json()

            self.context_id = None

            self.context_data = {}

            print("上下文删除成功")

            return True

        except requests.RequestException as e:

            print(f" 删除上下文失败: {e}")

            return False

    def close(self) -> None:

        """清理资源(此处无连接需关闭,可留空或用于日志)"""

        print("🔌 MCP客户端已关闭")

# 使用示例

if __name__ == "__main__":

    # 创建客户端实例

    client = MCPLocalClient("http://localhost:8000")

    # 创建上下文

    if client.create_context(

        model_id="chatbot-v1",

        context_data={

            "user_id": "12345",

            "user_name": "test_user",

            "preferences": {"theme": "dark", "notifications": True}

        },

        ttl=3600

    ):

        # 获取上下文

        context = client.get_context()

        if context:

            print("📥 当前上下文数据:")

            print(json.dumps(context, indent=2, ensure_ascii=False))

        # 更新上下文(追加模式)

        client.update_context({

            "last_login": "2023-10-01T12:00:00Z",

            "session_count": 5

        }, append=True)

        # 再次获取上下文

        context = client.get_context()

        if context:

            print("📥 更新后的上下文数据:")

            print(json.dumps(context, indent=2, ensure_ascii=False))

        # 覆盖模式更新

        client.update_context({

            "reset": True

        }, append=False)

        context = client.get_context()

        if context:

            print("📥 覆盖后的上下文数据:")

            print(json.dumps(context, indent=2, ensure_ascii=False))

        # 删除上下文

        client.delete_context()

    # 关闭客户端

    client.close()

先运行mcp_server.py(9.2 单机MCP服务器端搭建《AI Agent智能体开发实践》-CSDN博客):

再运行本示例代码,输出如下:

上下文创建成功,ID: 1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p

📥 当前上下文数据:

{

  "user_id": "12345",

  "user_name": "test_user",

  "preferences": {

    "theme": "dark",

    "notifications": true

  }

}

上下文更新成功

📥 更新后的上下文数据:

{

  "user_id": "12345",

  "user_name": "test_user",

  "preferences": {

    "theme": "dark",

    "notifications": true

  },

  "last_login": "2023-10-01T12:00:00Z",

  "session_count": 5

}

上下文更新成功

📥 覆盖后的上下文数据:

{

  "reset": true

}

上下文删除成功

🔌 MCP客户端已关闭

从上面的结果可以看到,代码使用标准HTTP客户端,完美适配FastAPI服务,结构清晰,功能     完整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值