MCP 课程文档

模块 1:构建 MCP 服务器

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

模块 1:构建 MCP 服务器

CodeCraft Studios 的 PR 混乱

这是您在 CodeCraft Studios 的第一周,您正在目睹一件让每个开发人员都感到不寒而栗的事情。团队的拉取请求看起来是这样的

  • “东西”
  • “更多更改”
  • “修复”
  • “更新内容”

同时,代码审查积压越来越多,因为审查人员无法理解更改了什么或为什么更改。来自后端团队的 Sarah 花了 30 分钟试图弄清楚“各种改进”到底意味着什么,而来自前端的 Mike 不得不翻阅 47 个文件才能理解一个“小修复”。

团队知道他们需要更好的 PR 描述,但每个人都忙于交付功能,无暇编写详细的解释。他们需要一个既能提供帮助又不会拖慢他们的解决方案。

您的任务:构建一个智能 PR 代理,自动分析代码更改并建议有用的描述。

截屏:PR 问题实际案例 😬

您将看到什么:CodeCraft Studios 中一个真实的 PR,标题为“各种改进”,描述简单地写着“修复了一些东西并进行了更新”。很经典,对吧?

困惑:观察队友们是如何挣扎的

  • Sarah(3 小时前):“修复了什么?我看到了 User 模型的变化,但无法分辨这是在解决 bug 还是在添加功能。”
  • Jamie(3 小时前):“有 8 个文件散布在 4 个服务中……这些更改是相关的吗?我审查时应该关注什么?”

痛点:截屏显示了实际的差异——8 个文件散布在多个服务中,零上下文。审查人员必须自己拼凑出故事,浪费宝贵时间,并可能错过关键问题。

为什么这很重要:这正是您的 MCP 服务器将解决的 PR 混乱问题!在本模块结束时,您将把这些神秘的 PR 转化为清晰、可操作的描述,让每个人的工作都变得更轻松。

您将构建什么

在本模块中,您将创建 CodeCraft Studios 自动化系统的基础:一个 MCP 服务器,它将改变团队编写拉取请求的方式。本模块将重点介绍您将在模块 2 和 3 中构建的核心 MCP 概念。

截屏:您的 PR 代理挽救了局面!🚀

解决方案实际案例:观看您的 MCP 服务器如何将 PR 混乱转化为清晰

  1. analyze_file_changes - 获取所有更改(8 个文件,共 453 行!)
  2. get_pr_templates - 向 Claude 展示 7 个可供选择的模板
  3. suggest_template - Claude 选择“Feature”(明智之举!)

您将看到什么:Claude 不仅仅选择了一个模板——它还:

  • 编写了实际更改的清晰摘要
  • 发现了安全问题(天哪,未哈希的密码!)
  • 创建了一个很好的后续工作待办事项列表
  • 甚至优先处理需要首先修复的问题

“哇”时刻 ✨:只需几秒钟,您的 MCP 服务器就帮助 Claude 将同一个分支转化为一个能实际解释发生了什么的 PR。不再有困惑的审查者,不再有“这是干什么用的?”的评论。

这就是您将要构建的:一个将 PR 恐惧转化为 PR 愉悦的工具——让我们开始吧!

您将学到什么

在本基础模块中,您将掌握:

  • 如何使用 FastMCP 创建基本的 MCP 服务器 - 模块 2 和 3 的构建块
  • 实现 MCP 工具以进行数据检索和分析 - 您将在单元 3 中使用的核心原语
  • 让 Claude 基于原始数据做出智能决策 - 所有 MCP 开发的关键原则
  • 测试和验证您的 MCP 服务器 - 构建可靠工具的基本技能

概述

您的 PR 代理将使用 MCP 开发的一个关键原则解决 CodeCraft Studios 的问题:您将为 Claude 提供原始 git 数据,而不是硬编码关于如何编写良好 PR 的严格规则,并让它智能地建议适当的描述。

这种方法有效的原因是:

  • 灵活分析:Claude 可以理解简单规则遗漏的上下文
  • 自然语言:建议感觉像人,而不是机器人
  • 适应性强:适用于任何代码库或编码风格

您将实现三个基本工具,为整个自动化系统建立模式:

  1. analyze_file_changes - 检索 git diff 信息和更改的文件(数据收集)
  2. get_pr_templates - 列出可用的 PR 模板(资源管理)
  3. suggest_template - 允许 Claude 推荐最合适的模板(智能决策)

入门

先决条件

  • Python 3.10 或更高版本
  • 已安装 Git 且有一个 Git 仓库可供测试
  • uv 包管理器 (安装指南)

启动代码

克隆启动代码仓库

git clone https://github.com/huggingface/mcp-course.git

导航到启动代码目录

cd mcp-course/projects/unit3/build-mcp-server/starter

