使用 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。

相关推荐
@_猿来如此8 分钟前
Django 实现电影推荐系统:从搭建到功能完善(附源码)
数据库·后端·python·django
言之。10 分钟前
【Go语言】ORM(对象关系映射)库
开发语言·后端·golang
独立开阀者_FwtCoder11 分钟前
TypeScript 是怎么工作的?一文带你深入编译器内部流程
前端·javascript·面试
Kusunoki_D14 分钟前
Win11 配置 Git 绑定 Github 账号的方法与问题汇总
git·github
独立开阀者_FwtCoder16 分钟前
前端自适应方案全面解析:打造多端适配的现代网页
前端·javascript·面试
zayyo32 分钟前
Web 应用轻量化实战
前端·javascript·面试
小华同学ai41 分钟前
牛!达摩院孵化开源项目,让数字人"活"起来:OpenAvatarChat教你轻松搭建自己的数字人
github
极客智谷1 小时前
深入理解Java线程池:从原理到实战的完整指南
java·后端
我的耳机没电了1 小时前
mySpace项目遇到的问题
后端
陈随易1 小时前
长跑8年,Node.js框架Koa v3.0终发布
前端·后端·程序员