Skip to main content
Glama

ocr-mcp-server

OpenCodeReview 补上确定性分析这条腿。

OpenCodeReview 是一个 LLM 驱动的代码审查 CLI。它的架构是「确定性管线 + LLM Agent」, 但审查结论本身完全来自 LLM——模型没注意到的缺陷,它就漏掉了。项目 README 自己承认 这是有意的取舍:

Recall is explicitly lower than that of general-purpose agents — a deliberate trade-off favoring precision over noise.

本服务通过 OpenCodeReview 官方支持的 MCP 扩展点暴露 Semgrep,让审查 agent 在推理 之外多一条「规则匹配」的路径。规则匹配不是猜测——命中就是命中。


核心设计:只报 diff 里的行

这是本项目最有价值的部分,也是实测逼出来的。

OpenCodeReview 一次只审一个文件的 diff,且它的 prompt 明确禁止评论 diff 之外的 内容(见其 tools.md「收集该上下文时发现的任何问题按设计都会被忽略」)。

一个报「整个文件」的扫描器因此是有害的:它把大量 agent 必须丢弃的命中塞进上下文, 而漏过去的那部分会变成对一个 PR 从未改动过的代码的评论。所以本服务的默认工具是 semgrep_scan_diff,它先解析 git diff --unified=0 取出新侧改动行区间,扫完再按区间过滤:

base..head  ──►  git diff --unified=0  ──►  {file: [(start, end), ...]}
                                              │
              semgrep --json  ──► findings ──►│──► 只保留落在区间内的
                                              ▼
                                        可被 agent 直接采用的结果

被过滤掉的数量会一并返回(... N match(es) outside the changed lines were suppressed.), 这样「扫描干净」和「扫描被截断」不会被混为一谈。

Related MCP server: Luvv MCPServer

实测:这个方法在 AACR-Bench 上的边界

OpenCodeReview 的官方基准 AACR-Bench 有 196 个 真实 PR、1505 条由 80+ 资深工程师交叉验证的标注。我用它的前 5 个样本实测了确定性分析的 覆盖面:

仓库

参考标注

semgrep 命中

命中位置

vllm-project/vllm

1

0

lvgl/lvgl

5

13

12 条在 .github/workflows,与标注无关

FreeCAD/FreeCAD

3

6

全在构建脚本

elastic/elasticsearch

5

0

astral-sh/uv

6

未测(仓库未克隆)

参考标注所在的文件,semgrep 一条都没报。

原因不是工具失效——同一套代码在一个受控的两提交仓库上,把 SQL 注入、shell=True、 MD5 存密码三个缺陷全部报出(见下方冒烟测试输出)。原因是分布不重叠

  • AACR-Bench 的标注是人工 reviewer 级的语义评论:方法命名误导、注释与实现不符、 缓存失效、设计冗余。

  • Semgrep 是模式匹配器:它能找的是语法与数据流层面的已知缺陷模式。

因此在这个基准上,直接接入确定性分析不会提升 Recall,反而会显著拉低 Precision。 这个负结果写在这里,是因为它划定了方法的适用边界——把模式匹配器接到语义级评审基准上 是个错配,而这件事在动手之前并不显然。

未完成:在模式匹配能赢的场景(例如「安全修复提交的父提交」这类缺陷检出任务) 上的量化结果尚未测量。本仓库不声称任何 Recall 改进数字。

工具

工具

用途

semgrep_scan_diff

首选。 只扫 base..head 改动的行

semgrep_scan

扫整个文件,用于 diff 之外的自查

semgrep_status

报告分析器是否可用、版本、规则集与限额

返回格式刻意紧凑——每条命中一行,外加可直接用作评论锚点的源码片段:

app.py
  L9       ERROR   sqlalchemy.security.sqlalchemy-execute-raw-query  Avoiding SQL string concatenation...  [CWE-89]
          | return conn.execute("SELECT * FROM users WHERE name = '" + name + "'").fetchone()
  L17      ERROR   security.audit.subprocess-shell-true  Found 'subprocess' function 'run' with 'shell=True'.  [CWE-78]
          | return subprocess.run(f"echo {user_input}", shell=True)

实现中发现的坑

1. --config=auto--metrics=off 互斥

Semgrep 拒绝在关闭遥测时解析 auto 规则集:

Cannot create auto config when metrics are off.
Please allow metrics or run with a specific config.

审查沙箱里不该向外发遥测,所以默认钉死 p/default。副作用是好的:钉死的规则集让 基准可复现,而整个项目的意义就在于测出可比较的差值。

2. Semgrep 的 extra.lines 字段不可信

实测 semgrep 1.177.0:对同一文件里两条毫不相关的命中(shell=True 与 MD5 存密码), extra.lines 都返回同一个字符串 "requires login"——而这个字符串在被扫描的文件里 根本不存在。

所以源码片段不取 Semgrep 的字段,改为按报出的行号自己读文件。多一次文件读取, 换来不依赖一个未文档化、跨版本可能变化的行为。

安装

uv tool install semgrep
git clone <this repo> && cd ocr-mcp-server
uv sync

接入 OpenCodeReview

ocr config set mcp_servers.semgrep.command uvx
ocr config set mcp_servers.semgrep.args '["--from", "/abs/path/to/ocr-mcp-server", "ocr-mcp-server"]'
ocr config set mcp_servers.semgrep.tools '["semgrep_scan_diff", "semgrep_scan", "semgrep_status"]'

工具名刻意带 semgrep_ 前缀:OpenCodeReview 的内置工具与 MCP 工具共享同一命名空间, 重名会被静默跳过(file_readcode_search 等已被占用),不报错。

配置

环境变量

默认值

说明

OCR_MCP_SEMGREP_BIN

semgrep

分析器可执行文件

OCR_MCP_SEMGREP_CONFIG

p/default

规则集。可用 p/security-auditp/python 或本地规则文件

OCR_MCP_TIMEOUT

120

单次扫描超时(秒)

OCR_MCP_MAX_FINDINGS

50

单次返回的命中上限

测试

uv run pytest -q                      # 56 个单元测试
uv run python scripts/smoke_test.py   # 端到端:经 MCP 协议真实调用

单元测试用桩替换子进程,覆盖 Semgrep 缺失 / 超时 / 输出损坏 / 正常返回四种情况, 并验证路径穿越(../、绝对路径、空字节)被拒绝。test_diff.py 里的解析测试跑在 真实的临时 git 仓库上,而不是手写的 diff 文本。

冒烟测试走真实 stdio 传输启动服务,并在一个真实的两提交仓库上调用工具——它抓到过 单元测试抓不到的 bug:--config=auto--metrics=off 的冲突只在真实子进程里暴露。

技术栈

Python · MCP (Model Context Protocol) · Semgrep · uv · pytest

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for static analysis of multi-tenant SaaS and MCP server code, catching cross-tenant data leakage. Provides tools to scan code, list/explain rules, and manage suppressions.
    4,098
    4
    MIT