- 教程
- 文档
- 人工智能
【免费下载链接】mcp-for-beginners
This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.
本文围绕 mcp-for-beginners 开源课程 03-llm-client 小节 的 Python 解决方案展开,完整讲解如何搭建运行环境、安装依赖、配置 Microsoft Foundry 模型,并逐行剖析 client.py 与 server.py 的源码调用链,让读者掌握「MCP 客户端 + LLM 工具调用」从环境准备到端到端运行的全过程。
一、示例定位:给客户端装上一个「会思考的大脑」
在前面的课程中,客户端都是显式调用服务器:自己列出工具、资源、提示词,再自己决定调用哪个。这种方式对最终用户并不友好——用户并不关心你用的是不是 MCP,他们只希望用自然语言和系统对话。
03-llm-client这一课的核心思路,就是在客户端里接入一个 LLM,让用户用一句话(例如「Add 2 to 20」)就能触发服务器上的add工具。整体交互流程分为四步:
- 与 MCP 服务器建立连接;
- 列出服务器的能力(resources、tools、prompts),并保存其 schema;
- 把 MCP 工具转换成 LLM 能理解的 function-calling 格式;
- 把用户提示词连同工具定义一起交给 LLM,再由客户端执行 LLM 建议调用的工具。
Python 解决方案位于 solution/python 目录,包含三个文件:
| 文件 | 作用 |
|---|---|
| server.py | 基于 FastMCP 的演示服务器,暴露add工具与greeting动态资源 |
| client.py | 通过 stdio 连接服务器的 MCP 客户端,内置 LLM 工具调用逻辑 |
| README.md | 运行该示例的分步操作指南(即本文主体) |
二、第 0 步:创建 Python 虚拟环境
示例建议使用uv管理依赖,但这并非必需,你也可以直接用venv。运行前先创建一个独立的虚拟环境,避免污染全局 Python 环境:
python -m venv venvuv是可选的加速工具;如果本机已安装,也可以直接用uv venv创建环境、用uv pip install安装依赖,其余流程保持一致。
三、第 1 步:激活虚拟环境
激活命令随操作系统不同而不同:
Windows(PowerShell / CMD):
venv\Scripts\activateLinux / macOS:
source venv/bin/activate
激活后,命令行提示符前会出现(venv)前缀,说明后续的pip install与python client.py都将运行在隔离环境中。原文档中写作venv\Scrips\activate,这是 Windows 路径下Scripts目录的笔误,实际目录名为Scripts。
四、第 2 步:安装依赖
pip install "mcp[cli]" pip install openai pip install azure-ai-inference三个包各司其职:
mcp[cli]:MCP 官方 Python SDK,[cli]额外安装mcp命令行工具。它是 client.py 中ClientSession、StdioServerParameters、stdio_client的来源,也是启动服务器所用命令mcp run server.py的来源;openai:OpenAI 官方 Python 客户端。示例用它连接 Azure OpenAI / Microsoft Foundry 的 OpenAI 兼容端点,完成 function-calling 请求(client.py);azure-ai-inference:Azure AI Inference SDK,可用于访问 Foundry 部署的模型,示例将其一并装入环境供扩展使用。
依赖安装后,确保
mcp命令可用:mcp --help。因为StdioServerParameters的command字段直接指定了可执行文件mcp(client.py),若mcp不在 PATH 中,客户端将无法拉起服务器进程。
五、第 3 步:配置 Microsoft Foundry 模型
运行示例前必须有一个可用的 LLM 部署。按照父课程 03-llm-client/README.md 的说明:在 Microsoft Foundry 中部署一个当前活跃的模型(例如gpt-5.1),然后设置以下环境变量:
export AZURE_OPENAI_ENDPOINT="https://<resource-name>.openai.azure.com" export AZURE_OPENAI_API_KEY="<api-key>" export AZURE_OPENAI_DEPLOYMENT="gpt-5.1"关键点:
AZURE_OPENAI_DEPLOYMENT是部署名,可能与底层模型名不同,API 调用时用的是部署名;- 选择模型前建议查阅 Microsoft Foundry 的模型退役计划(model retirement schedule),避免选中已停用或即将停用的模型;
- client.py 中
os.getenv("AZURE_OPENAI_DEPLOYMENT", "gpt-5.1")表明:即使不设置该变量,也会回退到默认值gpt-5.1;但AZURE_OPENAI_ENDPOINT与AZURE_OPENAI_API_KEY是硬性要求,未设置会直接抛KeyError。
六、第 4 步:运行示例并解读输出
python client.py正常运行时,输出与下面的日志结构一致:
LISTING RESOURCES Resource: ('meta', None) Resource: ('nextCursor', None) Resource: ('resources', []) INFO Processing request of type ListToolsRequest server.py:534 LISTING TOOLS Tool: add Tool {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}} CALLING LLM TOOL: {'function': {'arguments': '{"a":2,"b":20}', 'name': 'add'}, 'id': 'call_BCbyoCcMgq0jDwR8AuAF9QY3', 'type': 'function'} [05/08/25 21:04:55] INFO Processing request of type CallToolRequest server.py:534 TOOLS result: [TextContent(type='text', text='22', annotations=None)]这段日志完整对应了 client.py 的执行顺序:
- LISTING RESOURCES:
session.list_resources()列出服务器资源。示例服务器上注册的是greeting://{name}动态资源,因此返回的resources列表为空,仅打印分页元数据(meta、nextCursor); - LISTING TOOLS:
session.list_tools()列出工具。服务器通过 FastMCP 暴露了一个add(a: int, b: int) -> int工具(server.py),所以这里打印出工具名add及其输入 schema:{'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}; - CALLING LLM:客户端把提示词
"Add 2 to 20"与转换后的工具定义一起交给 LLM; - TOOL:LLM 返回一个 function call,
name=add、arguments={"a":2,"b":20}; - TOOLS result:客户端通过
session.call_tool("add", arguments={"a":2,"b":20})调用服务器工具,得到TextContent(text='22'),即2 + 20 = 22。
日志中server.py:534一行来自 MCP SDK 内部的日志输出(INFO Processing request of type ListToolsRequest / CallToolRequest),表明服务器端确实接收并处理了客户端的协议请求,可用于观察 stdio 传输的实时交互。
七、源码级原理:客户端是如何「指使」LLM 调用工具的
7.1 服务器端:FastMCP 声明式定义
server.py 只有 20 行左右,用 FastMCP 声明了两个能力:
mcp = FastMCP("Demo") @mcp.tool() def add(a: int, b: int) -> int: """Add two numbers""" return a + b @mcp.resource("greeting://{name}") def get_greeting(name: str) -> str: """Get a personalized greeting""" return f"Hello, {name}!"@mcp.tool()装饰器会把 Python 函数的类型注解与 docstring 自动转换为 MCP 协议中的inputSchema(JSON Schema),这正是客户端list_tools()返回properties的直接来源;@mcp.resource("greeting://{name}")则注册了一个模板化动态资源。这也解释了为什么上一步日志中工具的 schema 里a、b被标记为type: integer。
7.2 客户端:从「列工具」到「调工具」的完整调用链
client.py 的关键链路:
- 建立 stdio 连接:
StdioServerParameters(command="mcp", args=["run", "server.py"])定义子进程启动方式,stdio_client()启动服务器进程并返回读写流,ClientSession在initialize()后完成协议握手(client.py); - 能力枚举:
list_resources()、list_tools()分别拉取服务器资源与工具(client.py); - schema 转换:
convert_to_llm_tool(tool)把 MCP 工具包装成 OpenAI 兼容的 function 定义——type: "function"、name、description、parameters(取自inputSchema["properties"])(client.py); - LLM 决策:
call_llm(prompt, functions)用 OpenAI 客户端调用chat.completions.create,将tools=functions传给模型,随后解析response_message.tool_calls,把模型建议的工具名与参数(json.loads解析 arguments)收集到functions_to_call列表(client.py); - 执行工具:遍历
functions_to_call,逐个session.call_tool(f["name"], arguments=f["args"])回传服务器执行,并打印结果内容(client.py)。
值得注意的细节:OpenAI 客户端的base_url由os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/') + '/openai/v1/'拼成(client.py),即先去除端点尾部的斜杠再追加/openai/v1/,这是 Azure OpenAI / Foundry 的 OpenAI 兼容路由约定;max_completion_tokens=1000限制单次生成的最大 token 数。
7.3 同源多语言实现
同一套「列出 → 转换 → LLM 决策 → 执行」的流程在仓库中还有 TypeScript、.NET、Java(LangChain4j)、Rust 版本:
- TypeScript 方案:solution/typescript/src/client.ts
- .NET 方案:solution/dotnet/Program.cs
- Java 方案:solution/java/src/main/java/com/microsoft/mcp/sample/client/LangChain4jClient.java
- Rust 方案:solution/rust/src/main.rs
Java 与 Rust 版本还展示了进阶做法:Java 通过 LangChain4j 的McpToolProvider自动发现与转换工具;Rust 通过process_llm_response把工具结果回填消息历史后继续与 LLM 多轮对话,直到模型不再请求工具调用。相比之下,Python 示例刻意保持最小化,便于初学者聚焦理解核心概念。
八、常见问题排查
mcp: command not found:mcp[cli]未安装成功或虚拟环境未激活,重新执行激活与安装步骤;KeyError: 'AZURE_OPENAI_ENDPOINT':环境变量未设置。确认已按第五节执行export,且在同一终端会话中运行python client.py;- 模型选择错误:
AZURE_OPENAI_DEPLOYMENT填的是 Foundry 中的部署名而非模型名,且需选择仍在退役计划有效期内的活跃模型; - 输出中没有
CALLING LLM:说明程序在 LLM 调用前异常退出,优先检查网络连通性与 API Key 权限; - Windows 激活失败:确认路径是
venv\Scripts\activate(注意是Scripts而非Scrips),或改用venv\Scripts\activate.bat。
九、小结与延伸
通过这个示例,你可以完整掌握「MCP 客户端 + LLM」的最小可用实现:虚拟环境搭建、依赖安装、Foundry 模型配置、四步调用工作流,以及 MCP 工具 schema 与 OpenAI function-calling 格式之间的转换。这正是课程 Key Takeaways 强调的两点——给客户端加 LLM 能极大改善用户体验,以及必须把 MCP 服务器的返回格式转换为 LLM 能理解的工具定义。
完成本示例后,可以继续挑战课程的 Assignment:给服务器追加更多工具,并用不同的自然语言提示词验证客户端能否动态触发对应工具;也可以前往 04-vscode 学习如何在 Visual Studio Code 中消费 MCP 服务器,或参考 samples/python 查看更完整的 Python 计算器示例。
- 教程
- 文档
- 人工智能
【免费下载链接】mcp-for-beginners
This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.
相关推荐
N_m3u8DL-RE 完整指南:HLS/DASH/MSS 流媒体一键下载、加密解密与直播录制
N_m3u8DL RE 完整指南:HLS/DASH/MSS 流媒体一键下载、加密解密与直播录制 N_m3u8DL RE 是一款跨平台命令行流媒体下载工具,用于下
教程文档人工智能MCP Sampling 实战:在 Python 服务端中借助客户端 LLM 生成内容(mcp-for-beginners 第 14 课)
MCP Sampling 实战:在 Python 服务端中借助客户端 LLM 生成内容(mcp for beginners 第 14 课) 本文基于 mcp f
教程文档人工智能mcp-for-beginners 实战:使用 .NET 构建接入 LLM 的 MCP 客户端
mcp for beginners 实战:使用 .NET 构建接入 LLM 的 MCP 客户端 在本篇指南中,你将基于 mcp for beginners 开源
教程文档人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考