Skip to main content
Glama
README.md
# 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

A3.9/5.0

Scored across 7 tools

Disambiguation4/5

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 Consistency2/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues