内容
# 近视
[](https://pypi.org/project/myopic/)
[](https://pypi.org/project/myopic/)
[](LICENSE)
[](https://registry.modelcontextprotocol.io)
**注册中心中名字最具讽刺意味的代码审查工具。** 它绝非近视眼 — 它会针对整个代码库审查你的合并请求,而不仅仅是当前差异。
<p align="center">
<img src="https://raw.githubusercontent.com/SurajKGoyal/myopic/main/assets/demo.svg" alt="一个小差异更改了 formatPrice 以返回字符串;仅限差异的审查者说它看起来不错,但 myopic 检查整个存储库,发现了 4 个调用者它会破坏,以及一个现有的重复项 — 两者都不会在差异中可见。" width="720">
</p>
> **公开构建。** 审查 **GitLab 合并请求和 GitHub 拉取请求** — 传递任一 URL。读取更改,针对整个代码库审查,并可以将审查结果作为内联评论发布回去。问题和拉取请求欢迎。
---
## 为什么
真正重要的错误很少出现在差异中。它们存在于差异 **未显示** 的内容中:调用者位于三个文件之外,现在该文件静默地放弃了每个兄弟文件遵循的约定,新的调用者已经存在,因此新的调用者是重复的。只读取补丁的审查者是 **近视的**。
myopic 是一个开源的 [MCP](https://modelcontextprotocol.io) 服务器,为你已经使用的 AI 客户端(Claude、Cursor 等)提供结构化的上下文,以便像了解代码库的人一样进行审查。它在你的机器上运行 — 你的代码永远不会离开它,不会有每个请求的账单,审查会在你自己的代理中使用你自己的标准:
- **精确读取更改** — 差异作为行号的 hunks 或按功能/类分组,**对任何 MR 大小都安全**(10,000 行的差异永远不会溢出上下文窗口)。
- **针对整个代码库审查** — 调用更改代码的位置(影响范围),调用者/被调用者图,以及可选的语义相似代码,以便您捕获破坏的约定和重复代码。
它与 [amnesic](https://github.com/SurajKGoyal/amnesic) 配合使用,后者是我的 MCP 服务器,为 SQL 数据库提供 AI 持久内存。
---
## 工具
以下所有工具 **今日即可使用**,除非特别注明。
**读取合并请求(通过构造方式确保令牌安全):**
| 工具 | 功能 |
|------|--------------|
| `mr_review_status` | 合并请求元数据 + 每个讨论线程 + 已解决/未解决,全部在一个调用中 |
| `mr_changed_files` | 无内容变化的文件清单(路径、统计数据、噪音标志)— 无差异内容,因此即使在巨大的合并请求中也保持较小 |
| `mr_diff_sections` | 按功能/类分组的差异(AST 感知),预算有限 |
| `mr_diff_lines` | 差异作为行号的 hunks — 精确的位置用于内联评论 — 预算有限 |
在大型合并请求中,差异工具返回一个有限的页面,并在 `omitted_files` / `truncated` 下列出其余部分,而不是失败;锁定文件、生成代码和二进制文件被列出但不展开。可以使用 `files_filter` 获取其余部分。
**针对整个代码库审查(指向本地克隆):**
| 工具 | 功能 |
|------|--------------|
| `dependency_impact` | 更改符号被使用的所有位置 — 影响范围(ripgrep + tree-sitter) |
| `trace_call_chain` | 符号的调用者/被调用者图 |
| `mr_review_context` | **标题** — 对于每个更改的符号:其影响(始终)+ 可选的语义相似代码 |
**可选语义层** (`myopic[semantic]`) — `index_repo`、`code_search` 和 `mr_review_context` 的语义部分。参见下文。
**关闭循环 — 验证,并(按请求)评论:**
| 工具 | 功能 |
|------|--------------|
| `mr_verify_review` | 对于每个现有的审查线程,评论行附近的差异更改 — 跟进提交是否解决了问题?(只读) |
| `mr_post_comments` | **一次写入** — 从具有指数退避的队列中一次发布内联评论(无草稿,无批量发布),因此部分进度得以保留,速率限制得到尊重 |
参见 [ROADMAP.md](./ROADMAP.md) 以了解下一步计划。
---
## 安装
[pipx](https://pipx.pypa.io) 将 myopic 隔离并安装在你的 PATH 上:
```bash
pipx install "myopic[semantic]" # 省略 [semantic] 以进行核心安装
```
更喜欢纯净的 venv?`python3 -m venv ~/.venvs/myopic && ~/.venvs/myopic/bin/pip install "myopic[semantic]"`,然后在示例中使用该二进制文件。
## 设置
myopic 需要具有 `api`(或 `read_api`)范围的个人访问令牌。向导引导您完成:
```bash
myopic init # 提示 URL + 令牌,验证,保存两者
myopic test # ✓ 已通过身份验证到 https://gitlab.com 作为 <you>
myopic doctor # 健康检查配置 +(如果启用)语义层
```
令牌保存在 `~/.config/myopic/.env`(chmod 600)中,并从 TOML 中引用为 `${GITLAB_TOKEN}` — 永远不会在配置文件本身中。可以使用 `myopic set-secret` 或通过 `myopic init --template` 手动编辑进行轮换。
**GitHub 拉取请求:** 只需传递拉取请求 URL。在环境中或 `config.toml` 中设置 `[github]` 部分的 `GITHUB_TOKEN`(具有拉取请求读取访问权限的 PAT)。
## 添加到你的 AI 客户端
**Claude Code** — 一个命令,无需编辑配置:
```
/plugin marketplace add https://github.com/SurajKGoyal/myopic-marketplace
/plugin install myopic@myopic
```
**任何其他 MCP 客户端**(Cursor、Claude Desktop 等)— 指向 `myopic` 命令:
```json
{
"mcpServers": {
"myopic": {
"command": "myopic"
}
}
}
```
如果你的客户端无法在 PATH 中找到它,请使用绝对路径(pipx 安装到 `~/.local/bin/myopic`)。
### 在内联中配置而不是 `myopic init`
将令牌放入 `env` 块中并跳过配置文件 — myopic 从环境中读取 `GITLAB_TOKEN` / `GITHUB_TOKEN`:
```json
{
"mcpServers": {
"myopic": {
"command": "myopic",
"env": { "GITLAB_TOKEN": "glpat-…", "MYOPIC_AUTO_PULL": "1" }
}
}
}
```
`MYOPIC_AUTO_PULL=1`(可选)在首次使用时拉取缺失的嵌入模型而不是出错。
## 使用
将你的 AI 指向合并请求:
> "审查此合并请求:https://gitlab.com/group/project/-/merge_requests/42"
客户端可以遵循的一个良好流程:`mr_changed_files` 查看形状 → `mr_diff_sections`(大型合并请求)或 `mr_diff_lines` 读取更改 → 然后,在本地克隆检查完毕后,使用 `dependency_impact` / `trace_call_chain`(或 `mr_review_context`)检查有风险的更改符号。
图形工具分析 `root` 处检查的内容,因此请先检查合并请求的分支 — 否则您正在审查目标分支,而合并请求的新代码不在那里。`myopic worktree <mr-url> <repo>` 在临时工作树中检查合并请求的头部(你的主检查不受影响)并打印路径以用作 `root`。
---
## 可选:语义搜索 (`myopic[semantic]`)
对于“这与代码库的其他部分一致吗?”— 重复、约定漂移、类似模式 — 启用语义层。它的 **可选**,因此基础安装保持轻量(无 torch,无重量级矢量 DB)。
嵌入来自你运行的本地 [Ollama](https://ollama.com) 服务器 — 你的代码永远不会离开你的机器。myopic 通过 HTTP 与 Ollama 通信;它不捆绑或启动它。一次性先决条件:
1. `pip install "myopic[semantic]"` — 添加 `lancedb` + `httpx`。
2. Ollama 运行(默认 `localhost:11434`,或设置 `MYOPIC_OLLAMA_URL`)。
3. 拉取嵌入模型:`ollama pull unclemusclez/jina-embeddings-v2-base-code`。
`myopic doctor` 检查所有三个并为您提供拉取模型的选项。
嵌入存储在具有混合(矢量 + 全文)搜索的嵌入式 [LanceDB](https://lancedb.com) 索引中,`mr_review_context` 为每个更改的符号添加语义相似的代码。**您不必手动运行 `index_repo`** — 额外安装后,`mr_review_context` 在第一次审查时索引代码库,并在过期时刷新,自动(禁用 `MYOPIC_AUTO_INDEX=0`; 图形传递不需要索引,始终运行)。`index_repo` / `myopic index` 仍然用于显式/ cron 使用。没有额外功能时,`mr_review_context` 返回图形信号。
**索引是增量和新鲜度感知的。** 首次 `index_repo` 是完整构建;之后,只有内容更改的文件会重新嵌入,因此刷新很便宜。`index_status(root)` 报告索引是否新鲜、`stale`(有多少提交落后于 main)或在不同模型上构建 — 新鲜度是针对存储库的 **主线** 进行衡量的,而不是当前检查点,因此审查功能分支永远不会使索引过时;只有 main 实际移动时才会。`code_search` 和 `mr_review_context` 携带该状态,因此过时的索引永远不会静默降低审查质量;AI 被告知在过时时提供刷新。
索引 **每个存储库,而不是每个检查点** — 在合并请求的头部进行的 `myopic worktree` 与其克隆的索引共享,因此审查新分支永远不会重建它;只有分支更改的文件会重新嵌入。
myopic 是一个_stdio 服务器(无后台进程),因此没有内置调度程序 — 但 `myopic index /path/to/repo` 是钩子。指向 cron 或 launchd 以在后台保持索引新鲜:
```bash
# 每小时刷新(增量 — 通常为秒)
0 * * * * myopic index /path/to/repo
```
使用 `MYOPIC_EMBED_MODEL` / `MYOPIC_OLLAMA_URL` 覆盖模型/端点。
---
## 配置参考
| 来源 | 键 | 备注 |
|--------|-----|-------|
| `config.toml` | `[gitlab].url` | GitLab 基本 URL(默认为 `https://gitlab.com`) |
| `config.toml` | `[gitlab].token` | 使用 `${GITLAB_TOKEN}` — 不要硬编码 |
| `.env`(配置文件旁边) | `GITLAB_TOKEN` | 实际令牌值(chmod 600) |
| 环境变量 | `MYOPIC_GITLAB_URL` / `GITLAB_URL` | 如果没有 TOML,则使用备用 |
| 环境变量 | `MYOPIC_GITLAB_TOKEN` / `GITLAB_TOKEN` | 如果没有 TOML,则使用备用 |
| 环境变量 | `MYOPIC_CONFIG` / `MYOPIC_HOME` | 覆盖配置文件/目录 |
| 环境变量 | `MYOPIC_EMBED_MODEL` / `MYOPIC_OLLAMA_URL` | 语义层模型 + 端点 |
| 环境变量 | `MYOPIC_AUTO_INDEX` | `0` 禁用审查期间自动索引(默认为开启) |
| 环境变量 | `MYOPIC_AUTO_PULL` | `1` 自动拉取缺失的嵌入模型(默认为关闭) |
## 安全
- **一次显式写入,其他均为只读。** 只有 `mr_post_comments` 会修改审查,并且仅在您请求时 — 所有其他工具仅读取合并请求和存储库数据。写入永远不会推测。
- **您的令牌保持本地。** 它位于您的 `.env` / 环境中,仅发送到您配置的 GitLab 实例 — 永远不会发送到任何第三方。
- 身份验证错误被净化,因此您的令牌永远不会泄漏到错误消息中。
- 可选的语义层完全在本地运行(您的 Ollama,一个磁盘索引) — 您的代码永远不会发送到第三方。
## 开发
```bash
pip install -e ".[dev]" # + ".[semantic]" 以开发语义层
pytest # 密封 — 无需网络、Ollama 或 lancedb
```
## 许可证
MIT © Suraj Goyal
<!-- MCP 注册中心所有权标记 — 请勿删除。 -->
mcp-name: io.github.SurajKGoyal/myopic