安装依赖项

您可能需要为该项目创建一个虚拟环境

uv venv .venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
uv sync --all-extras

您的任务

这是您第一次亲手进行 MCP 开发!打开 server.py 并按照 TODO 注释实现这三个工具。启动代码提供了基本结构——您需要:

  1. 实现 analyze_file_changes 以运行 git 命令并返回 diff 数据
    • ⚠️ 重要:您可能会遇到令牌限制错误(每个响应最大 25,000 个令牌)
    • 这是一个真实的限制,用于教授正确的输出管理
    • 请参阅下面的“处理大型输出”部分以获取解决方案
    • ⚠️ 注意:Git 命令默认将在 MCP 服务器的目录中运行。有关详细信息,请参阅下面的“工作目录注意事项”
  2. 实现 get_pr_templates 以管理和返回 PR 模板
  3. 实现 suggest_template 以将更改类型映射到模板

别担心做得完美——您将在本单元的后续学习中完善这些技能。

设计理念

与根据文件扩展名或严格模式对更改进行分类的传统系统不同,您的实现应:

  • 向 Claude 提供原始 git 数据(差异、文件列表、统计数据)
  • 让 Claude 分析实际代码更改
  • 允许 Claude 做出智能模板建议
  • 保持逻辑简单 - Claude 处理复杂性

MCP 理念:不要将复杂的逻辑构建到您的工具中,而是为 Claude 提供丰富的数据,让其智能做出决策。这使您的代码比传统基于规则的系统更简单、更灵活。

测试您的实现

1. 验证您的代码

运行验证脚本以检查您的实现

uv run python validate_starter.py

2. 运行单元测试

使用提供的测试套件测试您的实现

uv run pytest test_server.py -v

3. 使用 Claude Code 进行测试

直接在 Claude Code 中配置您的服务器

# Add the MCP server to Claude Code
claude mcp add pr-agent -- uv --directory /absolute/path/to/starter run server.py

# Verify the server is configured
claude mcp list

然后

  1. 在 Git 仓库中进行一些更改
  2. 询问 Claude:“您能分析我的更改并建议一个 PR 模板吗?”
  3. 观察 Claude 如何使用您的工具提供智能建议

常见首个错误:如果您收到“MCP 工具响应超出最大允许令牌数(25000)”,这是预料之中的!大型仓库会生成大量的差异。这是一个宝贵的学习时刻——请参阅“处理大型输出”部分以获取解决方案。

常见模式

工具实现模式

@mcp.tool()
async def tool_name(param1: str, param2: bool = True) -> str:
    """Tool description for Claude.
    
    Args:
        param1: Description of parameter
        param2: Optional parameter with default
    """
    # Your implementation
    result = {"key": "value"}
    return json.dumps(result)

错误处理

始终优雅地处理潜在错误

try:
    result = subprocess.run(["git", "diff"], capture_output=True, text=True)
    return json.dumps({"output": result.stdout})
except Exception as e:
    return json.dumps({"error": str(e)})

错误处理:即使出现错误,您的工具也必须返回有效的 JSON。Claude 需要结构化数据来理解错误发生的原因,并向用户提供有用的响应。

处理大型输出(关键学习时刻!)

真实世界限制:MCP 工具的每个响应都有 25,000 个令牌的限制。大型 git diff 很容易超出此限制 10 倍甚至更多!这是生产 MCP 开发的关键一课。

在实现 analyze_file_changes 时,您可能会遇到此错误:

Error: MCP tool response (262521 tokens) exceeds maximum allowed tokens (25000)

为什么会发生这种情况:

  • 单个文件更改可能有数千行
  • 企业仓库通常有大量重构
  • Git diff 默认包含完整上下文
  • JSON 编码增加了开销

这教会我们一个重要原则:始终在设计工具时考虑输出限制。以下是解决方案:

@mcp.tool()
async def analyze_file_changes(base_branch: str = "main", 
                              include_diff: bool = True,
                              max_diff_lines: int = 500) -> str:
    """Analyze file changes with smart output limiting.
    
    Args:
        base_branch: Branch to compare against
        include_diff: Whether to include the actual diff
        max_diff_lines: Maximum diff lines to include (default 500)
    """
    try:
        # Get the diff
        result = subprocess.run(
            ["git", "diff", f"{base_branch}...HEAD"],
            capture_output=True, 
            text=True
        )
        
        diff_output = result.stdout
        diff_lines = diff_output.split('\n')
        
        # Smart truncation if needed
        if len(diff_lines) > max_diff_lines:
            truncated_diff = '\n'.join(diff_lines[:max_diff_lines])
            truncated_diff += f"\n\n... Output truncated. Showing {max_diff_lines} of {len(diff_lines)} lines ..."
            diff_output = truncated_diff
        
        # Get summary statistics
        stats_result = subprocess.run(
            ["git", "diff", "--stat", f"{base_branch}...HEAD"],
            capture_output=True,
            text=True
        )
        
        return json.dumps({
            "stats": stats_result.stdout,
            "total_lines": len(diff_lines),
            "diff": diff_output if include_diff else "Use include_diff=true to see diff",
            "files_changed": self._get_changed_files(base_branch)
        })
        
    except Exception as e:
        return json.dumps({"error": str(e)})

