diff --git a/README.md b/README.md
index b72ad20..64bf03d 100644
--- a/README.md
+++ b/README.md
@@ -1,46 +1,46 @@
-# The Model Context Protocol (MCP) Course
+# 模型上下文协议 (MCP) 课程

-If you like the course, **don't hesitate to ⭐ star this repository**. This helps us to **make the course more visible 🤗**.
+如果您喜欢这个课程,**请不要犹豫给这个仓库点个 ⭐ star**。这有助于我们**提高课程的可见度 🤗**。
-## Content
+## 内容
-The course is divided into 4 units. These will take you from **the basics of Model Context Protocol to a final project implementing MCP in an AI application**.
+本课程分为 4 个单元。这些单元将带您从**模型上下文协议的基础知识到最终在 AI 应用中实现 MCP 的项目**。
-Sign up here (it's free) 👉 [Coming Soon]
+在这里注册(免费)👉 [即将推出]
-You can access the course here 👉 [Coming Soon]
+您可以在这里访问课程 👉 [即将推出]
-| Unit | Topic | Description |
+| 单元 | 主题 | 描述 |
| ------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
-| 0 | Welcome to the Course | Welcome, guidelines, necessary tools, and course overview. |
-| 1 | Introduction to Model Context Protocol | Definition of MCP, key concepts, and its role in connecting AI models with external data and tools. |
-| 2 | Building with MCP: Practical Development | Learn to implement MCP clients and servers using available SDKs and frameworks. |
+| 0 | 欢迎来到课程 | 欢迎、指南、必要工具和课程概述。 |
+| 1 | 模型上下文协议简介 | MCP 的定义、关键概念及其在连接 AI 模型与外部数据和工具中的作用。 |
+| 2 | 使用 MCP 进行开发:实践开发 | 学习使用可用的 SDK 和框架实现 MCP 客户端和服务器。 |
-## Prerequisites
+## 先决条件
-* Basic understanding of AI and LLM concepts
-* Familiarity with software development principles and API concepts
-* Experience with at least one programming language (Python or TypeScript examples will be emphasized)
+* 对 AI 和 LLM 概念的基本理解
+* 熟悉软件开发原则和 API 概念
+* 至少掌握一种编程语言(将重点介绍 Python 或 TypeScript 示例)
-## Contribution Guidelines
+## 贡献指南
-If you want to contribute to this course, you're welcome to do so. Feel free to open an issue or submit a pull request. For specific contributions, here are some guidelines:
+如果您想为这个课程做出贡献,我们非常欢迎。您可以随时提出 issue 或提交 pull request。对于具体的贡献,以下是一些指南:
-### Small typo and grammar fixes
+### 小错误和语法修正
-If you find a small typo or grammar mistake, please fix it yourself and submit a pull request. This is very helpful for students.
+如果您发现小错误或语法错误,请自行修复并提交 pull request。这对学生非常有帮助。
-### New unit
+### 新单元
-If you want to add a new unit, **please create an issue in the repository, describe the unit, and why it should be added**. We will discuss it and if it's a good addition, we can collaborate on it.
+如果您想添加新单元,**请在仓库中创建一个 issue,描述该单元以及为什么应该添加它**。我们将讨论它,如果这是一个好的补充,我们可以一起合作。
-## Citing the project
+## 引用项目
-To cite this repository in publications:
+在出版物中引用此仓库:
```
@misc{mcp-course,
diff --git a/units/zh-CN/.DS_Store b/units/zh-CN/.DS_Store
new file mode 100644
index 0000000..0cf3878
Binary files /dev/null and b/units/zh-CN/.DS_Store differ
diff --git a/units/zh-CN/_toctree.yml b/units/zh-CN/_toctree.yml
new file mode 100644
index 0000000..6fb1c0d
--- /dev/null
+++ b/units/zh-CN/_toctree.yml
@@ -0,0 +1,46 @@
+- title: "0. 欢迎来到 MCP 课程"
+ sections:
+ - local: unit0/introduction
+ title: 欢迎来到 MCP 课程
+
+- title: "1. 模型上下文协议简介"
+ sections:
+ - local: unit1/introduction
+ title: 模型上下文协议 (MCP) 简介
+ - local: unit1/key-concepts
+ title: 关键概念和术语
+ - local: unit1/architectural-components
+ title: 架构组件
+ - local: unit1/communication-protocol
+ title: 通信协议
+ - local: unit1/capabilities
+ title: 理解 MCP 能力
+ - local: unit1/sdk
+ title: MCP SDK
+ - local: unit1/mcp-clients
+ title: MCP 客户端
+ - local: unit1/gradio-mcp
+ title: Gradio MCP 集成
+
+- title: "2. 用例:端到端 MCP 应用"
+ sections:
+ - local: unit2/introduction
+ title: MCP 应用开发简介
+ - local: unit2/gradio-server
+ title: 构建 Gradio MCP 服务器
+ - local: unit2/clients
+ title: 在应用中使用 MCP 客户端
+ - local: unit2/gradio-client
+ title: 使用 Gradio 构建 MCP 客户端
+ - local: unit2/tiny-agents
+ title: 使用 TypeScript 构建微型代理
+
+- title: "3. 用例:高级 MCP 开发"
+ sections:
+ - local: unit3/introduction
+ title: 即将推出
+
+- title: "额外单元"
+ sections:
+ - local: unit4/introduction
+ title: 即将推出
diff --git a/units/zh-CN/unit0/introduction.mdx b/units/zh-CN/unit0/introduction.mdx
new file mode 100644
index 0000000..d2e5dcc
--- /dev/null
+++ b/units/zh-CN/unit0/introduction.mdx
@@ -0,0 +1,139 @@
+# 欢迎来到 🤗 模型上下文协议 (MCP) 课程
+
+
+
+欢迎来到当今AI领域最激动人心的主题:**模型上下文协议(MCP)**!
+
+这门免费课程将带您踏上一段旅程,**从初学者到专业人士**,帮助您理解、使用并构建MCP应用程序。
+
+第一单元将帮助您入门:
+
+* 了解**课程大纲**。
+* **获取更多关于认证流程和时间安排的信息**。
+* 认识课程背后的团队。
+* 创建您的**账户**。
+* **加入我们的Discord服务器**,与同学和我们见面。
+
+让我们开始吧!
+
+## 这门课程会带给您什么?
+
+在本课程中,您将:
+
+* 📖 在**理论、设计和实践**方面学习模型上下文协议。
+* 🧑💻 学习**使用成熟的MCP SDK和框架**。
+* 💾 **分享您的项目**并探索社区创建的应用。
+* 🏆 参与挑战,在其中**将您的MCP实现与其他学生的进行评估**。
+* 🎓 通过完成作业**获得结业证书**。
+
+以及更多!
+
+在课程结束时,您将理解**MCP如何工作,以及如何构建利用外部数据和工具的AI应用,并使用最新MCP标准**。
+
+别忘了[**注册课程!**](https://huggingface.co/mcp-course)
+
+## 课程内容是什么样的?
+
+课程由以下部分组成:
+
+* _基础单元_:在这里您将学习MCP的**理论概念**。
+* _实践操作_:您将学习**使用成熟的MCP SDK**来构建应用程序。这些动手部分将有预配置的环境。
+* _用例作业_:您将应用所学概念来解决您选择的真实世界问题。
+* _合作项目_:我们与Hugging Face的合作伙伴协作,为您提供最新的MCP实现和工具。
+
+这门**课程是一个不断发展的项目,将根据您的反馈和贡献而演进!**欢迎在GitHub上提出问题和PR,并参与我们Discord服务器上的讨论。
+
+学完课程后,您也可以 👉 使用此表单[反馈表单链接]发送您的反馈
+
+## 课程大纲是什么?
+
+以下是**课程的总体大纲**。每个单元发布时会有更详细的主题列表。
+
+| 章节 | 主题 | 描述 |
+| ------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
+| 0 | 入门 | 为您设置将要使用的工具和平台。 |
+| 1 | MCP基础、架构和核心概念 | 解释模型上下文协议的核心概念、架构和组件。展示使用MCP的简单用例。 |
+| 2 | 端到端用例:MCP实战 | 构建一个简单的端到端MCP应用程序,您可以与社区分享。 |
+| 3 | 部署用例:MCP实战 | 使用Hugging Face生态系统和合作伙伴服务构建部署的MCP应用程序。 |
+| 4 | 附加单元 | 帮助您更好地利用课程的附加单元,与合作伙伴的库和服务一起工作。 |
+
+## 课程有哪些先决条件?
+
+要能够跟上这门课程,您应该具备:
+
+* 对AI和LLM概念的基本理解
+* 熟悉软件开发原则和API概念
+* 至少一种编程语言的经验(将展示Python或TypeScript示例)
+
+如果您不具备这些条件,不用担心!以下是一些可以帮助您的资源:
+
+* [LLM课程](https://huggingface.co/learn/llm-course/)将指导您了解使用和构建LLM的基础知识。
+* [Agents课程](https://huggingface.co/learn/agents-course/)将指导您使用LLM构建AI代理。
+
+
+
+上述课程本身并非先决条件,所以如果您理解LLM和代理的概念,您现在就可以开始这门课程!
+
+
+
+## 我需要哪些工具?
+
+您只需要2样东西:
+
+* _一台电脑_,带有互联网连接。
+* 一个_账户_:用于访问课程资源和创建项目。如果您还没有账户,可以在[这里](https://huggingface.co/join)创建一个(免费)。
+
+## 认证流程
+
+您可以选择_以审核模式_学习本课程,或者完成活动并_获得我们将颁发的两种证书之一_。如果您以审核模式学习,您可以参与所有挑战并完成作业(如果您想的话),并且**您不需要通知我们**。
+
+认证流程**完全免费**:
+
+* _获得基础认证_:您需要完成课程的第1单元。这适用于想了解MCP最新趋势的学生,而不需要构建完整应用程序。
+* _获得结业证书_:您需要完成用例单元(2和3)。这适用于想构建完整应用并与社区分享的学生。
+
+## 推荐的学习节奏是什么?
+
+本课程的每个章节设计为**在1周内完成,每周大约需要3-4小时的工作**。
+
+由于有截止日期,我们为您提供推荐的学习节奏:
+
+
+
+## 如何充分利用这门课程?
+
+要充分利用这门课程,我们有一些建议:
+
+1. 加入Discord的学习小组:小组学习总是更容易。为此,您需要加入我们的discord服务器并验证您的账户。
+2. **做测验和作业**:学习的最佳方式是通过动手实践和自我评估。
+3. **制定计划保持同步**:您可以使用下面我们推荐的节奏安排或创建您自己的计划。
+
+
+
+## 我们是谁
+
+关于作者:
+
+### Ben Burtenshaw
+
+Ben是Hugging Face的机器学习工程师,专注于构建LLM应用程序,使用后训练和代理方法。
+
+
+
+
+
+
+
+## 我发现了bug,或者我想改进课程
+
+欢迎**贡献** 🤗
+
+* 如果您_在笔记本中发现了bug 🐛_,请提出问题并**描述问题**。
+* 如果您_想改进课程_,您可以提交Pull Request。
+* 如果您_想添加完整的章节或新单元_,最好的方法是提出问题并**在开始编写之前描述您想添加的内容,以便我们可以指导您**。
+
+## 我还有问题
+
+请在我们的discord服务器 #mcp-course-questions 中提问。
+
+现在您已经掌握了所有信息,让我们开始吧 ⛵
\ No newline at end of file
diff --git a/units/zh-CN/unit1/architectural-components.mdx b/units/zh-CN/unit1/architectural-components.mdx
new file mode 100644
index 0000000..a7188d1
--- /dev/null
+++ b/units/zh-CN/unit1/architectural-components.mdx
@@ -0,0 +1,85 @@
+# MCP的架构组件
+
+在上一节中,我们讨论了MCP的关键概念和术语。现在,让我们深入了解组成MCP生态系统的架构组件。
+
+## 宿主、客户端和服务器
+
+模型上下文协议(MCP)建立在客户端-服务器架构上,实现了AI模型与外部系统之间的结构化通信。
+
+
+
+MCP架构由三个主要组件组成,每个组件都有明确定义的角色和职责:宿主、客户端和服务器。我们在上一节中简要提到了这些,但现在让我们深入了解每个组件及其职责。
+
+### 宿主
+
+**宿主**是面向用户的AI应用程序,终端用户直接与其交互。
+
+例子包括:
+- AI聊天应用,如OpenAI ChatGPT或Anthropic的Claude Desktop
+- AI增强的IDE,如Cursor,或像Continue.dev这样的工具集成
+- 在LangChain或smolagents等库中构建的自定义AI代理和应用
+
+宿主的职责包括:
+- 管理用户交互和权限
+- 通过MCP客户端发起与MCP服务器的连接
+- 协调用户请求、LLM处理和外部工具之间的整体流程
+- 以连贯的格式向用户呈现结果
+
+在大多数情况下,用户将根据自己的需求和偏好选择宿主应用。例如,开发人员可能会选择Cursor来利用其强大的代码编辑功能,而领域专家可能会使用在smolagents中构建的自定义应用。
+
+### 客户端
+
+**客户端**是宿主应用程序内部的一个组件,负责管理与特定MCP服务器的通信。其主要特点包括:
+
+- 每个客户端与单个服务器保持1:1连接
+- 处理MCP通信的协议级细节
+- 充当宿主逻辑和外部服务器之间的中介
+
+### 服务器
+
+**服务器**是通过MCP协议向AI模型公开功能的外部程序或服务。服务器:
+
+- 提供对特定外部工具、数据源或服务的访问
+- 作为现有功能的轻量级包装器
+- 可以在本地(与宿主在同一台机器上)或远程(通过网络)运行
+- 以客户端可以发现和使用的标准化格式公开其功能
+
+## 通信流程
+
+让我们来研究一下在典型的MCP工作流程中这些组件是如何交互的:
+
+
+
+在下一节中,我们将通过实际示例深入了解实现这些组件的通信协议。
+
+
+
+1. **用户交互**:用户与**宿主**应用程序交互,表达意图或查询。
+
+2. **宿主处理**:**宿主**处理用户的输入,可能使用LLM来理解请求并确定可能需要哪些外部功能。
+
+3. **客户端连接**:**宿主**指示其**客户端**组件连接到适当的服务器。
+
+4. **功能发现**:**客户端**查询**服务器**以发现它提供的功能(工具、资源、提示)。
+
+5. **功能调用**:根据用户需求或LLM的判断,宿主指示**客户端**调用**服务器**的特定功能。
+
+6. **服务器执行**:**服务器**执行请求的功能并将结果返回给**客户端**。
+
+7. **结果整合**:**客户端**将这些结果返回给**宿主**,后者将它们整合到LLM的上下文中或直接呈现给用户。
+
+此架构的一个关键优势是其模块化。单个**宿主**可以通过不同的**客户端**同时连接到多个**服务器**。新的**服务器**可以添加到生态系统中,而不需要对现有**宿主**进行更改。不同**服务器**的功能可以轻松组合。
+
+
+
+正如我们在上一节中讨论的,这种模块化将传统的M×N集成问题(M个AI应用程序连接到N个工具/服务)转变为更易管理的M+N问题,其中每个宿主和服务器只需实现MCP标准一次。
+
+
+
+这种架构看起来可能很简单,但其力量在于通信协议的标准化和组件之间责任的明确分离。这种设计允许形成一个凝聚力强的生态系统,AI模型可以与不断增长的外部工具和数据源无缝连接。
+
+## 结论
+
+这些交互模式受到几个关键原则的指导,这些原则塑造了MCP的设计和演进。协议强调**标准化**,提供AI连接的通用协议,同时保持**简洁性**,保持核心协议简单但启用高级功能。优先考虑**安全性**,要求用户明确批准敏感操作,并使功能可发现。协议设计具有**可扩展性**,通过版本控制和功能协商支持演进,并确保跨不同实现和环境的**互操作性**。
+
+在下一节中,我们将探讨使这些组件能够有效协同工作的通信协议。
\ No newline at end of file
diff --git a/units/zh-CN/unit1/capabilities.mdx b/units/zh-CN/unit1/capabilities.mdx
new file mode 100644
index 0000000..51c4071
--- /dev/null
+++ b/units/zh-CN/unit1/capabilities.mdx
@@ -0,0 +1,243 @@
+# 了解 MCP 功能
+
+MCP 服务器通过通信协议向客户端暴露多种功能。这些功能分为四大主要类别,每类具有不同的特性和使用场景。让我们探索构成 MCP 功能基础的这些核心原语。
+
+
+
+在本节中,我们将以与框架无关的函数形式展示示例,分别用不同语言编写。这是为了专注于概念及其协作方式,而不是任何框架的复杂性。
+
+在接下来的单元中,我们将展示这些概念如何在 MCP 特定代码中实现。
+
+
+
+## 工具
+
+工具是 AI 模型可以通过 MCP 协议调用的可执行函数或动作。
+
+- **控制**:工具通常是**模型控制**的,这意味着 AI 模型(LLM)根据用户请求和上下文决定何时调用它们。
+- **安全性**:由于工具执行可能带来副作用,工具执行可能具有危险性。因此,它们通常需要用户的明确批准。
+- **使用场景**:发送消息、创建工单、查询 API、执行计算。
+
+**示例**:一个获取指定位置当前天气数据的天气工具:
+
+
+
+
+```python
+def get_weather(location: str) -> dict:
+ """获取指定位置的当前天气。"""
+ # 连接到天气 API 并获取数据
+ return {
+ "temperature": 72,
+ "conditions": "晴天",
+ "humidity": 45
+ }
+```
+
+
+
+
+```javascript
+function getWeather(location) {
+ // 连接到天气 API 并获取数据
+ return {
+ temperature: 72,
+ conditions: '晴天',
+ humidity: 45
+ };
+}
+```
+
+
+
+
+## 资源
+
+资源提供对数据源的只读访问,允许 AI 模型检索上下文而无需执行复杂逻辑。
+
+- **控制**:资源是**应用控制**的,这意味着主机应用程序通常决定何时访问它们。
+- **性质**:它们专为数据检索设计,计算量最小,类似于 REST API 中的 GET 端点。
+- **安全性**:由于它们是只读的,通常比工具具有较低的安全风险。
+- **使用场景**:访问文件内容、检索数据库记录、读取配置信息。
+
+**示例**:一个提供文件内容访问的资源:
+
+
+
+
+```python
+def read_file(file_path: str) -> str:
+ """读取指定路径文件的内容。"""
+ with open(file_path, 'r') as f:
+ return f.read()
+```
+
+
+
+
+```javascript
+function readFile(filePath) {
+ // 使用 fs.readFile 读取文件内容
+ const fs = require('fs');
+ return new Promise((resolve, reject) => {
+ fs.readFile(filePath, 'utf8', (err, data) => {
+ if (err) {
+ reject(err);
+ return;
+ }
+ resolve(data);
+ });
+ });
+}
+```
+
+
+
+
+## 提示
+
+提示是预定义的模板或工作流,用于指导用户、AI 模型与服务器功能之间的交互。
+
+- **控制**:提示是**用户控制**的,通常在主机应用程序的 UI 中作为选项呈现。
+- **目的**:它们为可用工具和资源的最佳使用提供结构化的交互。
+- **选择**:用户通常在 AI 模型开始处理之前选择一个提示,为交互设置上下文。
+- **使用场景**:常见工作流、专用任务模板、引导交互。
+
+**示例**:一个用于生成代码审查的提示模板:
+
+
+
+
+```python
+def code_review(code: str, language: str) -> list:
+ """为提供的代码片段生成代码审查。"""
+ return [
+ {
+ "role": "system",
+ "content": f"你是一个审查 {language} 代码的代码审查者。提供详细的审查,突出最佳实践、潜在问题和改进建议。"
+ },
+ {
+ "role": "user",
+ "content": f"请审查这段 {language} 代码:\n\n```{language}\n{code}\n```"
+ }
+ ]
+```
+
+
+
+
+```javascript
+function codeReview(code, language) {
+ return [
+ {
+ role: 'system',
+ content: `你是一个审查 ${language} 代码的代码审查者。提供详细的审查,突出最佳实践、潜在问题和改进建议。`
+ },
+ {
+ role: 'user',
+ content: `请审查这段 ${language} 代码:\n\n\`\`\`${language}\n${code}\n\`\`\``
+ }
+ ];
+}
+```
+
+
+
+
+## 采样
+
+采样允许服务器请求客户端(具体为主机应用程序)执行 LLM 交互。
+
+- **控制**:采样是**服务器发起**的,但需要客户端/主机协助。
+- **目的**:它支持服务器驱动的代理行为以及可能的递归或多步骤交互。
+- **安全性**:与工具类似,采样操作通常需要用户批准。
+- **使用场景**:复杂的多步骤任务、自主代理工作流、交互过程。
+
+**示例**:服务器可能请求客户端分析其处理的数据:
+
+
+
+
+```python
+def request_sampling(messages, system_prompt=None, include_context="none"):
+ """从客户端请求 LLM 采样。"""
+ # 在实际实现中,这将向客户端发送请求
+ return {
+ "role": "assistant",
+ "content": "对提供的数据的分析..."
+ }
+```
+
+
+
+
+```javascript
+function requestSampling(messages, systemPrompt = null, includeContext = 'none') {
+ // 在实际实现中,这将向客户端发送请求
+ return {
+ role: 'assistant',
+ content: '对提供的数据的分析...'
+ };
+}
+
+function handleSamplingRequest(request) {
+ const { messages, systemPrompt, includeContext } = request;
+ // 在实际实现中,这将处理请求并返回响应
+ return {
+ role: 'assistant',
+ content: '对采样请求的响应...'
+ };
+}
+```
+
+
+
+
+采样流程遵循以下步骤:
+1. 服务器向客户端发送 `sampling/createMessage` 请求
+2. 客户端审查请求并可以修改它
+3. 客户端从 LLM 采样
+4. 客户端审查完成结果
+5. 客户端将结果返回给服务器
+
+
+
+这种人工参与设计确保用户对 LLM 看到和生成的内容保持控制。在实现采样时,提供清晰、结构良好的提示并包含相关上下文非常重要。
+
+
+
+## 功能如何协同工作
+
+让我们看看这些功能如何协同工作以实现复杂交互。在下表中,我们概述了功能、控制者、控制方向以及一些其他细节。
+
+| 功能 | 控制者 | 方向 | 副作用 | 需要批准 | 典型使用场景 |
+|------------|---------------|------------------|--------------|----------|-----------------------------------|
+| 工具 | 模型 (LLM) | 客户端 → 服务器 | 是(可能) | 是 | 动作、API 调用、数据操作 |
+| 资源 | 应用程序 | 客户端 → 服务器 | 否(只读) | 通常不需要 | 数据检索、上下文收集 |
+| 提示 | 用户 | 服务器 → 客户端 | 否 | 否(用户选择) | 引导工作流、专用模板 |
+| 采样 | 服务器 | 服务器 → 客户端 → 服务器 | 间接 | 是 | 多步骤任务、代理行为 |
+
+这些功能设计为以互补的方式协同工作:
+
+1. 用户可能选择一个**提示**以启动专用工作流
+2. 提示可能包括来自**资源**的上下文
+3. 在处理过程中,AI 模型可能调用**工具**执行特定动作
+4. 对于复杂操作,服务器可能使用**采样**请求额外的 LLM 处理
+
+这些原语之间的区别为 MCP 交互提供了清晰的结构,使 AI 模型能够访问信息、执行动作并参与复杂的工作流,同时保持适当的控制边界。
+
+## 发现过程
+
+MCP 的一个关键特性是动态功能发现。当客户端连接到服务器时,它可以通过特定的列表方法查询可用的工具、资源和提示:
+
+- `tools/list`:发现可用工具
+- `resources/list`:发现可用资源
+- `prompts/list`:发现可用提示
+
+这种动态发现机制使客户端能够适应每个服务器提供的特定功能,而无需对服务器功能进行硬编码。
+
+## 结论
+
+理解这些核心原语对于有效使用 MCP 至关重要。通过提供具有清晰控制边界的不同类型功能,MCP 使 AI 模型与外部系统之间的强大交互成为可能,同时保持适当的安全性和控制机制。
+
+在下一节中,我们将探讨 Gradio 如何与 MCP 集成,为这些功能提供易于使用的界面。
\ No newline at end of file
diff --git a/units/zh-CN/unit1/communication-protocol.mdx b/units/zh-CN/unit1/communication-protocol.mdx
new file mode 100644
index 0000000..7726b3b
--- /dev/null
+++ b/units/zh-CN/unit1/communication-protocol.mdx
@@ -0,0 +1,223 @@
+# 通信协议
+
+MCP 定义了一个标准化的通信协议,使客户端和服务器能够以一致、可预测的方式交换消息。这种标准化对于社区内的互操作性至关重要。在本节中,我们将探讨 MCP 中使用的协议结构和传输机制。
+
+
+
+我们正在深入了解 MCP 协议的细节。虽然在使用 MCP 构建时不需要了解所有这些内容,但了解它的存在和工作原理是很有帮助的。
+
+
+
+## JSON-RPC:基础
+
+MCP 的核心是使用 **JSON-RPC 2.0** 作为客户端和服务器之间所有通信的消息格式。JSON-RPC 是一个轻量级的远程过程调用协议,使用 JSON 编码,这使得它:
+
+- 人类可读且易于调试
+- 语言无关,支持在任何编程环境中实现
+- 成熟稳定,具有明确的规范和广泛的采用
+
+
+
+该协议定义了三种类型的消息:
+
+### 1. 请求
+
+从客户端发送到服务器以启动操作。请求消息包括:
+- 唯一标识符(`id`)
+- 要调用的方法名称(例如,`tools/call`)
+- 方法的参数(如果有)
+
+请求示例:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "tools/call",
+ "params": {
+ "name": "weather",
+ "arguments": {
+ "location": "San Francisco"
+ }
+ }
+}
+```
+
+### 2. 响应
+
+从服务器发送到客户端以回复请求。响应消息包括:
+- 与相应请求相同的 `id`
+- 成功时的 `result` 或失败时的 `error`
+
+成功响应示例:
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "temperature": 62,
+ "conditions": "Partly cloudy"
+ }
+}
+```
+
+错误响应示例:
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "error": {
+ "code": -32602,
+ "message": "Invalid location parameter"
+ }
+}
+```
+
+### 3. 通知
+
+不需要响应的单向消息。通常从服务器发送到客户端,以提供更新或事件通知。
+
+通知示例:
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "progress",
+ "params": {
+ "message": "Processing data...",
+ "percent": 50
+ }
+}
+```
+
+## 传输机制
+
+JSON-RPC 定义了消息格式,但 MCP 还指定了这些消息如何在客户端和服务器之间传输。支持两种主要的传输机制:
+
+### stdio(标准输入/输出)
+
+stdio 传输用于本地通信,客户端和服务器在同一台机器上运行:
+
+主机应用程序将服务器作为子进程启动,并通过写入其标准输入(stdin)和从其标准输出(stdout)读取来与之通信。
+
+
+
+这种传输的**使用场景**包括本地工具,如文件系统访问或运行本地脚本。
+
+
+
+这种传输的主要**优势**是简单,不需要网络配置,并且由操作系统安全地沙箱化。
+
+### HTTP + SSE(服务器发送事件)/ 可流式 HTTP
+
+HTTP+SSE 传输用于远程通信,客户端和服务器可能在不同的机器上:
+
+通信通过 HTTP 进行,服务器使用服务器发送事件(SSE)通过持久连接向客户端推送更新。
+
+
+
+这种传输的**使用场景**包括连接到远程 API、云服务或共享资源。
+
+
+
+这种传输的主要**优势**是可以在网络上工作,支持与 Web 服务集成,并且与无服务器环境兼容。
+
+MCP 标准的最新更新引入或改进了"可流式 HTTP",它提供了更大的灵活性,允许服务器在需要时动态升级到 SSE 进行流式传输,同时保持与无服务器环境的兼容性。
+
+## 交互生命周期
+
+在上一节中,我们讨论了客户端(💻)和服务器(🌐)之间单个交互的生命周期。现在让我们看看在 MCP 协议上下文中,客户端和服务器之间完整交互的生命周期。
+
+MCP 协议定义了客户端和服务器之间的结构化交互生命周期:
+
+### 初始化
+
+客户端连接到服务器,它们交换协议版本和功能,服务器响应其支持的协议版本和功能。
+
+
+
+ 💻 |
+ → initialize |
+ 🌐 |
+
+
+ 💻 |
+ ← response |
+ 🌐 |
+
+
+ 💻 |
+ → initialized |
+ 🌐 |
+
+
+
+客户端通过通知消息确认初始化完成。
+
+### 发现
+
+客户端请求有关可用功能的信息,服务器响应可用工具列表。
+
+
+
+ 💻 |
+ → tools/list |
+ 🌐 |
+
+
+ 💻 |
+ ← response |
+ 🌐 |
+
+
+
+这个过程可以针对每个工具、资源或提示类型重复进行。
+
+### 执行
+
+客户端根据主机的需求调用功能。
+
+
+
+ 💻 |
+ → tools/call |
+ 🌐 |
+
+
+ 💻 |
+ ← notification (optional progress) |
+ 🌐 |
+
+
+ 💻 |
+ ← response |
+ 🌐 |
+
+
+
+### 终止
+
+当不再需要时,连接会优雅地关闭,服务器确认关闭请求。
+
+
+
+ 💻 |
+ → shutdown |
+ 🌐 |
+
+
+ 💻 |
+ ← response |
+ 🌐 |
+
+
+ 💻 |
+ → exit |
+ 🌐 |
+
+
+
+客户端发送最终的退出消息以完成终止。
+
+## 协议演进
+
+MCP 协议设计为可扩展和适应性强的。初始化阶段包括版本协商,允许协议演进时保持向后兼容性。此外,功能发现使客户端能够适应每个服务器提供的特定功能,从而在同一生态系统中支持基本和高级服务器。
diff --git a/units/zh-CN/unit1/gradio-mcp.mdx b/units/zh-CN/unit1/gradio-mcp.mdx
new file mode 100644
index 0000000..040420b
--- /dev/null
+++ b/units/zh-CN/unit1/gradio-mcp.mdx
@@ -0,0 +1,154 @@
+# Gradio MCP 集成
+
+我们已经探索了 MCP 协议的核心概念以及如何实现 MCP 服务器和客户端。在本节中,我们将通过使用 Gradio 来创建一个 MCP 服务器,让事情变得更简单!
+
+
+
+Gradio 是一个流行的 Python 库,用于快速为机器学习模型创建可自定义的 Web 界面。
+
+
+
+## Gradio 简介
+
+Gradio 允许开发者用几行 Python 代码就能为他们的模型创建用户界面。它特别适用于:
+
+- 创建演示和原型
+- 与非技术用户共享模型
+- 测试和调试模型行为
+
+通过添加 MCP 支持,Gradio 现在提供了一种直接的方式,通过标准化的 MCP 协议来暴露 AI 模型的能力。
+
+将 Gradio 与 MCP 结合使用,你可以用最少的代码创建既适合人类使用又适合 AI 访问的工具。最重要的是,Gradio 已经被 AI 社区广泛使用,所以你可以用它来与他人分享你的 MCP 服务器。
+
+## 前提条件
+
+要使用支持 MCP 的 Gradio,你需要安装带有 MCP 扩展的 Gradio:
+
+```bash
+pip install "gradio[mcp]"
+```
+
+你还需要一个支持使用 MCP 协议进行工具调用的 LLM 应用程序,比如 Cursor(被称为"MCP 主机")。
+
+## 使用 Gradio 创建 MCP 服务器
+
+让我们通过一个基本示例来了解如何使用 Gradio 创建 MCP 服务器:
+
+```python
+import gradio as gr
+
+def letter_counter(word: str, letter: str) -> int:
+ """
+ 计算单词或文本中某个字母出现的次数。
+
+ 参数:
+ word (str): 要搜索的输入文本
+ letter (str): 要搜索的字母
+
+ 返回:
+ int: 字母在文本中出现的次数
+ """
+ word = word.lower()
+ letter = letter.lower()
+ count = word.count(letter)
+ return count
+
+# 创建标准 Gradio 界面
+demo = gr.Interface(
+ fn=letter_counter,
+ inputs=["textbox", "textbox"],
+ outputs="number",
+ title="字母计数器",
+ description="输入文本和字母,计算字母在文本中出现的次数。"
+)
+
+# 启动 Gradio Web 界面和 MCP 服务器
+if __name__ == "__main__":
+ demo.launch(mcp_server=True)
+```
+
+通过这种设置,你的字母计数函数现在可以通过以下方式访问:
+
+1. 传统的 Gradio Web 界面,用于直接的人机交互
+2. 可以连接到兼容客户端的 MCP 服务器
+
+MCP 服务器将在以下地址可访问:
+```
+http://your-server:port/gradio_api/mcp/sse
+```
+
+应用程序本身仍然可以访问,它看起来像这样:
+
+
+
+## 幕后工作原理
+
+当你在 `launch()` 中设置 `mcp_server=True` 时,会发生以下几件事:
+
+1. Gradio 函数自动转换为 MCP 工具
+2. 输入组件映射到工具参数模式
+3. 输出组件决定响应格式
+4. Gradio 服务器现在也监听 MCP 协议消息
+5. 设置 JSON-RPC over HTTP+SSE 用于客户端-服务器通信
+
+## Gradio <> MCP 集成的关键特性
+
+1. **工具转换**:你的 Gradio 应用中的每个 API 端点都会自动转换为具有相应名称、描述和输入模式的 MCP 工具。要查看工具和模式,请访问 `http://your-server:port/gradio_api/mcp/schema` 或转到你的 Gradio 应用底部的"View API"链接,然后点击"MCP"。
+
+2. **环境变量支持**:有两种方式可以启用 MCP 服务器功能:
+- 在 `launch()` 中使用 `mcp_server` 参数:
+ ```python
+ demo.launch(mcp_server=True)
+ ```
+- 使用环境变量:
+ ```bash
+ export GRADIO_MCP_SERVER=True
+ ```
+
+3. **文件处理**:服务器自动处理文件数据转换,包括:
+ - 将 base64 编码的字符串转换为文件数据
+ - 处理图像文件并以正确的格式返回
+ - 管理临时文件存储
+
+ 强烈建议将输入图像和文件作为完整 URL("http://..." 或 "https://...")传递,因为 MCP 客户端并不总是能正确处理本地文件。
+
+4. **在 🤗 Spaces 上托管 MCP 服务器**:你可以在 Hugging Face Spaces 上免费发布你的 Gradio 应用程序,这将允许你拥有一个免费的托管 MCP 服务器。这是一个示例 Space:https://huggingface.co/spaces/abidlabs/mcp-tools
+
+## 故障排除提示
+
+1. **类型提示和文档字符串**:确保为你的函数提供类型提示和有效的文档字符串。文档字符串应该包含带有缩进参数名称的"Args:"块。
+
+2. **字符串输入**:如有疑问,将输入参数接受为 `str` 并在函数内部将其转换为所需类型。
+
+3. **SSE 支持**:一些 MCP 主机不支持基于 SSE 的 MCP 服务器。在这种情况下,你可以使用 `mcp-remote`:
+ ```json
+ {
+ "mcpServers": {
+ "gradio": {
+ "command": "npx",
+ "args": [
+ "mcp-remote",
+ "http://your-server:port/gradio_api/mcp/sse"
+ ]
+ }
+ }
+ }
+ ```
+
+4. **重启**:如果遇到连接问题,尝试重启你的 MCP 客户端和 MCP 服务器。
+
+## 分享你的 MCP 服务器
+
+你可以通过将你的 Gradio 应用发布到 Hugging Face Spaces 来分享你的 MCP 服务器。下面的视频展示了如何创建 Hugging Face Space。
+
+
+
+现在,你可以通过分享你的 Hugging Face Space 来与他人分享你的 MCP 服务器。
+
+## 结论
+
+Gradio 与 MCP 的集成为 MCP 生态系统提供了一个易于访问的入口点。通过利用 Gradio 的简单性和添加 MCP 的标准化,开发者可以用最少的代码快速创建既适合人类使用又适合 AI 访问的工具。
+
+随着我们在本课程中的深入,我们将探索更复杂的 MCP 实现,但 Gradio 为理解和实验该协议提供了一个很好的起点。
+
+在下一单元中,我们将更深入地探讨构建 MCP 应用程序,重点关注设置开发环境、探索 SDK 以及实现更高级的 MCP 服务器和客户端。
\ No newline at end of file
diff --git a/units/zh-CN/unit1/introduction.mdx b/units/zh-CN/unit1/introduction.mdx
new file mode 100644
index 0000000..fa9256d
--- /dev/null
+++ b/units/zh-CN/unit1/introduction.mdx
@@ -0,0 +1,33 @@
+# 模型上下文协议 (MCP) 介绍
+
+欢迎来到 MCP 课程的第一单元!在本单元中,我们将探索模型上下文协议的基础知识。
+
+## 你将学习什么
+
+在本单元中,你将:
+
+* 了解什么是模型上下文协议及其重要性
+* 学习与 MCP 相关的关键概念和术语
+* 探索 MCP 解决的集成挑战
+* 了解 MCP 的主要优势和目标
+* 通过一个简单的示例了解 MCP 集成的实际应用
+
+在本单元结束时,你将牢固掌握 MCP 的基础概念,为下一单元深入学习其架构和实现做好准备。
+
+## MCP 的重要性
+
+人工智能生态系统正在快速发展,大型语言模型(LLMs)和其他人工智能系统变得越来越强大。然而,这些模型往往受限于其训练数据,无法访问实时信息或专业工具。这种限制阻碍了人工智能系统在许多场景中提供真正相关、准确和有用响应的潜力。
+
+这就是模型上下文协议(MCP)发挥作用的地方。MCP 使人工智能模型能够连接到外部数据源、工具和环境,实现人工智能系统与更广泛的数字世界之间的无缝信息传递和能力共享。这种互操作性对于真正有用的人工智能应用的成长和采用至关重要。
+
+## 第一单元概述
+
+以下是我们在本单元将要涵盖的内容概述:
+
+1. **什么是模型上下文协议?** - 我们将首先定义 MCP 并讨论其在人工智能生态系统中的角色。
+2. **关键概念** - 我们将探索与 MCP 相关的基本概念和术语。
+3. **集成挑战** - 我们将研究 MCP 旨在解决的问题,特别是"M×N 集成问题"。
+4. **优势和目标** - 我们将讨论 MCP 的主要优势和目标,包括标准化、增强人工智能能力和互操作性。
+5. **简单示例** - 最后,我们将通过一个简单的 MCP 集成示例来了解其实际工作原理。
+
+让我们开始探索模型上下文协议的精彩世界!
\ No newline at end of file
diff --git a/units/zh-CN/unit1/key-concepts.mdx b/units/zh-CN/unit1/key-concepts.mdx
new file mode 100644
index 0000000..3bf11c3
--- /dev/null
+++ b/units/zh-CN/unit1/key-concepts.mdx
@@ -0,0 +1,88 @@
+# 核心概念和术语
+
+在深入了解模型上下文协议(Model Context Protocol)之前,理解构成MCP基础的核心概念和术语非常重要。本节将介绍支撑该协议的基本概念,并为整个课程中讨论MCP实现提供通用词汇。
+
+MCP常被描述为"AI应用的USB-C"。就像USB-C为连接各种外设到计算设备提供了标准化的物理和逻辑接口一样,MCP为连接AI模型到外部能力提供了一致的协议。这种标准化使整个生态系统受益:
+
+- **用户**可以在AI应用中享受更简单、更一致的体验
+- **AI应用开发者**可以轻松集成不断增长的工具和数据源生态系统
+- **工具和数据提供商**只需创建一个适用于多个AI应用的实现
+- 整个生态系统从提高的互操作性、创新和减少的碎片化中受益
+
+## 集成问题
+
+**M×N集成问题**指的是在没有标准化方法的情况下,将M个不同的AI应用连接到N个不同的外部工具或数据源所面临的挑战。
+
+### 没有MCP的情况(M×N问题)
+
+如果没有像MCP这样的协议,开发者需要创建M×N个自定义集成——每个AI应用与外部能力的可能配对都需要一个。
+
+
+
+每个AI应用都需要单独与每个工具/数据源集成。这是一个非常复杂且昂贵的过程,给开发者带来了很多摩擦,并产生高昂的维护成本。
+
+### 使用MCP的情况(M+N解决方案)
+
+MCP通过提供标准接口将其转变为M+N问题:每个AI应用只需实现一次MCP的客户端,每个工具/数据源只需实现一次服务器端。这大大降低了集成复杂性和维护负担。
+
+
+
+每个AI应用只需实现一次MCP的客户端,每个工具/数据源只需实现一次服务器端。
+
+## MCP核心术语
+
+现在我们已经理解了MCP解决的问题,让我们深入了解构成MCP协议的核心术语和概念。
+
+
+
+MCP是一个像HTTP或USB-C一样的标准,是连接AI应用到外部工具和数据源的协议。因此,使用标准术语对于使MCP有效工作至关重要。
+
+在记录我们的应用和与社区交流时,我们应该使用以下术语。
+
+
+
+### 组件
+
+就像HTTP中的客户端服务器关系一样,MCP也有客户端和服务器。
+
+
+
+- **主机(Host)**:用户直接交互的面向用户的AI应用。例如包括Anthropic的Claude Desktop、AI增强的IDE如Cursor、推理库如Hugging Face Python SDK,或使用LangChain或smolagents等库构建的自定义应用。主机启动与MCP服务器的连接,并协调用户请求、LLM处理和外部工具之间的整体流程。
+
+- **客户端(Client)**:主机应用程序中管理与特定MCP服务器通信的组件。每个客户端与单个服务器保持1:1连接,处理MCP通信的协议级细节,并作为主机逻辑和外部服务器之间的中介。
+
+- **服务器(Server)**:通过MCP协议暴露能力(工具、资源、提示)的外部程序或服务。
+
+
+
+很多内容将"客户端"和"主机"互换使用。从技术上讲,主机是面向用户的应用程序,而客户端是主机应用程序中管理与特定MCP服务器通信的组件。
+
+
+
+### 能力
+
+当然,应用程序的价值在于它提供的能力总和。因此,能力是应用程序最重要的部分。MCP可以连接任何软件服务,但有一些常用于许多AI应用的通用能力。
+
+| 能力 | 描述 | 示例 |
+| ---------- | ----------- | ------- |
+| **工具(Tools)** | AI模型可以调用的可执行函数,用于执行操作或检索计算数据。通常与应用程序的用例相关。 | 天气应用的工具有可能是一个返回特定位置天气的函数。 |
+| **资源(Resources)** | 提供上下文而不需要大量计算的只读数据源。 | 研究助手可能有科学论文资源。 |
+| **提示(Prompts)** | 预定义的模板或工作流,指导用户、AI模型和可用能力之间的交互。 | 摘要提示。 |
+| **采样(Sampling)** | 服务器发起的请求,要求客户端/主机执行LLM交互,实现递归操作,使LLM可以审查生成的内容并做出进一步决定。 | 写作应用审查自己的输出并决定进一步改进。 |
+
+在下面的图表中,我们可以看到应用于代码代理用例的集体能力。
+
+
+
+这个应用程序可能以下列方式使用其MCP实体:
+
+| 实体 | 名称 | 描述 |
+| --- | --- | --- |
+| 工具 | 代码解释器 | 一个可以执行LLM编写的代码的工具。 |
+| 资源 | 文档 | 包含应用程序文档的资源。 |
+| 提示 | 代码风格 | 指导LLM生成代码的提示。 |
+| 采样 | 代码审查 | 允许LLM审查代码并做出进一步决定的采样。 |
+
+### 结论
+
+理解这些核心概念和术语为有效使用MCP奠定了基础。在接下来的章节中,我们将在此基础上探索构成模型上下文协议的架构组件、通信协议和能力。
\ No newline at end of file
diff --git a/units/zh-CN/unit1/mcp-clients.mdx b/units/zh-CN/unit1/mcp-clients.mdx
new file mode 100644
index 0000000..e921b51
--- /dev/null
+++ b/units/zh-CN/unit1/mcp-clients.mdx
@@ -0,0 +1,343 @@
+# MCP 客户端
+
+现在我们已经对模型上下文协议有了基本了解,让我们来探索 MCP 客户端在模型上下文协议生态系统中的重要作用。
+
+在本单元的这一部分,我们将探索 MCP 客户端在模型上下文协议生态系统中的重要作用。
+
+在本节中,你将:
+
+* 了解什么是 MCP 客户端及其在 MCP 架构中的角色
+* 学习 MCP 客户端的主要职责
+* 探索主要的 MCP 客户端实现
+* 了解如何使用 Hugging Face 的 MCP 客户端实现
+* 查看 MCP 客户端使用的实际示例
+
+## 理解 MCP 客户端
+
+MCP 客户端是重要的组件,它们充当 AI 应用程序(主机)和 MCP 服务器提供的外部功能之间的桥梁。可以将主机想象成你的主要应用程序(如 AI 助手或 IDE),而客户端则是该主机中负责处理 MCP 通信的专门模块。
+
+## 用户界面客户端
+
+让我们首先探索可用于 MCP 的用户界面客户端。
+
+### 聊天界面客户端
+
+Anthropic 的 Claude Desktop 是最著名的 MCP 客户端之一,它提供了与各种 MCP 服务器的集成。
+
+### 交互式开发客户端
+
+Cursor 的 MCP 客户端实现通过直接集成代码编辑功能,实现了 AI 驱动的编码辅助。它支持多个 MCP 服务器连接,并在编码过程中提供实时工具调用,使其成为开发人员的强大工具。
+
+Continue.dev 是另一个支持 MCP 的交互式开发客户端示例,它可以从 VS Code 连接到 MCP 服务器。
+
+## 配置 MCP 客户端
+
+现在我们已经介绍了 MCP 协议的核心内容,让我们来看看如何配置你的 MCP 服务器和客户端。
+
+MCP 服务器和客户端的有效部署需要正确的配置。
+
+
+
+MCP 规范仍在不断发展,因此配置方法可能会发生变化。我们将重点关注当前的配置最佳实践。
+
+
+
+### MCP 配置文件
+
+MCP 主机使用配置文件来管理服务器连接。这些文件定义了哪些服务器可用以及如何连接到它们。
+
+幸运的是,配置文件非常简单、易于理解,并且在主要的 MCP 主机之间保持一致。
+
+#### `mcp.json` 结构
+
+MCP 的标准配置文件名为 `mcp.json`。以下是基本结构:
+
+```json
+{
+ "servers": [
+ {
+ "name": "服务器名称",
+ "transport": {
+ "type": "stdio|sse",
+ // 传输特定的配置
+ }
+ }
+ ]
+}
+```
+
+在这个例子中,我们有一个带有名称和传输类型的服务器。传输类型可以是 `stdio` 或 `sse`。
+
+#### stdio 传输的配置
+
+对于使用 stdio 传输的本地服务器,配置包括启动服务器进程的命令和参数:
+
+```json
+{
+ "servers": [
+ {
+ "name": "文件浏览器",
+ "transport": {
+ "type": "stdio",
+ "command": "python",
+ "args": ["/path/to/file_explorer_server.py"]
+ }
+ }
+ ]
+}
+```
+
+这里,我们有一个名为"文件浏览器"的服务器,它是一个本地脚本。
+
+#### HTTP+SSE 传输的配置
+
+对于使用 HTTP+SSE 传输的远程服务器,配置包括服务器 URL:
+
+```json
+{
+ "servers": [
+ {
+ "name": "远程 API 服务器",
+ "transport": {
+ "type": "sse",
+ "url": "https://example.com/mcp-server"
+ }
+ }
+ ]
+}
+```
+
+#### 配置中的环境变量
+
+可以使用 `env` 字段将环境变量传递给服务器进程。以下是如何在服务器代码中访问它们:
+
+
+
+
+在 Python 中,我们使用 `os` 模块来访问环境变量:
+
+```python
+import os
+
+# 访问环境变量
+github_token = os.environ.get("GITHUB_TOKEN")
+if not github_token:
+ raise ValueError("需要 GITHUB_TOKEN 环境变量")
+
+# 在服务器代码中使用令牌
+def make_github_request():
+ headers = {"Authorization": f"Bearer {github_token}"}
+ # ... 代码的其余部分
+```
+
+
+
+
+在 JavaScript 中,我们使用 `process.env` 对象来访问环境变量:
+
+```javascript
+// 访问环境变量
+const githubToken = process.env.GITHUB_TOKEN;
+if (!githubToken) {
+ throw new Error("需要 GITHUB_TOKEN 环境变量");
+}
+
+// 在服务器代码中使用令牌
+function makeGithubRequest() {
+ const headers = { "Authorization": `Bearer ${githubToken}` };
+ // ... 代码的其余部分
+}
+```
+
+
+
+
+相应的 `mcp.json` 配置如下:
+
+```json
+{
+ "servers": [
+ {
+ "name": "GitHub API",
+ "transport": {
+ "type": "stdio",
+ "command": "python",
+ "args": ["/path/to/github_server.py"],
+ "env": {
+ "GITHUB_TOKEN": "your_github_token"
+ }
+ }
+ }
+ ]
+}
+```
+
+### 配置示例
+
+让我们看一些实际配置场景:
+
+#### 场景 1:本地服务器配置
+
+在这个场景中,我们有一个本地服务器,它是一个 Python 脚本,可以是文件浏览器或代码编辑器。
+
+```json
+{
+ "servers": [
+ {
+ "name": "文件浏览器",
+ "transport": {
+ "type": "stdio",
+ "command": "python",
+ "args": ["/path/to/file_explorer_server.py"]
+ }
+ }
+ ]
+}
+```
+
+#### 场景 2:远程服务器配置
+
+在这个场景中,我们有一个远程服务器,它是一个天气 API。
+
+```json
+{
+ "servers": [
+ {
+ "name": "天气 API",
+ "transport": {
+ "type": "sse",
+ "url": "https://example.com/mcp-server"
+ }
+ }
+ ]
+}
+```
+
+正确的配置对于成功部署 MCP 集成至关重要。通过理解这些方面,你可以在 AI 应用程序和外部功能之间创建强大且可靠的连接。
+
+在下一节中,我们将探索 Hugging Face Hub 上可用的 MCP 服务器生态系统,以及如何在那里发布你自己的服务器。
+
+## 代码客户端
+
+你也可以在代码中使用 MCP 客户端,使工具对 LLM 可用。让我们探索 `smolagents` 中的一些示例。
+
+首先,让我们探索上一页中的天气服务器。在 `smolagents` 中,我们可以使用 `ToolCollection` 类来自动发现和注册来自 MCP 服务器的工具。这是通过将 `StdioServerParameters` 或 `SSEServerParameters` 传递给 `ToolCollection.from_mcp` 方法来实现的。然后我们可以将工具打印到控制台。
+
+```python
+from smolagents import ToolCollection, CodeAgent
+from mcp.client.stdio import StdioServerParameters
+
+server_parameters = StdioServerParameters(command="uv", args=["run", "server.py"])
+
+with ToolCollection.from_mcp(
+ server_parameters, trust_remote_code=True
+) as tools:
+ print("\n".join(f"{t.name}: {t.description}" for t in tools))
+
+```
+
+
+
+输出
+
+
+```sh
+Weather API: 获取特定位置的天气
+
+```
+
+
+
+我们还可以连接到托管在远程机器上的 MCP 服务器。在这种情况下,我们需要将 `SSEServerParameters` 传递给 `ToolCollection.from_mcp` 方法。
+
+```python
+from smolagents.mcp_client import MCPClient
+
+with MCPClient(
+ {"url": "https://abidlabs-mcp-tools.hf.space/gradio_api/mcp/sse"}
+) as tools:
+ # 远程服务器的工具可用
+ print("\n".join(f"{t.name}: {t.description}" for t in tools))
+```
+
+
+
+输出
+
+
+```sh
+prime_factors: 计算正整数的质因数分解。
+generate_cheetah_image: 生成猎豹图像。
+image_orientation: 返回图像是纵向还是横向。
+sepia: 对输入图像应用棕褐色滤镜。
+```
+
+
+
+现在,让我们看看如何在代码代理中使用 MCP 客户端。
+
+```python
+from smolagents import ToolCollection, CodeAgent
+from mcp.client.stdio import StdioServerParameters
+from smolagents import CodeAgent, InferenceClientModel
+
+model = InferenceClientModel()
+
+server_parameters = StdioServerParameters(command="uv", args=["run", "server.py"])
+
+with ToolCollection.from_mcp(
+ server_parameters, trust_remote_code=True
+) as tool_collection:
+ agent = CodeAgent(tools=[*tool_collection.tools], model=model)
+ agent.run("东京的天气怎么样?")
+
+```
+
+
+
+输出
+
+
+```sh
+东京的天气晴朗,气温为 20 摄氏度。
+```
+
+
+
+我们还可以连接到 MCP 包。这是连接到 `pubmedmcp` 包的示例。
+
+```python
+from smolagents import ToolCollection, CodeAgent
+from mcp import StdioServerParameters
+
+server_parameters = StdioServerParameters(
+ command="uv",
+ args=["--quiet", "pubmedmcp@0.1.3"],
+ env={"UV_PYTHON": "3.12", **os.environ},
+)
+
+with ToolCollection.from_mcp(server_parameters, trust_remote_code=True) as tool_collection:
+ agent = CodeAgent(tools=[*tool_collection.tools], add_base_tools=True)
+ agent.run("请找到宿醉的补救方法。")
+```
+
+
+
+输出
+
+
+```sh
+宿醉的补救方法是喝水。
+```
+
+
+
+## 下一步
+
+现在你已经了解了 MCP 客户端,你可以:
+
+* 探索特定的 MCP 服务器实现
+* 学习创建自定义 MCP 客户端
+* 深入研究高级 MCP 集成模式
+
+让我们继续探索模型上下文协议的世界!
diff --git a/units/zh-CN/unit1/sdk.mdx b/units/zh-CN/unit1/sdk.mdx
new file mode 100644
index 0000000..5a55f49
--- /dev/null
+++ b/units/zh-CN/unit1/sdk.mdx
@@ -0,0 +1,168 @@
+# MCP SDK
+
+The Model Context Protocol provides official SDKs for both JavaScript, Python and other languages. This makes it easy to implement MCP clients and servers in your applications. These SDKs handle the low-level protocol details, allowing you to focus on building your application's capabilities.
+
+## SDK Overview
+
+Both SDKs provide similar core functionality, following the MCP protocol specification we discussed earlier. They handle:
+
+- Protocol-level communication
+- Capability registration and discovery
+- Message serialization/deserialization
+- Connection management
+- Error handling
+
+## Core Primitives Implementation
+
+Let's explore how to implement each of the core primitives (Tools, Resources, and Prompts) using both SDKs.
+
+
+
+
+
+
+```python
+from mcp.server.fastmcp import FastMCP
+
+# Create an MCP server
+mcp = FastMCP("Weather Service")
+
+
+@mcp.tool()
+def get_weather(location: str) -> str:
+ """Get the current weather for a specified location."""
+ return f"Weather in {location}: Sunny, 72°F"
+
+
+@mcp.resource("weather://{location}")
+def weather_resource(location: str) -> str:
+ """Provide weather data as a resource."""
+ return f"Weather data for {location}: Sunny, 72°F"
+
+
+@mcp.prompt()
+def weather_report(location: str) -> str:
+ """Create a weather report prompt."""
+ return f"""You are a weather reporter. Weather report for {location}?"""
+
+
+# Run the server
+if __name__ == "__main__":
+ mcp.run()
+
+```
+
+
+
+
+```javascript
+import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
+import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
+import { z } from "zod";
+
+// Create an MCP server
+const server = new McpServer({
+ name: "Weather Service",
+ version: "1.0.0"
+});
+
+// Tool implementation
+server.tool("get_weather",
+ { location: z.string() },
+ async ({ location }) => ({
+ content: [{
+ type: "text",
+ text: `Weather in ${location}: Sunny, 72°F`
+ }]
+ })
+);
+
+// Resource implementation
+server.resource(
+ "weather",
+ new ResourceTemplate("weather://{location}", { list: undefined }),
+ async (uri, { location }) => ({
+ contents: [{
+ uri: uri.href,
+ text: `Weather data for ${location}: Sunny, 72°F`
+ }]
+ })
+);
+
+// Prompt implementation
+server.prompt(
+ "weather_report",
+ { location: z.string() },
+ async ({ location }) => ({
+ messages: [
+ {
+ role: "assistant",
+ content: {
+ type: "text",
+ text: "You are a weather reporter."
+ }
+ },
+ {
+ role: "user",
+ content: {
+ type: "text",
+ text: `Weather report for ${location}?`
+ }
+ }
+ ]
+ })
+);
+
+// Run the server
+const transport = new StdioServerTransport();
+await server.connect(transport);
+```
+
+
+
+
+Once you have your server implemented, you can start it by running the server script.
+
+```bash
+mcp dev server.py
+```
+
+This will initialize a development server running the file `server.py`. And log the following output:
+
+```bash
+Starting MCP inspector...
+⚙️ Proxy server listening on port 6277
+Spawned stdio transport
+Connected MCP client to backing server transport
+Created web app transport
+Set up MCP proxy
+🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
+```
+
+You can then open the MCP Inspector at [http://127.0.0.1:6274](http://127.0.0.1:6274) to see the server's capabilities and interact with them.
+
+You'll see the server's capabilities and the ability to call them via the UI.
+
+
+
+## MCP SDKs
+
+MCP is designed to be language-agnostic, and there are official SDKs available for several popular programming languages:
+
+| Language | Repository | Maintainer(s) | Status |
+|----------|------------|---------------|--------|
+| TypeScript | [github.com/modelcontextprotocol/typescript-sdk](https://github.com/modelcontextprotocol/typescript-sdk) | Anthropic | Active |
+| Python | [github.com/modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) | Anthropic | Active |
+| Java | [github.com/modelcontextprotocol/java-sdk](https://github.com/modelcontextprotocol/java-sdk) | Spring AI (VMware) | Active |
+| Kotlin | [github.com/modelcontextprotocol/kotlin-sdk](https://github.com/modelcontextprotocol/kotlin-sdk) | JetBrains | Active |
+| C# | [github.com/modelcontextprotocol/csharp-sdk](https://github.com/modelcontextprotocol/csharp-sdk) | Microsoft | Active (Preview) |
+| Swift | [github.com/modelcontextprotocol/swift-sdk](https://github.com/modelcontextprotocol/swift-sdk) | loopwork-ai | Active |
+| Rust | [github.com/modelcontextprotocol/rust-sdk](https://github.com/modelcontextprotocol/rust-sdk) | Anthropic/Community | Active |
+
+These SDKs provide language-specific abstractions that simplify working with the MCP protocol, allowing you to focus on implementing the core logic of your servers or clients rather than dealing with low-level protocol details.
+
+## Next Steps
+
+We've only scratched the surface of what you can do with the MCP but you've already got a basic server running. In fact, you've also connected to it using the MCP Client in the browser.
+
+In the next section, we'll look at how to connect to your server from an LLM.
diff --git a/units/zh-CN/unit2/clients.mdx b/units/zh-CN/unit2/clients.mdx
new file mode 100644
index 0000000..4464fb2
--- /dev/null
+++ b/units/zh-CN/unit2/clients.mdx
@@ -0,0 +1,80 @@
+# 构建 MCP 客户端
+
+在本节中,我们将创建能够使用不同编程语言与 MCP 服务器交互的客户端。我们将实现一个使用 HuggingFace.js 的 JavaScript 客户端和一个使用 smolagents 的 Python 客户端。
+
+## 配置 MCP 客户端
+
+MCP 服务器和客户端的有效部署需要适当的配置。由于 MCP 规范仍在不断发展,配置方法也可能会随之变化。我们将重点关注当前的最佳配置实践。
+
+### MCP 配置文件
+
+MCP 主机使用配置文件来管理服务器连接。这些文件定义了可用的服务器以及如何连接到它们。
+
+配置文件非常简单,易于理解,并且在主要的 MCP 主机之间保持一致。
+
+#### `mcp.json` 结构
+
+MCP 的标准配置文件名为 `mcp.json`。以下是基本结构:
+
+```json
+{
+ "servers": [
+ {
+ "name": "MCP Server",
+ "transport": {
+ "type": "sse",
+ "url": "http://localhost:7860/gradio_api/mcp/sse"
+ }
+ }
+ ]
+}
+```
+
+在这个例子中,我们配置了一个使用 SSE 传输的服务器,连接到运行在 7860 端口的本地 Gradio 服务器。
+
+
+
+我们通过 SSE 传输连接到 Gradio 应用,因为我们假设 gradio 应用运行在远程服务器上。但是,如果你想连接到本地脚本,使用 `stdio` 传输而不是 `sse` 传输是更好的选择。
+
+
+
+#### HTTP+SSE 传输的配置
+
+对于使用 HTTP+SSE 传输的远程服务器,配置包括服务器 URL:
+
+```json
+{
+ "servers": [
+ {
+ "name": "Remote MCP Server",
+ "transport": {
+ "type": "sse",
+ "url": "https://example.com/gradio_api/mcp/sse"
+ }
+ }
+ ]
+}
+```
+
+这个配置允许你的 UI 客户端使用 MCP 协议与 Gradio MCP 服务器通信,实现前端和 MCP 服务之间的无缝集成。
+
+## 配置 UI MCP 客户端
+
+在使用 Gradio MCP 服务器时,你可以配置你的 UI 客户端使用 MCP 协议连接到服务器。以下是设置方法:
+
+### 基本配置
+
+创建一个名为 `config.json` 的新文件,使用以下配置:
+
+```json
+{
+ "mcpServers": {
+ "mcp": {
+ "url": "http://localhost:7860/gradio_api/mcp/sse"
+ }
+ }
+}
+```
+
+这个配置允许你的 UI 客户端使用 MCP 协议与 Gradio MCP 服务器通信,实现前端和 MCP 服务之间的无缝集成。
+
diff --git a/units/zh-CN/unit2/gradio-client.mdx b/units/zh-CN/unit2/gradio-client.mdx
new file mode 100644
index 0000000..8eb90e1
--- /dev/null
+++ b/units/zh-CN/unit2/gradio-client.mdx
@@ -0,0 +1,146 @@
+# 使用 Gradio 作为 MCP 客户端
+
+在上一节中,我们探讨了如何使用 Gradio 创建 MCP 服务器并使用 MCP 客户端连接到它。在本节中,我们将探讨如何使用 Gradio 作为 MCP 客户端来连接到 MCP 服务器。
+
+
+
+Gradio 最适合用于创建 UI 客户端和 MCP 服务器,但它也可以用作 MCP 客户端并作为 UI 展示。
+
+
+
+我们将连接到在上一节中创建的 MCP 服务器,并使用它来回答问题。
+
+## Gradio 中的 MCP 客户端
+
+首先,如果还没有安装,我们需要安装 `smolagents`、gradio 和 mcp-client 库:
+
+```bash
+pip install smolagents[mcp] gradio[mcp] mcp
+```
+
+现在,我们可以导入必要的库并创建一个简单的 Gradio 界面,该界面使用 MCP 客户端连接到 MCP 服务器。
+
+```python
+import gradio as gr
+
+from mcp.client.stdio import StdioServerParameters
+from smolagents import ToolCollection, CodeAgent
+from smolagents import CodeAgent, InferenceClientModel
+from smolagents.mcp_client import MCPClient
+```
+
+接下来,我们将连接到 MCP 服务器并获取可用于回答问题的工具。
+
+```python
+mcp_client = MCPClient(
+ {"url": "http://localhost:7860/gradio_api/mcp/sse"}
+)
+tools = mcp_client.get_tools()
+```
+
+现在我们有了工具,我们可以创建一个简单的代理来使用它们回答问题。我们现在只使用一个简单的 `InferenceClientModel` 和 `smolagents` 的默认模型。
+
+```python
+model = InferenceClientModel()
+agent = CodeAgent(tools=[*tools], model=model)
+```
+
+现在,我们可以创建一个简单的 Gradio 界面,使用代理来回答问题。
+
+```python
+demo = gr.ChatInterface(
+ fn=lambda message, history: str(agent.run(message)),
+ type="messages",
+ examples=["Prime factorization of 68"],
+ title="Agent with MCP Tools",
+ description="This is a simple agent that uses MCP tools to answer questions.",
+ messages=[],
+)
+
+demo.launch()
+```
+
+就是这样!我们已经创建了一个简单的 Gradio 界面,它使用 MCP 客户端连接到 MCP 服务器并回答问题。
+
+
+
+
+## 完整示例
+
+以下是 Gradio 中 MCP 客户端的完整示例:
+
+```python
+import gradio as gr
+
+from mcp.client.stdio import StdioServerParameters
+from smolagents import ToolCollection, CodeAgent
+from smolagents import CodeAgent, InferenceClientModel
+from smolagents.mcp_client import MCPClient
+
+
+try:
+ mcp_client = MCPClient(
+ # {"url": "https://abidlabs-mcp-tools.hf.space/gradio_api/mcp/sse"}
+ {"url": "http://localhost:7860/gradio_api/mcp/sse"}
+ )
+ tools = mcp_client.get_tools()
+
+ model = InferenceClientModel()
+ agent = CodeAgent(tools=[*tools], model=model)
+
+ def call_agent(message, history):
+ return str(agent.run(message))
+
+
+ demo = gr.ChatInterface(
+ fn=lambda message, history: str(agent.run(message)),
+ type="messages",
+ examples=["Prime factorization of 68"],
+ title="Agent with MCP Tools",
+ description="This is a simple agent that uses MCP tools to answer questions.",
+ messages=[],
+ )
+
+ demo.launch()
+finally:
+ mcp_client.close()
+```
+
+你会注意到我们在 `finally` 块中关闭了 MCP 客户端。这很重要,因为 MCP 客户端是一个长期运行的对象,需要在程序退出时关闭。
+
+## 部署到 Hugging Face Spaces
+
+要使你的服务器可供他人使用,你可以将其部署到 Hugging Face Spaces,就像我们在上一节中所做的那样。
+要将你的 Gradio MCP 客户端部署到 Hugging Face Spaces:
+
+1. 在 Hugging Face 上创建一个新的 Space:
+ - 访问 huggingface.co/spaces
+ - 点击"Create new Space"
+ - 选择"Gradio"作为 SDK
+ - 为你的 space 命名(例如,"mcp-client")
+
+2. 创建 `requirements.txt` 文件:
+```txt
+gradio[mcp]
+smolagents[mcp]
+```
+
+3. 将你的代码推送到 Space:
+```bash
+git init
+git add server.py requirements.txt
+git commit -m "Initial commit"
+git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-client
+git push -u origin main
+```
+
+## 结论
+
+在本节中,我们探讨了如何使用 Gradio 作为 MCP 客户端连接到 MCP 服务器。我们还了解了如何在 Hugging Face Spaces 中部署 MCP 客户端。
+
+
diff --git a/units/zh-CN/unit2/gradio-server.mdx b/units/zh-CN/unit2/gradio-server.mdx
new file mode 100644
index 0000000..ed4a55a
--- /dev/null
+++ b/units/zh-CN/unit2/gradio-server.mdx
@@ -0,0 +1,188 @@
+# 构建 Gradio MCP 服务器
+
+在本节中,我们将使用 Gradio 创建我们的情感分析 MCP 服务器。这个服务器将暴露一个情感分析工具,可以通过网页界面供人类用户使用,也可以通过 MCP 协议供 AI 模型使用。
+
+## Gradio MCP 集成介绍
+
+Gradio 提供了一种简单的方法来创建 MCP 服务器,通过自动将你的 Python 函数转换为 MCP 工具。当你在 `launch()` 中设置 `mcp_server=True` 时,Gradio 会:
+
+1. 自动将你的函数转换为 MCP 工具
+2. 将输入组件映射到工具参数模式
+3. 从输出组件确定响应格式
+4. 设置基于 HTTP+SSE 的 JSON-RPC 客户端-服务器通信
+5. 创建网页界面和 MCP 服务器端点
+
+## 项目设置
+
+首先,让我们为我们的项目创建一个新目录并设置所需的依赖:
+
+```bash
+mkdir mcp-sentiment
+cd mcp-sentiment
+python -m venv venv
+source venv/bin/activate # Windows: venv\Scripts\activate
+pip install "gradio[mcp]" textblob
+```
+
+## 创建服务器
+
+创建一个名为 `server.py` 的新文件,包含以下代码:
+
+```python
+import gradio as gr
+from textblob import TextBlob
+
+def sentiment_analysis(text: str) -> dict:
+ """
+ 分析给定文本的情感。
+
+ 参数:
+ text (str): 要分析的文本
+
+ 返回:
+ dict: 包含极性、主观性和评估的字典
+ """
+ blob = TextBlob(text)
+ sentiment = blob.sentiment
+
+ return {
+ "polarity": round(sentiment.polarity, 2), # -1(负面)到 1(正面)
+ "subjectivity": round(sentiment.subjectivity, 2), # 0(客观)到 1(主观)
+ "assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
+ }
+
+# 创建 Gradio 界面
+demo = gr.Interface(
+ fn=sentiment_analysis,
+ inputs=gr.Textbox(placeholder="输入要分析的文本..."),
+ outputs=gr.JSON(),
+ title="文本情感分析",
+ description="使用 TextBlob 分析文本情感"
+)
+
+# 启动界面和 MCP 服务器
+if __name__ == "__main__":
+ demo.launch(mcp_server=True)
+```
+
+## 代码解析
+
+让我们分解关键组件:
+
+1. **函数定义**:
+ - `sentiment_analysis` 函数接收文本输入并返回一个字典
+ - 使用 TextBlob 进行情感分析
+ - 文档字符串很重要,因为它帮助 Gradio 生成 MCP 工具模式
+ - 类型提示(`str` 和 `dict`)帮助定义输入/输出模式
+
+2. **Gradio 界面**:
+ - `gr.Interface` 同时创建网页 UI 和 MCP 服务器
+ - 函数自动暴露为 MCP 工具
+ - 输入和输出组件定义工具的模式
+ - JSON 输出组件确保正确的序列化
+
+3. **MCP 服务器**:
+ - 设置 `mcp_server=True` 启用 MCP 服务器
+ - 服务器将在 `http://localhost:7860/gradio_api/mcp/sse` 可用
+ - 你也可以使用环境变量启用它:
+ ```bash
+ export GRADIO_MCP_SERVER=True
+ ```
+
+## 运行服务器
+
+通过运行以下命令启动服务器:
+
+```bash
+python server.py
+```
+
+你应该看到指示网页界面和 MCP 服务器都在运行的输出。网页界面将在 `http://localhost:7860` 可用,MCP 服务器在 `http://localhost:7860/gradio_api/mcp/sse`。
+
+## 测试服务器
+
+你可以通过两种方式测试服务器:
+
+1. **网页界面**:
+ - 在浏览器中打开 `http://localhost:7860`
+ - 输入一些文本并点击"提交"
+ - 你应该看到情感分析结果
+
+2. **MCP 模式**:
+ - 访问 `http://localhost:7860/gradio_api/mcp/schema`
+ - 这显示了客户端将使用的 MCP 工具模式
+ - 你也可以在 Gradio 应用的页脚中的"查看 API"链接中找到这个
+
+## 故障排除提示
+
+1. **类型提示和文档字符串**:
+ - 始终为函数参数和返回值提供类型提示
+ - 为每个参数包含带有"Args:"块的文档字符串
+ - 这有助于 Gradio 生成准确的 MCP 工具模式
+
+2. **字符串输入**:
+ - 如有疑问,将输入参数接受为 `str`
+ - 在函数内部将它们转换为所需的类型
+ - 这提供了与 MCP 客户端更好的兼容性
+
+3. **SSE 支持**:
+ - 一些 MCP 客户端不支持基于 SSE 的 MCP 服务器
+ - 在这些情况下,使用 `mcp-remote`:
+ ```json
+ {
+ "mcpServers": {
+ "gradio": {
+ "command": "npx",
+ "args": [
+ "mcp-remote",
+ "http://localhost:7860/gradio_api/mcp/sse"
+ ]
+ }
+ }
+ }
+ ```
+
+4. **连接问题**:
+ - 如果遇到连接问题,尝试重启客户端和服务器
+ - 检查服务器是否正在运行且可访问
+ - 验证 MCP 模式是否在预期 URL 可用
+
+## 部署到 Hugging Face Spaces
+
+要使你的服务器对其他人可用,你可以将其部署到 Hugging Face Spaces:
+
+1. 在 Hugging Face 上创建新的 Space:
+ - 访问 huggingface.co/spaces
+ - 点击"创建新 Space"
+ - 选择"Gradio"作为 SDK
+ - 为你的 space 命名(例如,"mcp-sentiment")
+
+2. 创建 `requirements.txt` 文件:
+```txt
+gradio[mcp]
+textblob
+```
+
+3. 将代码推送到 Space:
+```bash
+git init
+git add server.py requirements.txt
+git commit -m "Initial commit"
+git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-sentiment
+git push -u origin main
+```
+
+你的 MCP 服务器现在将在以下地址可用:
+```
+https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse
+```
+
+## 下一步
+
+现在我们的 MCP 服务器已经运行,我们将创建客户端来与之交互。在接下来的章节中,我们将:
+
+1. 创建一个受 Tiny Agents 启发的基于 HuggingFace.js 的客户端
+2. 实现一个基于 SmolAgents 的 Python 客户端
+3. 使用我们部署的服务器测试这两个客户端
+
+让我们开始构建我们的第一个客户端!
\ No newline at end of file
diff --git a/units/zh-CN/unit2/introduction.mdx b/units/zh-CN/unit2/introduction.mdx
new file mode 100644
index 0000000..cf6a72a
--- /dev/null
+++ b/units/zh-CN/unit2/introduction.mdx
@@ -0,0 +1,64 @@
+# 构建端到端 MCP 应用
+
+欢迎来到 MCP 课程的第二单元!
+
+在本单元中,我们将从零开始构建一个完整的 MCP 应用,重点创建使用 Gradio 的服务器并连接多个客户端。这种实践方法将让你获得整个 MCP 生态系统的实际经验。
+
+
+
+在本单元中,我们将使用 Gradio 和 HuggingFace hub 构建一个简单的 MCP 服务器和客户端。在下一个单元中,我们将构建一个更复杂的服务器来解决实际用例。
+
+
+
+## 你将学到什么
+
+在本单元中,你将:
+
+- 使用 Gradio 内置的 MCP 支持创建 MCP 服务器
+- 构建一个可供 AI 模型使用的情感分析工具
+- 使用不同的客户端实现连接到服务器:
+ - 基于 HuggingFace.js 的客户端
+ - 基于 SmolAgents 的 Python 客户端
+- 将你的 MCP 服务器部署到 Hugging Face Spaces
+- 测试和调试完整系统
+
+在本单元结束时,你将拥有一个展示协议强大功能和灵活性的可运行的 MCP 应用。
+
+## 前提条件
+
+在继续本单元之前,请确保你:
+
+- 已完成第一单元或对 MCP 概念有基本了解
+- 熟悉 Python 和 JavaScript/TypeScript
+- 对 API 和客户端-服务器架构有基本了解
+- 拥有包含以下内容的开发环境:
+ - Python 3.10+
+ - Node.js 18+
+ - Hugging Face 账户(用于部署)
+
+## 我们的端到端项目
+
+我们将构建一个情感分析应用,它包含三个主要部分:服务器、客户端和部署。
+
+
+
+### 服务器端
+
+- 使用 Gradio 通过 `gr.Interface` 创建 Web 界面和 MCP 服务器
+- 使用 TextBlob 实现情感分析工具
+- 通过 HTTP 和 MCP 协议暴露工具
+
+### 客户端
+
+- 实现 HuggingFace.js 客户端
+- 或创建 smolagents Python 客户端
+- 演示如何使用不同的客户端实现连接同一个服务器
+
+### 部署
+
+- 将服务器部署到 Hugging Face Spaces
+- 配置客户端以与已部署的服务器配合工作
+
+## 让我们开始吧!
+
+准备好构建你的第一个端到端 MCP 应用了吗?让我们从设置开发环境和创建 Gradio MCP 服务器开始。
\ No newline at end of file
diff --git a/units/zh-CN/unit2/tiny-agents.mdx b/units/zh-CN/unit2/tiny-agents.mdx
new file mode 100644
index 0000000..0c11779
--- /dev/null
+++ b/units/zh-CN/unit2/tiny-agents.mdx
@@ -0,0 +1,455 @@
+# Tiny Agents: 一个由MCP驱动的50行代码的智能体
+
+既然我们已经用Gradio构建了MCP服务器,让我们进一步探索MCP客户端。本节基于实验项目[Tiny Agents](https://huggingface.co/blog/tiny-agents),该项目展示了一种超级简单的方式来部署MCP客户端,这些客户端可以连接到像我们之前构建的Gradio情感分析服务器这样的服务。
+
+在这个简短的练习中,我们将指导你如何实现一个TypeScript (JS) MCP客户端,它可以与任何MCP服务器通信,包括我们在上一节中构建的基于Gradio的情感分析服务器。你将看到MCP如何标准化智能体与工具的交互方式,使Agentic AI开发变得显著简单。
+
+
+图片来源 https://x.com/adamdotdev
+
+我们将向你展示如何将你的tiny agent连接到基于Gradio的MCP服务器,使其能够利用你的自定义情感分析工具和其他预构建工具。
+
+## 如何运行完整演示
+
+如果你有NodeJS(带有`pnpm`或`npm`),只需在终端中运行:
+
+```bash
+npx @huggingface/mcp-client
+```
+
+或者如果使用`pnpm`:
+
+```bash
+pnpx @huggingface/mcp-client
+```
+
+这会将包安装到临时文件夹中,然后执行其命令。
+
+你将看到你的简单Agent连接到多个MCP服务器(在本地运行),加载它们的工具(类似于它如何加载你的Gradio情感分析工具),然后提示你进行对话。
+
+
+
+默认情况下,我们的示例Agent连接到以下两个MCP服务器:
+
+- "规范"的[文件系统服务器](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem),它可以访问你的桌面,
+- 以及[Playwright MCP](https://github.com/microsoft/playwright-mcp)服务器,它知道如何为你使用沙盒化的Chromium浏览器。
+
+你可以轻松地将你的Gradio情感分析服务器添加到此列表中,我们将在本节后面演示。
+
+> [!NOTE]
+> 注意:这有点反直觉,但目前tiny agents中的所有MCP服务器实际上都是本地进程(尽管远程服务器即将推出)。这不包括我们在localhost:7860上运行的Gradio服务器。
+
+我们第一个视频的输入是:
+
+> 写一首关于Hugging Face社区的俳句,并将其写入我桌面上的"hf.txt"文件
+
+现在让我们尝试这个涉及网页浏览的提示:
+
+> 在Brave Search上搜索HF推理提供商并打开前3个结果
+
+
+
+连接我们的Gradio情感分析工具后,我们可以类似地问:
+> 分析这条评论的情感:"我绝对喜欢这个产品,它超出了我所有的期望!"
+
+### 默认模型和提供商
+
+在模型/提供商对方面,我们的示例Agent默认使用:
+- ["Qwen/Qwen2.5-72B-Instruct"](https://huggingface.co/Qwen/Qwen2.5-72B-Instruct)
+- 运行在[Nebius](https://huggingface.co/docs/inference-providers/providers/nebius)上
+
+这些都是可以通过环境变量配置的!在这里,我们还将展示如何添加我们的Gradio MCP服务器:
+
+```ts
+const agent = new Agent({
+ provider: process.env.PROVIDER ?? "nebius",
+ model: process.env.MODEL_ID ?? "Qwen/Qwen2.5-72B-Instruct",
+ apiKey: process.env.HF_TOKEN,
+ servers: [
+ // 默认服务器
+ {
+ command: "npx",
+ args: ["@modelcontextprotocol/servers", "filesystem"]
+ },
+ {
+ command: "npx",
+ args: ["playwright-mcp"]
+ },
+ // 我们的Gradio情感分析服务器
+ {
+ command: "npx",
+ args: [
+ "mcp-remote",
+ "http://localhost:7860/gradio_api/mcp/sse"
+ ]
+ }
+ ],
+});
+```
+
+
+
+我们通过[`mcp-remote`](https://www.npmjs.com/package/mcp-remote)包连接到我们的基于Gradio的MCP服务器。
+
+
+
+## 基础:LLM中的工具调用原生支持
+
+使将Gradio MCP服务器连接到我们的Tiny Agent成为可能的是,最近的LLM(包括闭源和开源的)都经过函数调用(也称为工具使用)的训练。这种能力同样支持我们与使用Gradio构建的情感分析工具的集成。
+
+工具由其名称、描述和参数的JSONSchema表示定义 - 这正是我们在Gradio服务器中定义情感分析函数的方式。让我们看一个简单的例子:
+
+```ts
+const weatherTool = {
+ type: "function",
+ function: {
+ name: "get_weather",
+ description: "获取给定位置的当前温度。",
+ parameters: {
+ type: "object",
+ properties: {
+ location: {
+ type: "string",
+ description: "城市和国家,例如:波哥大,哥伦比亚",
+ },
+ },
+ },
+ },
+};
+```
+
+我们的Gradio情感分析工具会有类似的结构,只是输入参数是`text`而不是`location`。
+
+我将在这里链接的规范文档是[OpenAI的函数调用文档](https://platform.openai.com/docs/guides/function-calling?api-mode=chat)。(是的...OpenAI几乎为整个社区定义了LLM标准😅)。
+
+推理引擎允许你在调用LLM时传递工具列表,LLM可以自由调用零个、一个或多个这些工具。
+作为开发者,你运行这些工具并将它们的结果反馈给LLM以继续生成。
+
+> 注意,在后端(在推理引擎级别),工具只是以特殊格式的`chat_template`传递给模型,就像任何其他消息一样,然后从响应中解析出来(使用模型特定的特殊标记)以将它们作为工具调用暴露出来。
+
+## 在InferenceClient之上实现MCP客户端
+
+现在我们知道最近LLM中的工具是什么,让我们实现实际的MCP客户端,它将与我们的Gradio服务器和其他MCP服务器通信。
+
+https://modelcontextprotocol.io/quickstart/client 上的官方文档写得相当好。你只需要用任何其他OpenAI兼容的客户端SDK替换对Anthropic客户端SDK的任何提及。(还有一个[llms.txt](https://modelcontextprotocol.io/llms-full.txt)你可以输入到你选择的LLM中以帮助你编码)。
+
+提醒一下,我们使用HF的`InferenceClient`作为我们的推理客户端。
+
+> [!TIP]
+> 如果你想使用实际代码跟随,完整的`McpClient.ts`代码文件在[这里](https://github.com/huggingface/huggingface.js/blob/main/packages/mcp-client/src/McpClient.ts) 🤓
+
+我们的`McpClient`类有:
+- 一个推理客户端(适用于任何推理提供商,`huggingface/inference`支持远程和本地端点)
+- 一组MCP客户端会话,每个连接的MCP服务器一个(这允许我们连接到多个服务器,包括我们的Gradio服务器)
+- 以及一个可用工具列表,它将从连接的服务器中填充并稍微重新格式化。
+
+```ts
+export class McpClient {
+ protected client: InferenceClient;
+ protected provider: string;
+ protected model: string;
+ private clients: Map = new Map();
+ public readonly availableTools: ChatCompletionInputTool[] = [];
+
+ constructor({ provider, model, apiKey }: { provider: InferenceProvider; model: string; apiKey: string }) {
+ this.client = new InferenceClient(apiKey);
+ this.provider = provider;
+ this.model = model;
+ }
+
+ // [...]
+}
+```
+
+要连接到MCP服务器(如我们的Gradio情感分析服务器),官方的`@modelcontextprotocol/sdk/client` TypeScript SDK提供了一个带有`listTools()`方法的`Client`类:
+
+```ts
+async addMcpServer(server: StdioServerParameters): Promise {
+ const transport = new StdioClientTransport({
+ ...server,
+ env: { ...server.env, PATH: process.env.PATH ?? "" },
+ });
+ const mcp = new Client({ name: "@huggingface/mcp-client", version: packageVersion });
+ await mcp.connect(transport);
+
+ const toolsResult = await mcp.listTools();
+ debug(
+ "Connected to server with tools:",
+ toolsResult.tools.map(({ name }) => name)
+ );
+
+ for (const tool of toolsResult.tools) {
+ this.clients.set(tool.name, mcp);
+ }
+
+ this.availableTools.push(
+ ...toolsResult.tools.map((tool) => {
+ return {
+ type: "function",
+ function: {
+ name: tool.name,
+ description: tool.description,
+ parameters: tool.inputSchema,
+ },
+ } satisfies ChatCompletionInputTool;
+ })
+ );
+}
+```
+
+`StdioServerParameters`是来自MCP SDK的一个接口,它将让你轻松生成一个本地进程:正如我们前面提到的,目前所有MCP服务器实际上都是本地进程,包括我们的Gradio服务器(尽管我们通过HTTP访问它)。
+
+对于我们连接的每个MCP服务器(包括我们的Gradio情感分析服务器),我们稍微重新格式化其工具列表并将它们添加到`this.availableTools`中。
+
+### 如何使用工具
+
+使用我们的情感分析工具(或任何其他MCP工具)很简单。你只需将`this.availableTools`传递给你的LLM聊天完成,除了你通常的消息数组:
+
+```ts
+const stream = this.client.chatCompletionStream({
+ provider: this.provider,
+ model: this.model,
+ messages,
+ tools: this.availableTools,
+ tool_choice: "auto",
+});
+```
+
+`tool_choice: "auto"`是你传递的参数,让LLM生成零个、一个或多个工具调用。
+
+在解析或流式传输输出时,LLM将生成一些工具调用(即函数名称和一些JSON编码的参数),你需要(作为开发者)计算这些调用。MCP客户端SDK再次使这变得非常容易;它有一个`client.callTool()`方法:
+
+```ts
+const toolName = toolCall.function.name;
+const toolArgs = JSON.parse(toolCall.function.arguments);
+
+const toolMessage: ChatCompletionInputMessageTool = {
+ role: "tool",
+ tool_call_id: toolCall.id,
+ content: "",
+ name: toolName,
+};
+
+/// 获取此工具的适当会话
+const client = this.clients.get(toolName);
+if (client) {
+ const result = await client.callTool({ name: toolName, arguments: toolArgs });
+ toolMessage.content = result.content[0].text;
+} else {
+ toolMessage.content = `Error: No session found for tool: ${toolName}`;
+}
+```
+
+如果LLM选择使用我们的情感分析工具,这段代码将自动将调用路由到我们的Gradio服务器,执行分析,并将结果返回给LLM。
+
+最后,你将把生成的工具消息添加到你的`messages`数组中并返回给LLM。
+
+## 我们的50行代码Agent 🤯
+
+现在我们有了一个能够连接到任意MCP服务器(包括我们的Gradio情感分析服务器)以获取工具列表的MCP客户端,并且能够将它们注入并从LLM推理中解析出来,那么...什么是Agent?
+
+> 一旦你有了一个带有一组工具的推理客户端,那么Agent就只是它上面的一个while循环。
+
+更详细地说,Agent只是以下内容的组合:
+- 一个系统提示
+- 一个LLM推理客户端
+- 一个MCP客户端,用于从一堆MCP服务器(包括我们的Gradio服务器)中钩入一组工具
+- 一些基本的控制流(见下面的while循环)
+
+> [!TIP]
+> 完整的`Agent.ts`代码文件在[这里](https://github.com/huggingface/huggingface.js/blob/main/packages/mcp-client/src/Agent.ts)。
+
+我们的Agent类简单地扩展了McpClient:
+
+```ts
+export class Agent extends McpClient {
+ private readonly servers: StdioServerParameters[];
+ protected messages: ChatCompletionInputMessage[];
+
+ constructor({
+ provider,
+ model,
+ apiKey,
+ servers,
+ prompt,
+ }: {
+ provider: InferenceProvider;
+ model: string;
+ apiKey: string;
+ servers: StdioServerParameters[];
+ prompt?: string;
+ }) {
+ super({ provider, model, apiKey });
+ this.servers = servers;
+ this.messages = [
+ {
+ role: "system",
+ content: prompt ?? DEFAULT_SYSTEM_PROMPT,
+ },
+ ];
+ }
+}
+```
+
+默认情况下,我们使用一个非常简单的系统提示,灵感来自[GPT-4.1提示指南](https://cookbook.openai.com/examples/gpt4-1_prompting_guide)中分享的提示。
+
+尽管这来自OpenAI 😈,但这句话特别适用于越来越多的模型,包括闭源和开源的:
+
+> 我们鼓励开发者专门使用tools字段来传递工具,而不是像过去一些人报告的那样,手动将工具描述注入到你的提示中并编写一个单独的工具调用解析器。
+
+也就是说,我们不需要在提示中提供精心格式化的工具使用示例列表。`tools: this.availableTools`参数就足够了,LLM将知道如何使用文件系统工具和我们的Gradio情感分析工具。
+
+在Agent上加载工具实际上只是连接到我们想要的MCP服务器(并行进行,因为在JS中很容易做到):
+
+```ts
+async loadTools(): Promise {
+ await Promise.all(this.servers.map((s) => this.addMcpServer(s)));
+}
+```
+
+我们添加了两个额外的工具(在MCP之外),LLM可以使用它们来控制我们的Agent的流程:
+
+```ts
+const taskCompletionTool: ChatCompletionInputTool = {
+ type: "function",
+ function: {
+ name: "task_complete",
+ description: "当用户给定的任务完成时调用此工具",
+ parameters: {
+ type: "object",
+ properties: {},
+ },
+ },
+};
+const askQuestionTool: ChatCompletionInputTool = {
+ type: "function",
+ function: {
+ name: "ask_question",
+ description: "向用户提问以获取解决或澄清他们问题所需的更多信息。",
+ parameters: {
+ type: "object",
+ properties: {},
+ },
+ },
+};
+const exitLoopTools = [taskCompletionTool, askQuestionTool];
+```
+
+当调用这些工具中的任何一个时,Agent将打破其循环并将控制权交还给用户以获取新的输入。
+
+### 完整的while循环
+
+看我们的完整while循环。🎉
+
+我们的Agent主while循环的要点是,我们只需与LLM迭代,在工具调用和向其提供工具结果之间交替,我们这样做**直到LLM开始连续响应两个非工具消息**。
+
+这是完整的while循环:
+
+```ts
+let numOfTurns = 0;
+let nextTurnShouldCallTools = true;
+while (true) {
+ try {
+ yield* this.processSingleTurnWithTools(this.messages, {
+ exitLoopTools,
+ exitIfFirstChunkNoTool: numOfTurns > 0 && nextTurnShouldCallTools,
+ abortSignal: opts.abortSignal,
+ });
+ } catch (err) {
+ if (err instanceof Error && err.message === "AbortError") {
+ return;
+ }
+ throw err;
+ }
+ numOfTurns++;
+ const currentLast = this.messages.at(-1)!;
+ if (
+ currentLast.role === "tool" &&
+ currentLast.name &&
+ exitLoopTools.map((t) => t.function.name).includes(currentLast.name)
+ ) {
+ return;
+ }
+ if (currentLast.role !== "tool" && numOfTurns > MAX_NUM_TURNS) {
+ return;
+ }
+ if (currentLast.role !== "tool" && nextTurnShouldCallTools) {
+ return;
+ }
+ if (currentLast.role === "tool") {
+ nextTurnShouldCallTools = false;
+ } else {
+ nextTurnShouldCallTools = true;
+ }
+}
+```
+
+## 将Tiny Agents与Gradio MCP服务器连接
+
+现在我们已经理解了Tiny Agents和Gradio MCP服务器,让我们看看它们如何协同工作!MCP的美妙之处在于它提供了一种标准化的方式,让智能体可以与任何MCP兼容的服务器交互,包括我们基于Gradio的情感分析服务器。
+
+### 将Tiny Agents与Gradio服务器一起使用
+
+要将我们的Tiny Agent连接到我们之前构建的Gradio情感分析服务器,我们只需要将其添加到我们的服务器列表中。以下是我们如何修改我们的agent配置:
+
+```ts
+const agent = new Agent({
+ provider: process.env.PROVIDER ?? "nebius",
+ model: process.env.MODEL_ID ?? "Qwen/Qwen2.5-72B-Instruct",
+ apiKey: process.env.HF_TOKEN,
+ servers: [
+ // ... 现有服务器 ...
+ {
+ command: "npx",
+ args: [
+ "mcp-remote",
+ "http://localhost:7860/gradio_api/mcp/sse" // 你的Gradio MCP服务器
+ ]
+ }
+ ],
+});
+```
+
+现在我们的agent可以与其他工具一起使用情感分析工具!例如,它可以:
+1. 使用文件系统服务器从文件中读取文本
+2. 使用我们的Gradio服务器分析其情感
+3. 将结果写回文件
+
+### 示例交互
+
+以下是与我们的agent的对话可能的样子:
+
+```
+用户:从我桌面读取文件"feedback.txt"并分析其情感
+
+Agent:我将帮助你分析反馈文件的情感。让我分步骤进行:
+
+1. 首先,我将使用文件系统工具读取文件
+2. 然后,我将使用情感分析工具分析其情感
+3. 最后,我将把结果写入新文件
+
+[Agent继续使用工具并提供分析]
+```
+
+### 部署注意事项
+
+当你将Gradio MCP服务器部署到Hugging Face Spaces时,你需要更新agent配置中的服务器URL,指向你部署的空间:
+
+```ts
+{
+ command: "npx",
+ args: [
+ "mcp-remote",
+ "https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse"
+ ]
+}
+```
+
+这允许你的agent从任何地方使用情感分析工具,而不仅仅是在本地!
+
+
+
diff --git a/units/zh-CN/unit3/introduction.mdx b/units/zh-CN/unit3/introduction.mdx
new file mode 100644
index 0000000..d3c9b29
--- /dev/null
+++ b/units/zh-CN/unit3/introduction.mdx
@@ -0,0 +1,3 @@
+# Coming Soon
+
+This will be another use case that dives deeper into the MCP protocol and how to use it in more complex ways.
\ No newline at end of file
diff --git a/units/zh-CN/unit4/introduction.mdx b/units/zh-CN/unit4/introduction.mdx
new file mode 100644
index 0000000..5eed14d
--- /dev/null
+++ b/units/zh-CN/unit4/introduction.mdx
@@ -0,0 +1,5 @@
+# Coming Soon
+
+This unit will be a collaboration with partners from the AI community.
+
+If you're building tools for MCP, please reach out to us and we'll add you to the unit. Open a [discussion](https://huggingface.co/spaces/mcp-course/README/discussions) on the hub organization.
\ No newline at end of file