使用 Model Context Protocol (MCP) 构建 GitHub PR 审查服务器

什么是 Model Context Protocol (MCP)?

MCP 是由 Anthropic 开发的开放标准,用于在 AI 模型和外部工具之间建立标准化的交互接口。它允许大型语言模型通过统一的方式与 API、数据库和商业应用程序进行动态交互。MCP 遵循客户端-服务器架构,客户端(如 Claude Desktop)请求信息并执行任务,而服务器提供访问外部工具和数据源的能力。

为什么使用 MCP?

  • 标准化 AI 集成:MCP 提供了结构化的方式来连接 AI 模型与工具。
  • 灵活性:允许轻松切换不同的 AI 模型和供应商。
  • 安全性:保持数据在您的基础设施内,同时与 AI 进行交互。
  • 可扩展性:支持多种传输方式,如 stdio、WebSockets、HTTP SSE 和 UNIX sockets。

MCP Demo 项目:PR 审查服务器

项目概述

本项目使用 MCP 构建一个 GitHub PR 审查服务器,集成 Claude Desktop 和 Notion。该服务器可以:

  1. 获取 GitHub PR 详情:从 GitHub 获取 PR 的元数据和文件变更。
  2. 分析代码变更:使用 Claude Desktop 直接分析代码变更。
  3. 生成 PR 审查摘要:生成 PR 审查的摘要和建议。
  4. 保存到 Notion:将审查结果保存到 Notion 进行跟踪。

步骤概述

  1. 环境设置:安装 Python 3.10+,使用 uv 包管理器设置环境。
  2. 安装依赖 :安装必要的 Python 包,包括 mcp[cli]requestspython-dotenvnotion-client
  3. 环境变量设置 :创建 .env 文件,存储 GitHub 和 Notion 的 API 密钥。
  4. GitHub 集成:编写代码从 GitHub 获取 PR 变更。
  5. 实现 MCP 服务器:创建 MCP 服务器,注册工具以获取 PR 详情和创建 Notion 页面。
  6. 运行 MCP 服务器:启动服务器,使用 Claude Desktop 进行 PR 审查。

代码示例

GitHub 集成示例

python 复制代码
import os
import requests
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) -> dict:
    """从 GitHub 获取 PR 变更"""
    pr_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/pulls/{pr_number}"
    headers = {'Authorization': f'token {GITHUB_TOKEN}'}
    
    try:
        pr_response = requests.get(pr_url, headers=headers)
        pr_response.raise_for_status()
        pr_data = pr_response.json()
        
        files_url = f"{pr_url}/files"
        files_response = requests.get(files_url, headers=headers)
        files_response.raise_for_status()
        files_data = files_response.json()
        
        changes = []
        for file in files_data:
            change = {
                'filename': file['filename'],
                'status': file['status'],
                '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_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
        }
        
        return pr_info
        
    except Exception as e:
        print(f"Error fetching PR changes: {str(e)}")
        return None

# 示例用法
pr_data = fetch_pr_changes('owner', 'repo', 1)
print(pr_data)

MCP 服务器示例

python 复制代码
import sys
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()
        
        self.mcp = FastMCP("github_pr_analysis")
        print("MCP Server initialized", file=sys.stderr)
        
        self._init_notion()
        self._register_tools()
    
    def _init_notion(self):
        self.notion_api_key = os.getenv("NOTION_API_KEY")
        self.notion_page_id = os.getenv("NOTION_PAGE_ID")
        
        self.notion = Client(auth=self.notion_api_key)
        print(f"Notion client initialized successfully", file=sys.stderr)
    
    def _register_tools(self):
        @self.mcp.tool()
        async def fetch_pr(repo_owner: str, repo_name: str, pr_number: int) -> dict:
            """获取 GitHub PR 变更"""
            pr_info = fetch_pr_changes(repo_owner, repo_name, pr_number)
            return pr_info
        
        @self.mcp.tool()
        async def create_notion_page(title: str, content: str) -> str:
            """创建 Notion 页面"""
            self.notion.pages.create(
                parent={"type": "page_id", "page_id": self.notion_page_id},
                properties={"title": {"title": [{"text": {"content": title}}]}},
                children=[{
                    "object": "block",
                    "type": "paragraph",
                    "paragraph": {
                        "rich_text": [{
                            "type": "text",
                            "text": {"content": content}
                        }]
                    }
                }]
            )
            return f"Notion page '{title}' created successfully!"
    
    def run(self):
        """启动 MCP 服务器"""
        self.mcp.run(transport="stdio")

if __name__ == "__main__":
    analyzer = PRAnalyzer()
    analyzer.run()

运行 MCP 服务器

使用以下命令启动 MCP 服务器:

bash 复制代码
python pr_analyzer.py

启动后,打开 Claude Desktop 应用程序,即可看到 MCP 的插件图标。通过 Claude Desktop,您可以分析 GitHub PR,并将结果保存到 Notion。

相关推荐
Hello World......25 分钟前
互联网大厂Java面试:从Spring到微服务的全面探讨
java·spring boot·spring cloud·微服务·面试·技术栈·互联网大厂
拾贰_C1 小时前
【SpringBoot】MyBatisPlus(MP | 分页查询操作
java·spring boot·后端·spring·maven·apache·intellij-idea
大大小小聪明3 小时前
Git合并多个提交方法详解
git·github
就叫飞六吧7 小时前
Spring Security 集成指南:避免 CORS 跨域问题
java·后端·spring
冼紫菜8 小时前
[特殊字符]CentOS 7.6 安装 JDK 11(适配国内服务器环境)
java·linux·服务器·后端·centos
Yvonne爱编码8 小时前
CSS- 4.1 浮动(Float)
前端·css·html·github·html5·hbuilder
秋野酱9 小时前
Spring Boot 项目的计算机专业论文参考文献
java·spring boot·后端
香饽饽~、9 小时前
【第二篇】 初步解析Spring Boot
java·spring boot·后端
冷yan~10 小时前
GitHub文档加载器设计与实现
java·人工智能·spring·ai·github·ai编程