MCP 課程文件
模組 1:構建 MCP 伺服器
並獲得增強的文件體驗
開始使用
模組 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 混亂轉化為清晰
analyze_file_changes
- 獲取所有更改(8 個檔案,共 453 行!)get_pr_templates
- 向 Claude 展示 7 個可供選擇的模板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 可以理解簡單規則遺漏的上下文
- 自然語言:建議感覺像人,而不是機器人
- 適應性強:適用於任何程式碼庫或編碼風格
您將實現三個基本工具,為整個自動化系統建立模式:
- analyze_file_changes - 檢索 git diff 資訊和更改的檔案(資料收集)
- get_pr_templates - 列出可用的 PR 模板(資源管理)
- 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 註釋實現這三個工具。啟動程式碼提供了基本結構——您需要:
- 實現
analyze_file_changes
以執行 git 命令並返回 diff 資料- ⚠️ 重要:您可能會遇到令牌限制錯誤(每個響應最大 25,000 個令牌)
- 這是一個真實的限制,用於教授正確的輸出管理
- 請參閱下面的“處理大型輸出”部分以獲取解決方案
- ⚠️ 注意:Git 命令預設將在 MCP 伺服器的目錄中執行。有關詳細資訊,請參閱下面的“工作目錄注意事項”
- 實現
get_pr_templates
以管理和返回 PR 模板 - 實現
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
然後
- 在 Git 倉庫中進行一些更改
- 詢問 Claude:“您能分析我的更改並建議一個 PR 模板嗎?”
- 觀察 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)})
大型輸出的最佳實踐:
- 實現分頁:將大型結果分成多個頁面
- 新增過濾選項:允許使用者請求特定檔案或目錄
- 首先提供摘要:在完整內容之前返回統計資訊
- 使用漸進式披露:從高層資訊開始,允許深入檢視
- 設定合理的預設值:預設設定為適用於大多數情況的合理限制
工作目錄注意事項
預設情況下,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 伺服器開發的測試策略
下一步該怎麼做:
- 檢視解決方案(位於
/projects/unit3/build-mcp-server/solution/
)以瞭解不同的實現方法 - 將您的實現與提供的解決方案進行比較——解決問題沒有單一的“正確”方法
- 徹底測試您的工具——嘗試使用不同型別的程式碼更改來檢視 Claude 如何適應
- 繼續學習模組 2,您將在其中新增即時 webhook 功能並瞭解用於工作流標準化的 MCP 提示
模組 2 將直接基於您在此處建立的伺服器,新增動態事件處理以補充您的靜態檔案分析工具!
故事仍在繼續…
有了您的 PR 代理,CodeCraft Studios 的開發人員已經能夠編寫出更好的拉取請求。但是下週,您將面臨一個新挑戰:關鍵的 CI/CD 故障正在悄無聲息地溜走。模組 2 將新增即時監控,以便在這些問題到達生產環境之前捕獲它們。
額外資源
- MCP 文件
- FastMCP 指南
- 解決方案演練:
unit3/build-mcp-server-solution-walkthrough.md