QR Reader MCP Server
# QR Reader MCP Server
**一个 MCP 工具,让 AI 真正读懂二维码。视觉模型能"看到"有码但解不了——这个工具补上了这一步。不只返回内容,还告诉 Agent 码清不清楚、值不值得增强重试。**
`decode_qrcode_full` 只需图片输入即可工作,任何对接了 MCP 的模型都能直接调用。`auto_enhance` 在质量不佳时自动尝试增强恢复,无需手动干预。`enhance_and_decode` 适合需要精确控制的场景。
> 🤖 **通过 AI Agent 安装** — 把这条链接发给你的 AI Agent,它会自动完成安装配置:
>
> https://raw.githubusercontent.com/Endymionus/qr-reader-mcp-server/main/INSTALL_FOR_AGENT.md
[](https://www.python.org/)
[](LICENSE)
[](https://modelcontextprotocol.io/)
---
## 解决什么问题
AI 模型面临一个尴尬的问题:有视觉能力的模型能认出"图里有一个二维码",但二维码解码走的是像素→二进制数据→文本的算法路径,模型做不到;纯文本模型更不用说,连"看到图里有码"都做不到。
QR Reader MCP Server 把 zbar 二维码解码能力**嵌入** AI 工作流——只要有图片输入,就能读出码里的内容。视觉模型可主动触发,纯文本模型通过用户引导触发。
### 工作流
```
图片 → decode_qrcode_full → SUCCESS? → 直接用
↓
RETRYABLE? → auto_enhance → 自动恢复
↓
需精确控制? → enhance_and_decode
```
三个工具各司其职——`decode_qrcode_full` 先行诊断,`auto_enhance` 一键自动恢复,`enhance_and_decode` 精确手动控制。
### 三个工具
| 工具 | 说明 |
|---|---|
| `auto_enhance` | 一键自动恢复 — 7 种增强策略有序尝试,首次成功即返回。成功后除 JSON 诊断外还返回增强区域的 PNG 截图(ImageContent),供多模态模型直接查看增强效果 |
| `enhance_and_decode` | 手动精控 — 对指定区域执行自定义增强后再解码 |
| `decode_qrcode_full` | 扫描整张图片,返回所有条形码的内容 + 质量诊断。支持 `symbologies` 参数按码制过滤 |
### 比成功/失败更多的信息
实际场景中二维码质量参差不齐——模糊、反光、太小、对比度不够。MCP 在返回解码结果的同时,也附带了图像质量数据(模糊度、对比度[标准差+ISO15415调制比]、反光比例[空间方差])和 `result_code`。Agent 拿到这些信息后,可以自然地告诉用户"这个码有点模糊,换个角度拍"或者"反光挡住了,调整一下光源",也可以直接调用 `auto_enhance` 自动修复。
---
## 快速开始
### 前置依赖
```bash
# Ubuntu / Debian
sudo apt install libzbar0
# macOS
brew install zbar
# Windows (choco — CI verified)
choco install zbar
```
### 安装运行
```bash
# 推荐:uvx 一行安装(Python 3.10+, 自动处理依赖)
uvx qr-reader-mcp-server
# 或:git clone + pip 安装
pip install . # 基础版(~15 MB)
pip install ".[full]" # 全功能版(~120 MB)
```
**两种安装方式 — 按需选择:**
```bash
# ── 基础版(推荐,~15 MB)───────────────────────────────
# pyzbar 解码 + 全部 3 个工具 + 质量诊断
pip install .
# ── 全功能版(需要最强能力)─────────────────────────────
# 基础版全部功能 + OpenCV 解码回退 + finder-pattern 畸变检测
pip install ".[full]"
```
| | 基础版 | 全功能版 `[full]` |
|---|---|---|
| 下载大小 | ~15 MB | ~120 MB |
| decode_qrcode_full | ✅ | ✅ |
| auto_enhance | ✅ | ✅ |
| enhance_and_decode | ✅ | ✅ |
| 质量指标(blur/contrast/glare/noise/modulation) | ✅ | ✅ |
| distortion (finder-pattern 几何畸变) | ❌ | ✅ |
| OpenCV 解码回退 | ❌ | ✅ |
```bash
# uvx 安装 → 启动(stdio 模式)
uvx qr-reader-mcp-server
# 或 pip 安装后启动
python -m qr_reader.server
```
### MCP 客户端配置
**Claude Desktop / VS Code Copilot / Cursor:**
按你的安装方式选一个。用 uvx 安装(推荐):
```json
{
"mcpServers": {
"qr-reader": {
"command": "uvx",
"args": ["qr-reader-mcp-server"],
"env": {
"LOG_LEVEL": "info",
"READ_ONLY_MODE": "false"
}
}
}
}
```
用 pip 安装:
```json
{
"mcpServers": {
"qr-reader": {
"command": "python",
"args": ["-m", "qr_reader.server"],
"env": {
"LOG_LEVEL": "info",
"READ_ONLY_MODE": "false"
}
}
}
}
```
> ⚠️ 两种配置不能混用:uvx 隔离环境下 `python -m qr_reader.server` 找不到包;pip 环境下 `uvx` 会重新拉取而不是用本地安装。
**Docker:**
```json
{
"mcpServers": {
"qr-reader": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"ghcr.io/Endymionus/qr-reader-mcp-server"
]
}
}
}
```
### 环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
| `LOG_LEVEL` | `info` | 日志级别:`debug`、`info`、`warning`、`error` |
| `READ_ONLY_MODE` | `false` | 设为 `true` 禁用 `enhance_and_decode`(仅保留 `decode_qrcode_full`) |
| `MAX_IMAGE_SIZE` | `10485760` | 图片大小上限(字节,默认 10 MB) |
| `MAX_INPUT_PIXELS` | `4096` | 图片长边超过此值自动缩放 |
| `MAX_OUTPUT_PIXELS` | `16384` | 增强管线单步输出长边上限(upscale 超限即拒绝,防链式放大 OOM) |
| `QR_BLUR_THRESHOLD` | `50.0` | Laplacian 方差归一化阈值(模糊贡献 = 阈值 ÷ 实际方差) |
| `QR_CONTRAST_PERFECT` | `0.50` | 对比度归一化锚点(实际对比度越接近此值越健康) |
| `QR_MODULATION_PERFECT` | `0.70` | ISO 15415 调制比归一化锚点 |
| `QR_GLARE_MAX` | `0.30` | 反光归一化上界(超过视为严重反光) |
| `QR_NOISE_MAX` | `50.0` | 噪声归一化上界 |
| `QR_ANGLE_MAX` | `30.0` | 畸变角度归一化上界(度) |
| `QR_LEG_RATIO_MIN` | `0.60` | 畸变腿比归一化下界 |
---
## 工具说明
### `decode_qrcode_full`
对整张图片进行二维码识别和解码,返回结构化结果和质量指标。
**输入参数:**
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `image_path` | string | 三选一 | 本地图片绝对路径(推荐——无管道开销) |
| `image_base64` | string | 三选一 | Base64 编码的图片 |
| `image_url` | string | 三选一 | 图片 URL |
**返回示例:**
> `blur_score` 是拉普拉斯方差:**数值越大图像越清晰**(高对比度边缘多),越小越模糊。`contrast` 是归一化标准差,越大对比度越高。两者方向相反,Agent 集成时请注意。
```json
{
"success": true,
"result_code": "SUCCESS",
"results": [
{
"content": "https://example.com",
"bbox": [50, 60, 200, 200],
"type": "QRCODE",
"raw_bytes": "..."
}
],
"analysis": {
"total_detected": 1,
"modulation": 0.92,
"quality": {
"blur_score": 128.5,
"contrast": 0.72,
"glare_ratio": 0.05,
"noise_level": 12.3
}
},
"suggestion": null,
"image_size": [600, 800],
"resize_factor": 1.0
}
```
### `auto_enhance`
质量不佳时的一键自动恢复。7 种增强策略有序尝试(upscale / sharpen / contrast / denoise / 组合策略),首次解码成功即返回,无需手动指定 bbox 或 operation。
**输入参数:**
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `image_path` | string | 三选一 | 本地图片绝对路径 |
| `image_base64` | string | 三选一 | Base64 编码的图片 |
| `image_url` | string | 三选一 | 图片 URL |
| `bbox` | [int,int,int,int] | 否 | 可选目标区域,不传则处理全图 |
**返回示例(成功):**
```json
{
"success": true,
"applied_strategy": "upscale_2x",
"strategies_tried": 1,
"result_code": "SUCCESS",
"results": [{"content": "https://example.com", "type": "QRCODE"}],
"image_size": [96, 96],
"resize_factor": 1.0
}
```
**返回示例(全部失败):**
```json
{
"success": false,
"applied_strategy": null,
"strategies_tried": 7,
"result_code": "NO_QR_FOUND",
"suggestion": "All 7 enhancement strategies failed to decode a QR code..."
}
```
### `enhance_and_decode`
裁剪指定区域,执行增强操作后再解码。
**输入参数:**
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `image_path` | string | 三选一 | 本地图片绝对路径(推荐——无管道开销) |
| `image_base64` | string | 三选一 | Base64 编码的图片 |
| `image_url` | string | 三选一 | 图片 URL |
| `bbox` | [int,int,int,int] 或 [[int,int,int,int], ...] | 是 | 目标区域。单区域传 `[x, y, width, height]`,多区域传 `[[x1,y1,w1,h1], ...]` |
| `operations` | object[] | 否 | 增强操作列表(见下方),不传则仅裁剪解码 |
**增强操作:**
| 操作 | 说明 | 关键参数 |
|---|---|---|
| `upscale` | 放大区域 | `scale`(默认 2.0) |
| `sharpen` | 锐化边缘 | `strength`(默认 1.5) |
| `adjust_contrast` | 调整对比度 | `alpha`(默认 1.5),`beta`(默认 0) |
| `denoise` | 降噪 | `h`(默认 10) |
---
## 结果码说明
`result_code` 告诉 AI 助手下一步该做什么:
| 结果码 | 含义 | AI 应该做什么 |
|---|---|---|
| `SUCCESS` | 解码成功 | 直接使用内容 |
| `SUCCESS_WITH_WARNING` | 解码成功但内容可能有异常 | 检查警告,验证内容 |
| `RETRYABLE` | 质量问题,可修复 | 调用 `auto_enhance`(推荐)或 `enhance_and_decode` |
| `NO_QR_FOUND` | 未检测到二维码 | 告知用户图中没有二维码 |
| `QR_UNRECOVERABLE` | 二维码已损坏无法恢复 | 告知用户二维码损坏 |
---
## 示例对话
接入后试试对 AI 助手说:
- "帮我读一下这张截图里的二维码"
- "这个二维码太模糊了,试试增强后再读"
- "扫描这张照片里的所有二维码,列出内容"
- "这个收据上的码很难扫——能修复一下吗?"
---
## 只读模式
设置 `READ_ONLY_MODE=true` 后,仅保留 `decode_qrcode_full`。`auto_enhance` 和 `enhance_and_decode` 均不可用——AI 只能扫描,不能运行增强管线。
> 注意:只读模式是**行为约束**,不是安全边界——三个工具本就不写磁盘、不改动文件,增强操作也只在内存中计算。它控制的是"AI 能调用哪些工具",而非"进程能否产生副作用"。
适用于审计/日志场景,避免 Agent 对图像执行计算密集的增强重试。
---
## 安全说明
- 通过 `image_path` 读取调用方指定的本地图片(仅扩展名白名单过滤)
- `image_url` 通过五层 SSRF 防御(单次 DNS 解析 + 连接钉定到校验 IP + hostname 黑名单 + 禁用重定向 + scheme 白名单)保护内网安全
- stdio 模式下无需 API Key 或认证
- 设置 `MAX_IMAGE_SIZE` 可限制内存占用
- 日志不记录图片内容和解码数据
---
## 项目结构
```
qr-reader-mcp-server/
├── README.md
├── LICENSE
├── pyproject.toml
├── requirements.txt
├── .env.example
├── .gitignore
├── Dockerfile
├── docker-compose.yml
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── release.yml
├── docs/
│ ├── setup.md
│ ├── tools.md
│ ├── troubleshooting.md
│ └── prompts.md
├── src/
│ └── qr_reader/
│ ├── __init__.py
│ ├── server.py # MCP 入口 + 三工具注册
│ └── core/
│ ├── __init__.py
│ ├── decoder.py # 二维码解码(pyzbar + OpenCV fallback)
│ ├── ops.py # 统一图像操作层(cv2 / Pillow 双后端)
│ ├── quality.py # 图像质量分析 + ISO 15415 modulation
│ ├── diagnosis.py # 五级结果码分类
│ ├── distortion.py # finder-pattern 几何畸变检测
│ └── url_utils.py # 四层 SSRF 防护
├── tests/
│ ├── test_decoder.py
│ ├── test_diagnosis.py
│ ├── test_e2e.py
│ ├── test_quality.py
│ ├── test_server.py
│ └── test_ssrf.py
├── benchmarks/ # pytest-benchmark 性能回归
├── INSTALL_FOR_AGENT.md # AI Agent 自动安装指南
├── CHANGELOG.md
└── SECURITY.md
```
---
## 开源协议
MIT — 详见 [LICENSE](LICENSE)。
TDQS
Scored across 3 tools
The tools are largely distinct: decode_qrcode_full performs initial scanning, enhance_and_decode allows manual enhancement of a region, and auto_enhance automatically tries strategies. The overlap between enhance_and_decode and auto_enhance is clear from descriptions, with one being manual and the other automatic.
Tool names follow no consistent pattern: 'decode_qrcode_full' is verb_noun_adjective, 'enhance_and_decode' is two verbs joined by 'and', and 'auto_enhance' is a prefixed verb. They are readable but structurally inconsistent.
Three tools is well-scoped for a QR reader server, covering the core decode step and two enhancement recovery approaches without unnecessary bloat. Each tool has a clear role in the workflow.
The surface covers initial decoding and recovery through enhancement, but lacks a direct 'decode region without enhancement' tool. This is a minor gap since the enhancement tools can also handle regions, but a simple region decode would be a natural addition.