前言
大家好,我是倔强青铜三。欢迎关注我。欢迎点赞、收藏、关注,一键三连!!!
在本教程中,我们将逐步构建一个 Python MCP(模型上下文协议)客户端,用于在终端测试服务器。通过这个项目,您将学习如何使用 MCP Python SDK 和 argparse 构建命令行客户端,列出服务器的功能,并通过 AI 聊天集成工具响应。
前置知识
为了从本项目中获得最大收益,您需要具备一些使用 uv 管理 Python 项目的知识,并了解 Python 标准库中的 asyncio 和 argparse 库的基本用法。如果您对这些内容不熟悉,可以参考以下资源:
此外,熟悉 OpenAI 的 Python API(openai)也会很有帮助,因为您将使用这个库为 MCP 客户端提供聊天功能。您还将使用 Model Context Protocol (MCP) Python SDK https://github.com/modelcontextprotocol/python-sdk。
如果您在开始本教程之前没有掌握所有前置知识,没关系!您可以通过实际操作来学习。如果您遇到困难,可以先回顾上述链接中的资源,然后再继续编码。
您还需要一个 MCP 服务器来测试您构建的客户端。如果您没有可用的服务器,可以使用本教程中提供的服务器代码。
第一步:设置项目和环境
为了管理您的 MCP 客户端项目,您将使用 uv,这是一个用于 Python 项目管理的命令行工具。
安装完成后,打开终端,进入您通常保存项目的目录,并运行以下命令以创建一个新的 mcp-client/ 项目:
uv new mcp-client
该命令将在 mcp-client/ 目录中创建一个新的 Python 项目,目录结构如下:
mcp-client/
├── .git/
├── .gitignore
├── .python-version
├── README.md
├── main.py
└── pyproject.toml
其中,.git/ 和 .gitignore 文件用于版本控制。.python-version 文件指定项目的默认 Python 版本,uv 会根据此文件创建项目的虚拟环境。README.md 文件用于项目文档,main.py 是项目的入口脚本(本教程中不会使用,可以删除)。pyproject.toml 文件用于项目构建和分发的配置。
接下来,运行以下命令安装项目依赖:
uv add mcp openai
这将自动为项目创建虚拟环境,并安装 mcp 和 openai 依赖。
现在,您可以在项目的根目录中启动您喜欢的代码编辑器或 IDE,准备开始编码!
第二步:使用 Python SDK 编写最小化的 MCP 客户端
在开始编码之前,您需要设置测试服务器。如果您没有服务器,请在项目根目录下创建一个 mcp_server/ 子目录,并在其中创建 mcp_server.py 脚本,代码如下:
# mcp_server.py
import mcp
@mcp.server
def example_server():
@mcp.tool
def add(a: int, b: int) -> int:
return a + b
@mcp.prompt
def welcome():
return "Welcome to the example server!"
@mcp.resource
def data():
return {"key": "value"}
if __name__ == "__main__":
example_server()
现在,您可以创建一个最小化的 MCP 客户端,使其能够连接到此服务器及其他服务器。在项目根目录下创建一个 mcp_client/ 子目录,并在其中创建 __init__.py 文件以将其标记为 Python 包。然后,创建 mcp_client.py 文件,初始内容如下:
# mcp_client/mcp_client.py
import asyncio
import mcp
from contextlib import AsyncExitStack
class MCPClient:
client_session: mcp.ClientSession
def __init__(self, server_path: str):
self.server_path = server_path
self.exit_stack = AsyncExitStack()
async def _connect_to_server(self) -> mcp.ClientSession:
try:
async with self.exit_stack:
stdin, stdout = await self.exit_stack.enter_async_context(
mcp.stdio_client()
)
server_cmd = f"{sys.executable} {self.server_path} 2>/dev/null"
session = await mcp.ClientSession.create(stdin, stdout, server_cmd)
return session
except Exception as e:
raise RuntimeError("Failed to connect to the server") from e
async def __aenter__(self):
self.client_session = await self._connect_to_server()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.exit_stack.aclose()
在上述代码中,您首先导入了所需的模块和对象,然后定义了 MCPClient 类以管理与目标 MCP 服务器的通信。通信通过 .client_session 属性实现,该属性是一个 mcp.ClientSession 实例。
.__init__() 方法初始化服务器的可执行路径,并创建一个 AsyncExitStack 实例。AsyncExitStack 是 Python contextlib 模块中的上下文管理器,用于管理多个异步上下文管理器。您需要它来管理 stdio 客户端及其会话。
您将 MCPClient 类用作异步上下文管理器,因此需要实现 .__aenter__() 和 .__aexit__() 特殊方法:
.__aenter__() 方法在 async with 语句进入目标上下文时运行。此时是创建客户端会话的好时机,您通过调用 ._connect_to_server() 辅助方法来实现。
.__aexit__() 方法在 async with 语句退出时自动调用。此时是关闭客户端会话的合适时机,您通过调用 AsyncExitStack 的 .aclose() 方法并异步等待其完成来释放资源。
接下来,实现 ._connect_to_server() 方法以完成实际的连接工作。该方法是异步的,返回一个 ClientSession 实例。
在 ._connect_to_server() 方法中,您在 try 块中使用 .exit_stack 对象进入异步上下文,并访问客户端标准 I/O 的读写流。
客户端启动一个服务器进程,其参数是使用 sh -c 执行的命令字符串。您使用 Python 解释器路径 sys.executable 和 self.server_path 属性构建目标字符串。2>/dev/null 将错误输出重定向,以避免终端窗口被杂乱信息填满。
然后,您将读写通信通道传递给 ClientSession 类,该类管理通信会话。最后,您初始化会话并将其返回给调用者。
AsyncExitStack 实例确保在整个应用程序执行期间维护 stdio 客户端及其会话上下文。只有在 .__aexit__() 方法中调用 .exit_stack.aclose() 时,才会退出这两个上下文。
如果任何步骤失败,您将引发一个 RuntimeError,表明连接尝试未成功。请注意,捕获宽泛的 Exception 类并不是 Python 中的最佳实践。然而,在此示例中,为了简单和方便,您使用了这个异常。
现在,您可以尝试运行此代码。返回到代码编辑器中,在 mcp_client 包内创建以下 __main__.py 文件:
# mcp_client/__main__.py
import asyncio
from mcp_client import MCPClient
async def main():
server_path = "mcp_server/mcp_server.py"
async with MCPClient(server_path) as client:
print("Connected to the server!")
if __name__ == "__main__":
asyncio.run(main())
运行以下命令以测试客户端:
python -m mcp_client
如果一切正常,您的 MCP 客户端将成功连接到目标服务器。这是个很好的开始!在下一节中,您将为客户端添加命令行界面(CLI)和更多有用的功能。
第三步:为 MCP 客户端添加命令行界面
为了为 MCP 客户端添加命令行界面,您将使用 Python 标准库中的 argparse 模块。该模块提供了一种快速创建用户友好 CLI 的方法,支持参数、选项、子命令等。
在初始阶段,CLI 将接受 MCP 服务器脚本的路径作为参数,并提供一个 --members 选项,用于列出服务器的工具、提示和资源。每个条目如果可用,还会显示简短描述。
使用 argparse 构建 MCP 客户端的 CLI
返回到代码编辑器中,在 mcp_client 包内创建一个名为 cli.py 的新文件,并添加以下内容:
# mcp_client/cli.py
import argparse
from pathlib import Path
def parse_args():
parser = argparse.ArgumentParser(description="MCP Client")
parser.add_argument(
"server_path",
type=Path,
help="Path to the MCP server script"
)
group = parser.add_mutually_exclusive_group()
group.add_argument(
"--members",
action="store_true",
help="List server members"
)
group.add_argument(
"--chat",
action="store_true",
help="Start a chat session"
)
return parser.parse_args()
在此文件中,您使用 ArgumentParser 类创建了一个命令行参数解析器,然后添加了一个参数以指定 MCP 服务器脚本的路径。您将参数的类型设置为 pathlib.Path,以便 CLI 将用户提供的路径字符串转换为 Path 对象,从而增强应用程序的路径管理能力。help 参数允许您为客户端用户提供描述性帮助消息。
您还创建了一个互斥的命令行选项组,因为您不希望 --members 选项与稍后将实现的 --chat 选项同时运行。接下来,您添加了 --members 选项,将其存储为布尔值,并提供了适当的帮助消息。至此,CLI 已准备好。
在下一节中,您将编写代码,使 --members 选项能够列出 MCP 服务器的工具、提示和资源。
添加 --members 命令行选项
--members 命令行选项将提供目标 MCP 服务器的所有成员或原语的完整列表。您将从 MCPClient 的公共接口中的 list_all_members() 函数开始:
# mcp_client/mcp_client.py
async def list_all_members(self):
print("Server Members:")
sections = {
"Tools": self.client_session.list_tools,
"Prompts": self.client_session.list_prompts,
"Resources": self.client_session.list_resources,
}
for section_name, list_method in sections.items():
await self._list_section(section_name, list_method)
async def _list_section(self, section_name: str, list_method):
try:
items = await list_method()
print(f"\n{section_name}:")
print(f"Total: {len(items)}")
for item in items:
print(f"- {item.name}: {item.description or 'No description'}")
except Exception as e:
print(f"Error listing {section_name.lower()}: {e}")
在 list_all_members() 函数中,您打印成员列表的标题,然后创建一个字典,将部分名称映射到客户端会话中的相应列出方法。接下来,您遍历字典项,调用 ._list_section() 方法以从 MCP 服务器获取数据。
._list_section() 辅助方法的实现如下:
在 ._list_section() 方法中,您接受一个部分名称(如 "tools"、"prompts" 或 "resources")和一个 ClientSession.list_* 方法对象作为参数。然后,您使用 getattr() 动态调用该方法,并检索该部分的成员或条目。最后,您打印部分标题、条目数量以及每个条目的详细信息,包括其名称和描述。
如果未找到任何条目,您将打印一条消息,表明该部分为空。该方法还包括错误处理,以捕获并显示在过程中发生的任何异常,确保程序不会因失败而崩溃,而是为用户提供清晰的错误消息。
更新客户端的入口脚本
为了让一切正常工作,您需要完全更新 __main__.py 文件,如下所示:
# mcp_client/__main__.py
import asyncio
from mcp_client import MCPClient
from mcp_client.cli import parse_args
async def main():
args = parse_args()
if not args.server_path.exists():
print("Error: Server script not found.")
return
try:
async with MCPClient(str(args.server_path)) as client:
if args.members:
await client.list_all_members()
elif args.chat:
await client.run_chat()
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
asyncio.run(main())
在此更新的 main() 函数中,您通过调用 cli.py 模块中的 parse_args() 获取命令行参数。条件语句检查 MCP 服务器脚本的路径是否存在。如果不存在,则打印错误消息并退出,这将导致应用程序终止。
接下来,在 try 块中,您在 async with 语句中创建一个 MCPClient 实例。with 代码块内的条件语句检查用户是否在命令行中提供了 --members 选项。如果是,则等待调用 .list_all_members()。如果发生错误,则将错误消息打印到屏幕上。
现在,您可以尝试运行您的 MCP 客户端。确保您位于项目的根目录中,然后运行以下命令:
python -m mcp_client --members
输出看起来很棒!它列出了三个部分及其各自的条目。这使您能够评估目标服务器的功能,并更好地了解如何有效使用它。
第四步:添加 AI 聊天功能
在本节中,您将为 MCP 客户端添加聊天功能。首先,您将在应用程序的 CLI 中添加一个 --chat 选项。然后,您将使用 OpenAI 的 Python SDK 编写一个 AI 聊天处理器。最后,您将设置客户端以便在当前 Python 环境中安装。
首先,您将在应用程序的 CLI 中添加 --chat 命令行选项。
添加 --chat 命令行选项
返回到 cli.py 文件,并添加以下代码:
# mcp_client/cli.py
group.add_argument(
"--chat",
action="store_true",
help="Start a chat session"
)
--chat 选项将触发命令行上的最小聊天界面。接下来,您将设置聊天界面,您可以在其中输入查询并接收 AI 后端的响应。
为了编写聊天界面,请在 mcp_client 包下创建一个名为 chat.py 的新文件,并添加以下代码:
# mcp_client/chat.py
async def run_chat(handler):
print("Chat started. Type 'quit' to exit.")
while True:
query = input("You: ")
if query.lower() == "quit":
break
try:
response = await handler.process_query(query)
print(f"Assistant: {response}")
except Exception as e:
print(f"Error: {e}")
这是一个非常简短的函数。它接受一个 AI 处理器作为参数,打印一条提示信息,并启动聊天循环。
while 循环是一个故意的无限循环,只有当用户在命令行中输入 quit 时才会终止。
在循环中,您使用内置的 input() 函数获取用户查询,并将其存储在 query 变量中。接下来,您使用此查询作为 handler.process_query() 的参数,该函数将查询传递给 OpenAI 模型进行进一步处理。如果发生错误,则打印相应的错误消息。
使用 OpenAI 的 Python SDK 创建聊天处理器
与 MCP 服务器交互需要一个 AI 客户端。到目前为止,您的 MCP 客户端还没有 AI 功能。在本节中,您将实现这一功能。您将使用已在工作环境中安装的 OpenAI Python SDK。
返回到代码编辑器中,在 mcp_client 包下创建一个名为 handlers.py 的新文件,并添加以下代码:
# mcp_client/handlers.py
import json
import openai
MODEL = "gpt-3.5-turbo"
MAX_TOKENS = 1000
class OpenAIQueryHandler:
def __init__(self, client_session):
self.client_session = client_session
self.openai = openai
if not openai.api_key:
raise ValueError("OpenAI API key not set")
async def process_query(self, query: str) -> str:
conversation = [{"role": "user", "content": query}]
tools = await self._get_tools()
response = await self.openai.ChatCompletion.acreate(
model=MODEL,
max_tokens=MAX_TOKENS,
messages=conversation,
tools=tools,
)
result_parts = []
if response.choices[0].message.content:
result_parts.append(response.choices[0].message.content)
if response.choices[0].message.tool_calls:
conversation.append(response.choices[0].message)
for tool_call in response.choices[0].message.tool_calls:
result = await self._execute_tool(tool_call)
result_parts.append(result["log"])
final_response = await self.openai.ChatCompletion.acreate(
model=MODEL,
max_tokens=MAX_TOKENS,
messages=conversation,
)
result_parts.append(final_response.choices[0].message.content)
return "\n".join(result_parts)
async def _get_tools(self):
tools = await self.client_session.list_tools()
return [
{
"type": "function",
"function": {
"name": tool.name,
"description": tool.description,
"parameters": json.loads(tool.input_schema.json()),
},
}
for tool in tools
]
async def _execute_tool(self, tool_call):
tool_name = tool_call.function.name
tool_args = json.loads(tool_call.function.arguments)
try:
result = await self.client_session.call_tool(tool_name, **tool_args)
if result:
content = result[0].text if result[0].text else ""
else:
content = ""
log = f"Called {tool_name} with args {tool_args}. Result: {content}"
return {"log": log, "message": {"role": "tool", "content": content}}
except Exception as e:
log = f"Failed to call {tool_name}: {e}"
return {"log": log, "message": {"role": "tool", "content": ""}}
在上述代码中,您定义了两个常量 MODEL 和 MAX_TOKENS,分别表示将使用的模型和允许的最大令牌数。
接下来,您定义了 OpenAIQueryHandler 类。初始化器接受一个 ClientSession 作为参数,并定义了 .client_session 和 .openai 属性。它还会检查您的环境中是否设置了 OpenAI API 密钥。
处理器的核心是 .process_query() 方法,它接受用户查询作为字符串,并执行以下操作:
- 将查询与 MCP 服务器上可用的工具列表一起发送给 OpenAI。
- 检查模型的响应,确定是否需要调用工具。
- 触发所需的工具调用。
- 请求模型提供一个最终答案,整合任何工具输出。
以下是您的 process_query() 方法的实现:
首先,您使用用户查询构建与 OpenAI 模型的初始对话。您调用 .create(),传入模型、令牌限制、消息以及调用 ._get_tools() 的结果,后者将 MCP 工具打包成 OpenAI 可处理的模式。
模型返回一个可能包含直接内容和可选工具调用指令的消息对象。
如果模型生成内容,则将其附加到结果部分列表中。然后,您检查响应是否需要任何工具调用。如果是,则将带有工具调用元数据的助手消息附加到对话中。接下来,您遍历工具并委托执行给 ._execute_tool()。
执行所有工具调用后,您再次调用模型,请求一个整合工具输出的最终答案。最后,您将所有部分附加在一起,并返回一个格式化的答案,这将是聊天界面中 AI 助手的响应。
._get_tools() 辅助方法非常简单。以下是它的代码:
在此方法中,您通过调用 .list_tools() 获取 MCP 服务器的工具,然后将每个工具转换为 OpenAI 可处理的 JSON 模式格式,描述要调用的函数。每个工具包含名称、描述和输入模式。
这些信息至关重要,因为它使 OpenAI 模型能够确定是否调用任何工具以生成整合结果数据的最终响应。
最后,您需要 ._execute_tool() 辅助方法。以下是它的实现:
在 ._execute_tool() 辅助方法中,您从模型输出中获取一个 tool_call 对象,并通过您的 ClientSession 在其上运行。为此,您首先提取工具的名称,并使用 json.loads() 函数解析其参数。
接下来,您等待 client_session.call_tool() 在 MCP 服务器端执行当前工具。如果工具返回结构化内容,则提取其第一项的文本。否则,将内容设置为空字符串。您还会构建一个总结调用的记录字符串,以便在聊天界面中为用户提供反馈。
如果由于异常导致工具执行失败,则捕获错误并相应地创建记录。最后,您返回一个包含两个键的字典:"log" 包含总结字符串,"message" 包含 AI 模型的工具角色消息。
至此,您已为客户端的聊天界面编写了 AI 处理器。现在是时候更新 MCPClient 类了。
将聊天与 MCP 客户端连接
返回到 mcp_client.py 文件。首先,更新导入内容,添加 chat 函数和 OpenAIQueryHandler 类:
# mcp_client/mcp_client.py
from .chat import run_chat
from .handlers import OpenAIQueryHandler
更新导入后,您可以向 MCPClient 添加 .run_chat() 方法:
# mcp_client/mcp_client.py
async def run_chat(self):
handler = OpenAIQueryHandler(self.client_session)
await run_chat(handler)
在 .run_chat() 方法中,您为聊天会话创建 AI 处理器,然后调用 .run_chat() 函数以启动聊天界面。如果发生错误,则打印适当的错误消息以通知用户。
现在,您可以更新应用程序的入口脚本,以便从命令行使用新的聊天功能。
更新客户端的入口脚本
为了将 --chat 选项集成到客户端的行为中,您只需要对 __main__.py 文件进行最小限度的更改。请考虑以下突出显示的行:
# mcp_client/__main__.py
async def main():
args = parse_args()
if not args.server_path.exists():
print("Error: Server script not found.")
return
try:
async with MCPClient(str(args.server_path)) as client:
if args.members:
await client.list_all_members()
elif args.chat:
await client.run_chat()
except Exception as e:
print(f"Error: {e}")
在此更新中,您只需在条件语句中添加一个 elif 分支。此分支检查用户是否提供了 --chat 命令行选项。如果是,则在客户端对象上调用 .run_chat()。
现在,您可以尝试使用聊天界面。运行以下命令,然后输入对助手的请求:
python -m mcp_client --chat
看起来很棒!聊天界面可以正常工作,让您能够查询模型并接收响应。注意模型如何将工具调用结果整合到其回复中。这证实了目标 MCP 服务器被正确使用。要退出聊天界面,请输入 quit 并按下 Enter。
使 MCP 客户端应用程序可安装
在本节中,您将编辑 pyproject.toml 文件,以便使用 uv 构建和本地安装您的 MCP 客户端,进行可编辑安装。
此时,您的项目应具有以下目录结构:
mcp-client/
├── .git/ # Git 版本控制
├── .venv/ # Python 虚拟环境
├── mcp_client/ # MCP 客户端
│ ├── __init__.py
│ ├── __main__.py
│ ├── chat.py
│ ├── cli.py
│ ├── handlers.py
│ └── mcp_client.py
├── mcp_server/ # 测试 MCP 服务器
│ └── mcp_server.py
├── .gitignore
├── .python-version
├── README.md
├── pyproject.toml
└── uv.lock
第五步:将项目打包为可安装的 Python 应用程序
在项目的根目录下,打开 pyproject.toml 文件,并按照以下内容进行更新:
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
[tool.poetry]
name = "mcp-client"
version = "0.1.0"
description = "A minimal MCP client for testing servers from the terminal"
authors = ["Your Name <your.email@example.com>"]
license = "MIT"
[tool.poetry.dependencies]
python = "^3.8"
mcp = "^1.0.0"
openai = "^1.0.0"
[tool.poetry.dev-dependencies]
uv = "^1.0.0"
[tool.poetry.scripts]
mcp-client = "mcp_client.__main__:cli_main"
解释配置文件内容
-
[build-system]:
- 指定使用 Poetry 构建系统。
requires 指定了构建依赖,这里使用 Poetry。
build-backend 指定了构建后端,这里使用 Poetry 的构建工具。
-
[tool.poetry]:
name:项目名称。
version:项目版本。
description:项目描述。
authors:项目作者信息。
license:项目许可证。
-
[tool.poetry.dependencies]:
- 列出了项目运行时依赖,包括 Python 版本和
mcp、openai 库。
-
[tool.poetry.dev-dependencies]:
-
[tool.poetry.scripts]:
- 定义了项目入口点脚本。这里将
mcp-client 命令映射到 mcp_client.__main__:cli_main。
添加 cli_main 函数
在 mcp_client/__main__.py 文件中,添加以下内容:
# mcp_client/__main__.py
import asyncio
from mcp_client import MCPClient
from mcp_client.cli import parse_args
def cli_main():
asyncio.run(main())
async def main():
args = parse_args()
if not args.server_path.exists():
print("Error: Server script not found.")
return
try:
async with MCPClient(str(args.server_path)) as client:
if args.members:
await client.list_all_members()
elif args.chat:
await client.run_chat()
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
cli_main()
构建和安装项目
在终端中运行以下命令以构建和安装项目:
poetry build
poetry install
这将构建项目并将其安装到当前的 Python 环境中。安装完成后,您可以通过以下命令直接运行客户端:
mcp-client --members
mcp-client --chat
第六步:测试和验证
测试 --members 功能
运行以下命令以列出服务器的功能:
mcp-client --members
您应该看到类似以下的输出:
Server Members:
Tools:
Total: 1
- add: Adds two integers
Prompts:
Total: 1
- welcome: Welcome message
Resources:
Total: 1
- data: Example data
测试聊天功能
运行以下命令以启动聊天界面:
mcp-client --chat
在聊天界面中,输入以下内容:
You: What is 2 + 3?
您应该收到类似以下的回复:
Assistant: The result of 2 + 3 is 5.
这表明您的客户端能够成功调用服务器上的工具并返回结果。
第七步:扩展和优化
添加 HTTP 流式支持
您可以修改代码,使客户端能够通过 HTTP POST 和 GET 请求连接到在线 MCP 服务器。这将使您的客户端更加灵活,能够测试更广泛的服务器。
处理提示和资源
目前,您的客户端仅支持工具调用。您可以扩展功能,支持 MCP 提示和资源,以增强与服务器的交互能力。
支持更多 AI 模型
您可以扩展客户端,使其能够使用来自其他在线和本地提供商的 AI 模型,从而为聊天功能提供更多选择。
结论
通过本教程,您学习了如何使用 Python 构建一个基本的命令行 MCP 客户端,能够连接到 MCP 服务器、发现其功能并通过 AI 聊天界面与之交互。您从设置项目环境和实现强大的客户端类开始,使用异步上下文管理和 MCP Python SDK。接下来,您添加了用户友好的命令行界面,使用 argparse 实现了无缝的功能发现和由 OpenAI API 提供支持的交互式聊天会话。最后,您将项目打包以便安装。
通过这些技能,您现在可以直接从终端快速测试 MCP 服务器,并可以根据需要扩展客户端应用程序的功能。您已具备实验高级 AI 集成和优化 MCP 服务器开发周期的能力。
下一步
现在您已经完成了 MCP 客户端应用程序的构建,可以通过添加新功能来进一步扩展项目。以下是一些扩展项目的思路:
- 添加 HTTP 流式支持:修改代码,使客户端能够通过 HTTP POST 和 GET 请求连接到在线 MCP 服务器。
- 处理提示和资源:添加代码以支持不仅工具调用,还包括 MCP 提示和资源。
- 支持更多 AI 模型:启用来自其他在线和本地提供商的模型,以处理聊天功能。
原文:realpython.com/python-mcp-client
作者:Leodanis Pozo Ramos
译者:倔强青铜三