什么是 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。该服务器可以:
- 获取 GitHub PR 详情:从 GitHub 获取 PR 的元数据和文件变更。
- 分析代码变更:使用 Claude Desktop 直接分析代码变更。
- 生成 PR 审查摘要:生成 PR 审查的摘要和建议。
- 保存到 Notion:将审查结果保存到 Notion 进行跟踪。
步骤概述
- 环境设置:安装 Python 3.10+,使用 uv 包管理器设置环境。
- 安装依赖 :安装必要的 Python 包,包括
mcp[cli]
、requests
、python-dotenv
和notion-client
。 - 环境变量设置 :创建
.env
文件,存储 GitHub 和 Notion 的 API 密钥。 - GitHub 集成:编写代码从 GitHub 获取 PR 变更。
- 实现 MCP 服务器:创建 MCP 服务器,注册工具以获取 PR 详情和创建 Notion 页面。
- 运行 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。