Code Review 是开发流程中绑定的环节,但人工审查效率有限,容易遗漏问题。这篇文章介绍我写的一个工具,让 Cursor 能够直接读取 PR/MR、分析代码变更、生成审查意见并提交到对应平台。
项目地址:https://github.com/OldJii/code-review-mcp
思路
Cursor 本身不具备访问 GitHub/GitLab API 的能力,需要通过 MCP(Model Context Protocol)来扩展。MCP 是 Anthropic 推出的协议,允许 AI 模型与外部数据源和工具交互。
整体思路是:
- 写一个 MCP Server,封装 GitHub/GitLab 的 API
- 在 Cursor 中配置这个 MCP Server
- 用 mdc 规则文件定义审查规范,约束 AI 的审查行为
- 在 Cursor 中对话,让 AI 读取 PR、分析代码、提交评论
MCP Server
MCP Server 用 Python 实现,通过 stdio 与 Cursor 通信。核心是抽象出一个 CodeReviewProvider 基类,GitHub 和 GitLab 各自实现具体逻辑。
class CodeReviewProvider(ABC): @abstractmethod def get_pr_info(self, repo: str, pr_id: int) -> Dict: pass
@abstractmethod def get_pr_changes(self, repo: str, pr_id: int) -> Dict: pass
@abstractmethod def add_inline_comment(self, repo: str, pr_id: int, file_path: str, line: int, line_type: str, comment: str) -> Dict: pass
@abstractmethod def add_pr_comment(self, repo: str, pr_id: int, comment: str) -> Dict: passGitHub 和 GitLab 的 API 差异主要在两个地方:
- 认证方式:GitHub 用 Bearer Token,GitLab 用 PRIVATE-TOKEN Header
- 行内评论:GitLab 需要计算
line_code,GitHub 直接传行号
Token 获取
为了简化配置,没有让用户手动填写 Token,而是复用 gh 和 glab 命令行工具的认证信息。
GitHub 直接调用 gh auth token 获取:
def _get_token(self) -> str: try: result = subprocess.run( ["gh", "auth", "token"], capture_output=True, text=True ) if result.returncode == 0: return result.stdout.strip() except FileNotFoundError: pass return ""GitLab 需要从 glab 的配置文件中解析:
def _get_token(self) -> str: config_paths = [ Path.home() / ".config" / "glab-cli" / "config.yml", Path.home() / "Library" / "Application Support" / "glab-cli" / "config.yml", ]
for config_path in config_paths: if config_path.exists(): with open(config_path, 'r') as f: content = f.read() pattern = rf'{re.escape(self.host)}:.*?token:\s*([^\s\n]+)' match = re.search(pattern, content, re.DOTALL) if match: return match.group(1).strip() return ""这样用户只需要执行 gh auth login 或 glab auth login,MCP Server 就能自动获取 Token。
GitLab 行内评论
GitLab 的行内评论 API 比较麻烦,需要提供 line_code 参数。这个参数的格式是 {head_sha}_{old_line}_{new_line},需要从 diff 中解析出来。
def _find_line_code(self, diff: str, target_line: int, line_type: str, head_sha: str) -> str: lines = diff.split('\n') old_line = 0 new_line = 0
for line in lines: if line.startswith('@@'): match = re.match(r'@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@', line) if match: old_line = int(match.group(1)) - 1 new_line = int(match.group(2)) - 1 elif line.startswith('-'): old_line += 1 if line_type == "old" and old_line == target_line: return f"{head_sha}_{old_line}_" elif line.startswith('+'): new_line += 1 if line_type == "new" and new_line == target_line: return f"{head_sha}_{old_line}_{new_line}" else: old_line += 1 new_line += 1
return ""核心逻辑是遍历 diff 内容,根据 @@ 行头解析起始行号,然后跟踪 old_line 和 new_line 的变化,找到目标行对应的 line_code。
MCP 工具
最终暴露给 Cursor 的工具有 6 个:
| 工具 | 说明 |
|---|---|
get_pr_info | 获取 PR/MR 的标题、描述、分支等信息 |
get_pr_changes | 获取代码变更,支持按文件类型过滤 |
extract_related_prs | 从描述中提取关联的 PR 链接 |
add_inline_comment | 添加行内评论 |
add_pr_comment | 添加整体评论 |
batch_add_comments | 批量添加评论 |
batch_add_comments 是为了减少用户确认次数,一次性提交所有评论。
审查规范
MCP 只解决了”能做什么”的问题,“怎么做”需要通过 mdc 规则文件来约束。
mdc 是 Cursor 的规则文件格式,可以在项目的 .cursor/rules/ 目录下定义。AI 在对话时会参考这些规则。
核心原则
审查规范的核心是”理解优先”:
- 先理解 PR 整体目的,再看具体 diff
- 深度分析(架构/逻辑/性能)优先于风格检查
- 只提”确认的问题”,不提”可能的问题”
- 结合上下文分析,不孤立判断
最后一条很重要。AI 容易犯的错误是看到一个变量可能为空就报 NPE 风险,但实际上调用方可能已经做过校验。规则里明确要求 AI 追溯上下文,避免误报。
审查流程
规则里定义了完整的审查流程:
- 获取变更:调用
get_pr_changes获取所有文件的完整 diff - 理解上下文:从标题、描述、变更列表理解 PR 目的
- 深度分析:逐文件分析架构、逻辑、性能、安全问题
- 去重:同一文件相同问题合并,避免重复评论
- 预览确认:展示所有评论让用户确认
- 批量提交:调用
batch_add_comments一次性提交
第 5 步是关键。AI 生成的评论需要人工把关,避免提交低质量或错误的评论。
优先级
问题按严重程度分为三级:
- P0:崩溃、内存泄漏、严重性能问题、安全漏洞
- P1:架构问题、逻辑缺陷、代码质量
- P2:代码复用、命名优化
P0 问题不限数量,P1 和 P2 会根据 P0 的数量动态调整。如果 P0 超过 10 个,说明代码质量较差,此时减少 P1/P2 的数量,集中精力在严重问题上。
避免误报
规则里列举了常见的误报场景:
| 类型 | 误报条件 | 处理 |
|---|---|---|
| NPE | 调用方已校验 | 不提 |
| 越界 | 上文已检查长度 | 不提 |
| 性能 | 数据量 <= 5 | 不提 |
| 线程 | 耗时 < 1ms | 不提 |
这些规则是从实际 Review 经验中总结出来的。AI 的判断倾向于保守,容易对一些不是问题的代码报警。通过这些规则可以让 AI 更准确地识别真正的问题。
使用
配置
MCP 配置是全局的,编辑 ~/.cursor/mcp.json:
{ "mcpServers": { "code-review": { "command": "python3", "args": ["/path/to/cursor-ai-code-review/code_review_mcp.py"] } }}审查规范是项目级别的,需要复制到每个项目的 .cursor/rules/ 目录。这个设计是因为不同项目可能有不同的审查标准。
审查
配置完成后,在 Cursor 中直接输入:
Review https://github.com/owner/repo/pull/123AI 会自动调用 MCP 工具获取 PR 信息和代码变更,然后按照规则进行审查,审查完成后会展示所有评论供确认:

我删除了某 Flutter 项目中 一个Dart 文件的一行 import 代码,用于演示工具的使用流程。
确认无误后,AI 会调用 batch_add_comments 批量提交评论到 GitHub/GitLab。

私有 GitLab
如果使用私有化部署的 GitLab,在认证时指定地址:
glab auth login --hostname gitlab.yourcompany.comMCP Server 会自动从 glab 配置中读取对应的 Token。
局限
这个工具目前还有一些局限:
- 上下文有限:AI 只能看到 diff,无法读取完整的项目代码。对于涉及多文件交互的问题,分析能力有限。
- 规则依赖:审查质量很大程度取决于 mdc 规则的完善程度。规则写得不好,AI 可能遗漏问题或产生误报。
- 需要人工确认:每次提交评论前需要人工确认,无法完全自动化。这是有意为之,避免 AI 提交低质量评论。
后续可以考虑接入更多上下文,比如让 AI 能够读取相关文件、查看历史提交等。规则也可以根据实际使用情况持续优化。
总结
这个工具的核心价值是把 Code Review 的机械性工作交给 AI,人只需要确认最终结果。实际使用下来,对于常规的代码问题(空指针、资源泄漏、性能隐患等),AI 的识别率还是可以的。
但 AI 不能完全替代人工 Review。架构设计、业务逻辑这些需要深度理解上下文的问题,还是得靠人来判断。把 AI 当作辅助工具,提高效率的同时保持人的把关,是目前比较务实的用法。