大型输出的最佳实践:

  1. 实现分页:将大型结果分成多个页面
  2. 添加过滤选项:允许用户请求特定文件或目录
  3. 首先提供摘要:在完整内容之前返回统计信息
  4. 使用渐进式披露:从高层信息开始,允许深入查看
  5. 设置合理的默认值:默认设置为适用于大多数情况的合理限制

工作目录注意事项

默认情况下,MCP 服务器在其安装目录中运行命令,而不是在 Claude 的当前工作目录中。这意味着您的 git 命令可能会分析错误的仓库!

为了解决这个问题,MCP 提供了 根目录——一种客户端通知服务器相关目录的方式。Claude Code 会自动将其工作目录作为根目录提供。

以下是您如何在工具中访问它的方法:

@mcp.tool()
async def analyze_file_changes(...):
    # Get Claude's working directory from roots
    context = mcp.get_context()
    roots_result = await context.session.list_roots()
    
    # Extract the path from the FileUrl object
    working_dir = roots_result.roots[0].uri.path
    
    # Use it for all git commands
    result = subprocess.run(
        ["git", "diff", "--name-status"],
        capture_output=True,
        text=True,
        cwd=working_dir  # Run in Claude's directory!
    )

这确保您的工具在 Claude 实际工作的仓库上运行,而不是 MCP 服务器的安装位置。

故障排除

  • 导入错误:确保您已运行 uv sync

  • Git 错误:确保您在 Git 仓库中

  • 无输出:MCP 服务器通过标准输入输出进行通信 - 使用 Claude Desktop 进行测试

  • JSON 错误:所有工具都必须返回有效的 JSON 字符串

  • 令牌限制超出:大型差异会发生这种情况!按照上述方法实现输出限制

  • “响应过大”错误:添加 max_diff_lines 参数或设置 include_diff=false

  • Git 命令在错误目录中运行:MCP 服务器默认在其安装目录中运行,而不是 Claude 的工作目录中。要解决此问题,请使用 MCP roots 访问 Claude 的当前目录

    # Get Claude's working directory from roots
    context = mcp.get_context()
    roots_result = await context.session.list_roots()
    working_dir = roots_result.roots[0].uri.path  # FileUrl object has .path property
    
    # Use it in subprocess calls
    subprocess.run(["git", "diff"], cwd=working_dir)

    Claude Code 自动将其工作目录作为根目录提供,允许您的 MCP 服务器在正确的位置运行。

下一步

恭喜!您已经使用工具构建了您的第一个 MCP 服务器——这是单元 3 中所有后续内容的基础。

您在模块 1 中完成的工作:

  • 创建了 MCP 工具,为 Claude 提供了结构化数据
  • 实现了核心 MCP 理念——让 Claude 根据原始数据做出智能决策
  • 构建了一个实用的 PR 代理,可以分析代码更改并建议模板
  • 了解了实际限制——25,000 令牌限制以及如何处理它
  • 建立了测试模式,包括验证脚本和单元测试

您可以重用的关键模式:

  • 数据收集工具,用于从外部源获取信息
  • 智能分析,其中 Claude 处理原始数据以做出决策
  • 输出管理——截断大型响应同时保持其有用性
  • 错误处理,返回结构化的 JSON 响应
  • MCP 服务器开发的测试策略

下一步该怎么做:

  1. 查看解决方案(位于 /projects/unit3/build-mcp-server/solution/)以了解不同的实现方法
  2. 将您的实现与提供的解决方案进行比较——解决问题没有单一的“正确”方法
  3. 彻底测试您的工具——尝试使用不同类型的代码更改来查看 Claude 如何适应
  4. 继续学习模块 2,您将在其中添加实时 webhook 功能并了解用于工作流标准化的 MCP 提示

模块 2 将直接基于您在此处创建的服务器,添加动态事件处理以补充您的静态文件分析工具!

故事仍在继续…

有了您的 PR 代理,CodeCraft Studios 的开发人员已经能够编写出更好的拉取请求。但是下周,您将面临一个新挑战:关键的 CI/CD 故障正在悄无声息地溜走。模块 2 将添加实时监控,以便在这些问题到达生产环境之前捕获它们。

额外资源

< > 在 GitHub 上更新