Umi-OCR MCP Server
# Umi-OCR MCP Server
[简体中文](README.md) | [English](README_EN.md)
通过 MCP 协议将 [Umi-OCR v2](https://github.com/hiroi-sora/Umi-OCR) 本地 OCR 能力暴露给 AI Agent(Hermes、Claude Code、Codex 等)。
自动拉起 Umi-OCR 进程,无需手动启动服务。
## 目录结构
```
Umi-OCR-MCP/
├── server.py # MCP 服务器(核心)
├── pyproject.toml # 依赖声明(uv run 自动安装)
├── requirements.txt # pip 依赖声明(备选)
├── config.yaml # Hermes config 接入模板
└── README.md
```
## 前置要求
| 依赖 | 说明 |
|------|------|
| Umi-OCR v2.1.5+ | 前往 [umi-ocr.com](https://umi-ocr.com/zh-CN/download) 下载 **Paddle 版(推荐)**,安装后开启 HTTP API(设置 -> 服务 -> 启用 HTTP API,默认端口 1224) |
| Python 3.11+ | 推荐通过 uv 管理 |
| uv | 包管理器,用于 `uv run` 自动安装依赖 |
## 快速开始
### 1. 确认 Umi-OCR 路径
默认路径:`YOUR_UMI_OCR_PATH\Umi-OCR.exe`
如不同,通过环境变量 `UMI_OCR_EXE` 指定。
> Windows 注意:路径中含中文/空格/特殊字符时,确保在 YAML 和环境变量中正确转义。
### 2. 测试 MCP 服务
```bash
cd YOUR_PROJECT_PATH\Umi-OCR-MCP
uv run server.py
```
首次运行 `uv run` 会自动读取 `pyproject.toml`,创建临时虚拟环境并安装 `mcp`、`requests` 依赖。
### 3. 接入 Hermes Agent
将 `config.yaml` 内容合并到 Hermes 的 `config.yaml` 的 `mcp_servers` 段:
```yaml
mcp_servers:
umi-ocr-mcp:
command: uv
args:
- run
- --directory
- YOUR_PROJECT_PATH/Umi-OCR-MCP
- YOUR_PROJECT_PATH/Umi-OCR-MCP/server.py
env:
UMI_OCR_URL: "http://127.0.0.1:1224/api/ocr"
UMI_OCR_EXE: "YOUR_UMI_OCR_PATH\\Umi-OCR.exe"
```
> 关键:`--directory` 参数告诉 uv 到哪里找 `pyproject.toml`,**不能省略**。缺了它 uv 找不到依赖,直接报 ModuleNotFoundError。
> 路径格式:推荐正斜杠 `D:/path/to/`。反斜杠在 YAML 中需转义为 `D:\\path\\to\\`。
## 工作原理
```
AI Agent -> MCP stdio -> server.py
1. 检测端口 1224 是否开放
2. 未开放 -> 自动启动 Umi-OCR.exe(指数退避等待,最长 30s)
3. 开放 -> 调用 HTTP API 识别图片
4. OCR 文本 -> 置信度过滤(>0.85)
5. 轻量后处理(常见 OCR typo 修正)
6. 返回纯文本给 Agent
```
### 服务保活
每次调用 `extract_text_umi_v2` 时自动检测端口。Umi-OCR 进程意外退出后,下一次调用会自动重新拉起,无需手动干预。
### 后处理规则
内置正则替换,修正无歧义的 OCR 常见错误(不影响 AI 理解的不修):
| 原始 | 修正 |
|------|------|
| packspace | backspace |
| AMDV | AMD-V |
| Windows102004 | Windows 10 2004 |
| 打并 | 打开 |
| 重新新 | 重新 |
后处理仅修正**可确定**的 OCR 噪声,超出规则范围的保留原样交由 AI 阅读理解。
## 常见问题
### ModuleNotFoundError: No module named 'requests'
uv run 默认隔离环境,看不到全局包。
**解决**:项目已含 `pyproject.toml`,确保用 `uv run --directory <项目目录>` 启动,uv 会自动安装依赖。
### Umi-OCR 启动超时
- 检查 `UMI_OCR_EXE` 路径是否正确
- 首次启动 Umi-OCR 需加载 PaddleOCR 模型,较慢机器可能需 15-30 秒
- 可在 Umi-OCR 设置中开启"开机自启"或"最小化到托盘"避免每次等待
### API 返回错误码
Umi-OCR v2 API 格式:
```
POST /api/ocr
{"base64": "<base64字符串>"}
```
返回:
```json
{"code": 100, "data": [{"text":"...","score":0.99}], "msg":"success"}
```
- code=100: 成功
- code=300: Base64 解码失败(传了数组而非字符串)
- code=802: 缺少 base64 字段
### 其他电脑部署
1. 安装 uv
2. 安装 Umi-OCR(从 [umi-ocr.com](https://umi-ocr.com/zh-CN/download) 下载 Paddle 版)并开启 HTTP API(端口 1224)
3. 修改 `config.yaml` 和 `server.py` 中的默认路径
4. 确认端口 1224 未被占用
5. 首次 `uv run` 需联网自动下载依赖
## API 参考
### 工具总览
| 工具 | 用途 | 类别 | Token 特点 |
|------|------|------|-----------|
| `quick_ocr_status` | 极简服务状态 | 检查 | 仅 ~5 字符输出 |
| `check_ocr_status` | 完整服务状态 | 检查 | ~200 字符输出 |
| `extract_text_umi_v2` | 单张图片 OCR | 核心 | 标准输出 |
| `ocr_image_base64` | Base64 直接 OCR | 核心 | 免去写文件步骤 |
| `ocr_batch` | 多张图片批量 OCR | 批量 | 一次调用处理多图 |
| `ocr_directory` | 目录扫描批量 OCR | 批量 | 免去 list + 构建清单 |
| `ocr_pdf_page` | PDF 单页直接 OCR | PDF | 免去渲染 + 存文件步骤 |
### quick_ocr_status
极简状态检查,适用于高频轮询。
```
参数:
无
返回:
"running" | "stopped" | "error: ..."
```
**Token 对比**:~5 chars vs `check_ocr_status` 的 ~200 chars,省 97%。
### check_ocr_status
完整服务状态信息。
```
参数:
无
返回:
服务运行状态、监听地址、API 端点、可执行文件路径
```
### extract_text_umi_v2
OCR 提取本地图片文本。内置段落合并与置信度过滤。
```
参数:
file_path: str -- 图片绝对路径(必填)
is_handwritten: bool -- 是否手写笔记,默认 False
返回:
str -- 识别文本,或错误信息
```
### ocr_image_base64
直接从 Base64 编码的图片提取文本,省去写文件步骤。
```
参数:
image_base64: str -- Base64 编码字符串(含 data URL 前缀亦可)
is_handwritten: bool -- 是否手写笔记,默认 False
返回:
str -- 识别文本,或错误信息
```
### ocr_batch
批量 OCR 多张本地图片,一次调用返回所有结果。
```
参数:
file_paths: List[str] -- 图片绝对路径列表
is_handwritten: bool -- 是否手写笔记,默认 False
返回:
str -- 按输入顺序的分隔线分区结果
```
### ocr_directory ⭐ v1.1 新增
扫描目录下所有图片并批量 OCR。递归模式下可处理子目录。
```
参数:
directory_path: str -- 目录绝对路径(必填)
extensions: str -- 逗号分隔的扩展名,默认 "png,jpg,jpeg,bmp,webp"
recursive: bool -- 是否递归子目录,默认 False
is_handwritten: bool -- 是否手写笔记,默认 False
confidence_threshold: float -- 置信度阈值,默认 0.85
返回:
str -- 紧凑格式:[总数] + 文件名 + 文本
```
### ocr_pdf_page ⭐ v1.1 新增
直接渲染 PDF 指定页为图像并 OCR,一步到位。依赖 PyMuPDF。
```
参数:
pdf_path: str -- PDF 文件绝对路径(必填)
page_number: int -- 页码(1-based),默认 1
is_handwritten: bool -- 是否手写笔记,默认 False
dpi: int -- 渲染分辨率,默认 200
confidence_threshold: float -- 置信度阈值,默认 0.85
返回:
str -- 识别文本,或错误信息
```
### 置信度阈值说明
所有 OCR 工具内部使用 `confidence_threshold` 过滤低质量结果。
需直接控制时使用新工具暴露的参数:
| 场景 | 推荐阈值 | 说明 |
|------|---------|------|
| 清晰印刷体 | 0.90+ | 极高精度,宁缺毋滥 |
| 标准文档 | 0.85 (默认) | 精度与召回平衡 |
| 扫描版教辅 | 0.70-0.80 | 纸张质量不一,需更高包容度 |
| 手写笔记 | 0.60-0.75 | 手写体识别率天然较低 |
## MCP 固定指令(Prompts)
MCP 协议支持 **Prompts** —— 预定义的固定指令模板。
Agent 通过专用工具 `get_prompt(name)` 调取,返回标准化的分步工作流指令。
server.py 已内置 3 个 Prompt,覆盖最常用的 OCR 场景。
### 在 Hermes 中调用
重启 MCP 连接后,Hermes 会自动注册 `mcp__umi_ocr__get_prompt` 工具。
调用方式:
```
# 列出所有可用 Prompt
mcp__umi_ocr__list_prompts()
# 调取特定 Prompt
mcp__umi_ocr__get_prompt(name="ocr-workflow-quick")
```
Prompts 返回的是**指令文本**(非执行结果),Agent 读取后按步骤调用对应的 Tool 完成实际 OCR。
---
### ocr-workflow-quick
**单张图片快速 OCR 标准流程。**
| 步骤 | 操作 | 工具 |
|------|------|------|
| 1 | 确认服务在线 | `quick_ocr_status` |
| 2 | 提取文本 | `extract_text_umi_v2(file_path)` |
| 3 | 质量不足 → 降阈值重试 | `extract_text_umi_v2(..., confidence_threshold=0.65)` |
适用:截图、单张试卷照片、板书拍照。
---
### ocr-workflow-pdf
**PDF 逐页 OCR 标准流程。**
| 步骤 | 操作 | 工具 |
|------|------|------|
| 1 | 确认服务在线 | `quick_ocr_status` |
| 2 | OCR 首页试探质量 | `ocr_pdf_page(pdf_path, page_number=1)` |
| 3 | 文字模糊 → 提高 DPI 到 300 | `ocr_pdf_page(..., dpi=300)` |
| 4 | 漏字严重 → 降阈值到 0.70 | `ocr_pdf_page(..., confidence_threshold=0.70)` |
| 5 | 质量 OK → 逐页提取 | 循环 `ocr_pdf_page(pdf_path, page_number=N)` |
适用:扫描版高考真题 PDF、电子教辅、论文。
---
### ocr-workflow-batch
**整本教辅/试卷批量 OCR 标准流程。**
| 步骤 | 操作 | 工具 |
|------|------|------|
| 1 | 确认服务在线 | `quick_ocr_status` |
| 2 | 扫描目录下所有图片 | `ocr_directory(dir, recursive=true)` |
| 3 | 抽查 2-3 个结果 | 人工或 Agent 判断质量 |
| 4 | 个别失败 → 单独重试 | `extract_text_umi_v2(path, confidence_threshold=0.65)` |
| 5 | 拼接为完整文档 | 按文件名排序合并 |
适用:按页扫描后存为多张图片的整本教材、多页试卷合集。
TDQS
Scored across 7 tools
Tools are mostly distinct: OCR methods target different input types (file, base64, PDF, batch, directory). The two status-check tools serve different granularities (detailed vs quick), but their overlap could cause slight confusion despite clear descriptions.
Naming is inconsistent: some tools use 'ocr_' prefix (ocr_batch, ocr_directory), others use different patterns (check_ocr_status, quick_ocr_status, extract_text_umi_v2). The 'extract_text_umi_v2' name includes a version suffix, breaking convention.
With 7 tools, the set is well-scoped for an OCR server. Each tool has a clear role: status checks, single-image OCR from various sources, batch, and directory scanning. No unnecessary tools.
Covers the main OCR workflow: status check, single image from file/base64/PDF, batch, and directory. Minor gaps like multi-page PDF OCR or clipboard input are absent but not critical for the core use case.