MCP驱动的Github PR审查系统
在这篇指南中,我将引导你构建一个强大的PR审查系统,该系统使用MCP协议将Claude与GitHub和Notion连接起来,创建一个自动化的流程,从而改变你的开发过程。

代码审查在当今快节奏的开发环境中至关重要,但非常耗时。如果可以使用人工智能简化这个过程呢?介绍模型上下文协议(MCP)——Anthropic的开源标准,正在改变AI模型与外部工具交互的方式。
在这篇指南中,我将引导你构建一个强大的PR审查系统,该系统将Claude与GitHub和Notion连接起来,创建一个自动化的流程,从而改变你的开发过程。
1、什么是模型上下文协议(MCP)?
模型上下文协议是由Anthropic开发的一个开源标准,它作为AI模型与外部工具之间的通用连接器。最初是为了增强Claude的功能而构建的,Anthropic在2024年初开源了MCP,以促进行业范围内的采用。
MCP遵循客户端-服务器架构,其中:
- MCP客户端(如Claude桌面版)请求信息并执行任务
- MCP服务器提供对外部工具和数据源的访问
- 主机应用程序促进模型与工具之间的通信

使用MCP的好处包括:
- 标准化集成:一种结构化的方法来连接AI与外部工具
- 灵活性:轻松切换不同的AI模型和供应商
- 安全性:保持敏感数据在您的基础设施内
- 可扩展性:支持多种传输协议,包括stdio、WebSockets、HTTP SSE和UNIX套接字
2、示例项目:构建PR审查服务器
我们的示例项目使用Claude桌面版自动化代码分析,并在Notion中记录审查结果。以下是流程:
- 设置GitHub和Notion的环境和凭据
- 初始化MCP服务器以与Claude桌面版通信
- 从GitHub获取PR更改和元数据
- 使用Claude桌面版分析代码更改
- 在Notion中记录分析结果
让我们逐步分解实现步骤。
3、设置环境
首先,我们将安装uv
包管理器,它提供了比conda更快更轻量的包管理方式:
# 对于Mac/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# 对于Windows(PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- 接下来,创建并设置项目目录:
uv init pr_reviewer
cd pr_reviewer
- 创建并激活虚拟环境:
# Mac/Linux
uv venv
source .venv/bin/activate
# Windows
.venv\Scripts\activate
- 安装所需的依赖项:
uv add "mcp[cli]" requests python-dotenv notion-client
4、设置依赖项和环境变量
创建一个requirements.txt
文件,内容如下:
# PR分析器的核心依赖项
requests>=2.31.0 # 用于GitHub API调用
python-dotenv>=1.0.0 # 用于环境变量
mcp[cli]>=1.4.0 # 用于MCP服务器功能
notion-client>=2.3.0 # 用于Notion集成
- 安装这些依赖项:
uv pip install -r requirements.txt
- 接下来,在
.env
文件中设置环境变量:
GITHUB_TOKEN=your_github_token
NOTION_API_KEY=your_notion_api_key
NOTION_PAGE_ID=your_notion_page_id
生成这些凭据的方法:
- GitHub令牌:登录GitHub → 设置 → 开发者设置 → 个人访问令牌 → 生成新令牌(经典)→ 启用
read:org
、read:repo_hook
和repo
权限 - Notion集成:
- 登录Notion的集成页面
- 创建一个新的内部集成
- 复制集成密钥(Notion API密钥)
- 复制集成URL中的UUID作为Notion页面ID
5、GitHub集成
创建一个github_integration.py
文件来处理PR数据检索:
import os
import requests
import traceback
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
def fetch_pr_changes(repo_owner: str, repo_name: str, pr_number: int) -> list:
"""从GitHub拉取请求中获取更改。
参数:
repo_owner: GitHub存储库的所有者
repo_name: GitHub存储库的名称
pr_number: 要分析的拉取请求编号
返回:
包含每个更改详细信息的文件更改列表
"""
print(f"正在为 {repo_owner}/{repo_name}#{pr_number} 获取PR更改")
# 获取PR详细信息
pr_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/pulls/{pr_number}"
files_url = f"{pr_url}/files"
headers = {'Authorization': f'token {GITHUB_TOKEN}'}
try:
# 获取PR元数据
pr_response = requests.get(pr_url, headers=headers)
pr_response.raise_for_status()
pr_data = pr_response.json()
# 获取文件更改
files_response = requests.get(files_url, headers=headers)
files_response.raise_for_status()
files_data = files_response.json()
# 将PR元数据与文件更改组合
changes = []
for file in files_data:
change = {
'filename': file['filename'],
'status': file['status'], # added, modified, removed
'additions': file['additions'],
'deletions': file['deletions'],
'changes': file['changes'],
'patch': file.get('patch', ''), # 实际差异
'raw_url': file.get('raw_url', ''),
'contents_url': file.get('contents_url', '')
}
changes.append(change)
# 添加PR元数据
pr_info = {
'title': pr_data['title'],
'description': pr_data['body'],
'author': pr_data['user']['login'],
'created_at': pr_data['created_at'],
'updated_at': pr_data['updated_at'],
'state': pr_data['state'],
'total_changes': len(changes),
'changes': changes
}
print(f"成功获取 {len(changes)} 次更改")
return pr_info
except Exception as e:
print(f"获取PR更改时出错: {str(e)}")
traceback.print_exc()
return None
# 示例用法进行调试
# pr_data = fetch_pr_changes('owner', 'repo', 1)
# print(pr_data)
此模块发送经过身份验证的HTTP请求到GitHub API,以检索有关拉取请求的全面信息,包括元数据和文件级更改。
6、实现MCP服务器
这个MCP服务器负责主要工作:
- 初始化环境:设置MCP服务器和Notion客户端
2. 注册工具:向Claude公开两个工具:
fetch_pr
:从GitHub检索PR详细信息create_notion_page
:在Notion中创建文档
3. 运行服务器:使用stdio作为通信的传输协议
现在,让我们创建核心PR分析器,该分析器将Claude桌面版与GitHub和Notion连接起来。创建一个pr_analyzer.py
文件:
import sys
import os
import traceback
from typing import Any, List, Dict
from mcp.server.fastmcp import FastMCP
from github_integration import fetch_pr_changes
from notion_client import Client
from dotenv import load_dotenv
class PRAnalyzer:
def __init__(self):
# 加载环境变量
load_dotenv()
# 初始化MCP服务器
self.mcp = FastMCP("github_pr_analysis")
print("MCP服务器已初始化", file=sys.stderr)
# 初始化Notion客户端
self._init_notion()
# 注册MCP工具
self._register_tools()
def _init_notion(self):
"""使用API密钥和页面ID初始化Notion客户端。"""
try:
self.notion_api_key = os.getenv("NOTION_API_KEY")
self.notion_page_id = os.getenv("NOTION_PAGE_ID")
self.notion_client = Client(auth=self.notion_api_key)
print("Notion客户端已初始化", file=sys.stderr)
except Exception as e:
print(f"初始化Notion客户端时出错: {str(e)}", file=sys.stderr)
traceback.print_exc()
def _register_tools(self):
"""注册MCP工具。"""
try:
# 注册fetch_pr工具
self.mcp.register_tool(
tool_name="fetch_pr",
description="从GitHub检索PR详细信息。",
func=self.fetch_pr_changes
)
print("fetch_pr工具已注册", file=sys.stderr)
# 注册create_notion_page工具
self.mcp.register_tool(
tool_name="create_notion_page",
description="在Notion中创建文档。",
func=self.create_notion_page
)
print("create_notion_page工具已注册", file=sys.stderr)
except Exception as e:
print(f"注册MCP工具时出错: {str(e)}", file=sys.stderr)
traceback.print_exc()
def fetch_pr_changes(self, repo_owner: str, repo_name: str, pr_number: int) -> Dict[str, Any]:
"""从GitHub拉取请求中获取更改。
参数:
repo_owner: GitHub存储库的所有者
repo_name: GitHub存储库的名称
pr_number: 要分析的拉取请求编号
返回:
包含PR详细信息的字典
"""
try:
pr_info = fetch_pr_changes(repo_owner, repo_name, pr_number)
if pr_info:
print(f"成功获取PR详细信息: {pr_info}", file=sys.stderr)
return {"success": True, "data": pr_info}
else:
print("无法获取PR详细信息", file=sys.stderr)
return {"success": False, "error": "无法获取PR详细信息"}
except Exception as e:
print(f"获取PR详细信息时出错: {str(e)}", file=sys.stderr)
traceback.print_exc()
return {"success": False, "error": str(e)}
def create_notion_page(self, title: str, content: str) -> Dict[str, Any]:
"""在Notion中创建文档。
参数:
title: 文档标题
content: 文档内容
返回:
包含创建状态的字典
"""
try:
response = self.notion_client.pages.create(
parent={"database_id": self.notion_page_id},
properties={
"Title": {
"title": [
{
"text": {
"content": title
}
}
]
}
},
children=[
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "text",
"text": {
"content": content
}
}
]
}
}
]
)
print(f"Notion页面已创建: {response['id']}", file=sys.stderr)
return {"success": True, "data": response}
except Exception as e:
print(f"在Notion中创建页面时出错: {str(e)}", file=sys.stderr)
traceback.print_exc()
return {"success": False, "error": str(e)}
def run(self):
"""运行MCP服务器。"""
try:
self.mcp.run()
except Exception as e:
print(f"MCP服务器运行时出错: {str(e)}", file=sys.stderr)
traceback.print_exc()
if __name__ == "__main__":
analyzer = PRAnalyzer()
analyzer.run()
7、运行MCP服务器
现在所有组件都已经就位,使用以下命令运行服务器:
python pr_analyzer.py
当服务器运行时,在Claude桌面应用程序中,你会注意到文本框旁边有一个插头图标(🔌),表示存在一个MCP服务器。一个类似锤子的图标(🔨)将显示所有可用的MCP工具。
8、使用PR审查系统
- 在Claude桌面中粘贴PR链接。
- Claude将使用你的MCP服务器获取PR详细信息。
- Claude将分析代码并提供摘要和审查意见。
- 您可以指示Claude将分析上传到Notion。
完成的工作流自动化了整个PR审查过程,从获取代码更改到在您的Notion工作区中记录分析。
9、结束语
通过利用模型上下文协议(MCP),我们构建了一个强大的集成系统,将Claude的智能与GitHub的PR数据以及Notion的文档功能连接起来。该系统展示了MCP如何作为通用连接器,使AI模型能够无缝地与外部工具和服务交互。
我们构建的PR审查系统提供了以下优势:
- 节省时间:自动化初始代码审查过程。
- 一致性:在整个PR中应用相同的分析模式。
- 文档记录:在Notion中维护可搜索的审查历史记录。
- 可扩展性:可以扩展以支持其他工具和服务。
MCP代表了创建标准化、互操作AI系统的重大进步,这些系统可以轻松集成到现有的工作流程和工具中。随着越来越多的组织采用这一开放标准,我们可能会看到各种领域中创新的AI驱动应用程序的爆炸式增长。
原文链接:Build a Claude-Powered PR Review System with MCP
汇智网翻译整理,转载请标明出处
