Skip to main content
Glama
README.md
# abbyy-finereader-ocr-mcp — Multi-Engine OCR MCP Server

A [Model Context Protocol](https://modelcontextprotocol.io) server that gives AI
assistants (Claude Code, Codex, Cursor, …) **OCR with first-class accuracy handling
and evaluation**. It wraps three engines behind one interface and can score and
compare them:

| Engine | Backend | Local? | Confidence | Notes |
|--------|---------|--------|-----------|-------|
| **RapidOCR** (default) | PaddleOCR models on [onnxruntime](https://onnxruntime.ai) | ✅ fully local/headless | per-line | No GPU/torch needed; great default |
| **Tesseract** | Google [Tesseract](https://github.com/tesseract-ocr/tesseract) via `pytesseract` | ✅ local | per-word | Needs `tesseract.exe` on PATH |
| **ABBYY FineReader 16** | local FineReader Regular CLI (`/send Clipboard`) | ✅ local | — | Best accuracy; GUI flashes, 1 doc at a time. Headless file output needs ABBYY's paid Extended CLI |

> **Why multi-engine?** No single OCR engine wins on every document. This server
> lets the model run several, **compare their agreement**, and **score them against
> ground truth (CER/WER)** — so you can pick the right engine per job instead of
> guessing.

## Features

- 📄 OCR images **and** PDFs (PDFs rasterized via PyMuPDF, per-page OCR).
- 🎯 **Confidence scores** per line/word, with low-confidence flagging.
- ⚖️ **`compare_engines`** — run every available engine on one document and report
  pairwise agreement + a consensus pick (no ground truth required).
- 📏 **`evaluate_accuracy`** — CER / WER, char/word accuracy %, and edit breakdown
  (substitutions/deletions/insertions) against a ground-truth text file.
- 🧹 Optional preprocessing (grayscale / denoise / deskew via OpenCV).
- 🧱 Fails soft: an unavailable engine is reported, never crashes the server.

## Tools

| Tool | Description |
|------|-------------|
| `list_engines()` | Which engines are usable on this machine + status. Call first. |
| `ocr_image(path, engine="auto", lang="en", preprocess=False)` | OCR one image. |
| `ocr_pdf(path, engine="auto", lang="en", pages="all", dpi=300)` | OCR a PDF. |
| `batch_ocr(paths_or_glob, engine="auto", lang="en")` | OCR many images (glob or JSON list). |
| `compare_engines(path, lang="en")` | Run all engines, compare agreement + consensus. |
| `evaluate_accuracy(ground_truth_path, ocr_text="" \| ocr_path="", engine, lang)` | CER/WER vs ground truth. |

`engine` ∈ `auto` (=RapidOCR) · `rapidocr` · `tesseract` · `finereader`.
`lang` is an ISO-639-1 code (`en`, `de`, `fr`, `ro`, `zh`, …), mapped per engine.

## Requirements

- **Python ≥ 3.12** (3.12 recommended — all wheels mature; 3.14 also works for the
  core RapidOCR path but OpenCV/PyMuPDF wheels may lag).
- **Tesseract** (optional): install [Tesseract-OCR](https://github.com/UB-Mannheim/tesseract/wiki)
  and add `tesseract.exe` to PATH for that engine.
- **ABBYY FineReader 16** (optional): a local install enables the FineReader engine
  (Regular-CLI clipboard mode). Headless file output requires ABBYY's Extended CLI license.

## Install

```bash
git clone https://github.com/Prekzursil/abbyy-finereader-ocr-mcp
cd abbyy-finereader-ocr-mcp
uv venv --python 3.12
uv pip install -e .
# (first OCR call downloads the small RapidOCR ONNX models, ~?? MB, cached locally)
```

## Configure

### Claude Code
```bash
claude mcp add ocr -s user -- "/abs/path/abbyy-finereader-ocr-mcp/.venv/Scripts/python.exe" "/abs/path/abbyy-finereader-ocr-mcp/index.py"
```

### Codex (`~/.codex/config.toml`)
```toml
[mcp_servers.ocr]
command = "D:\\path\\abbyy-finereader-ocr-mcp\\.venv\\Scripts\\python.exe"
args = ["D:\\path\\abbyy-finereader-ocr-mcp\\index.py"]
startup_timeout_sec = 60
tool_timeout_sec = 300

[mcp_servers.ocr.env]
PYTHONUTF8 = "1"
PYTHONUNBUFFERED = "1"
```

### Generic MCP client (`mcp.json`)
```json
{
  "mcpServers": {
    "ocr": { "command": "/abs/path/.venv/bin/python", "args": ["/abs/path/index.py"] }
  }
}
```

## Usage examples

```
> OCR this scan and tell me how confident you are.
  → ocr_image("C:/scans/invoice.png")  → text + mean_confidence + low-confidence lines

> Which engine reads this receipt best?
  → compare_engines("C:/scans/receipt.jpg")  → per-engine text + agreement + consensus

> How accurate is RapidOCR on this page vs my transcript?
  → evaluate_accuracy("truth.txt", ocr_path="page.png", engine="rapidocr") → CER/WER
```

## Evaluation methodology

`evaluate_accuracy` uses [`jiwer`](https://github.com/jitsi/jiwer) for **CER**
(character error rate) and **WER** (word error rate). Lower is better;
`char_accuracy_pct = (1 − CER)·100`. Keep ground-truth `.txt` files next to your
test images to track engine accuracy over time. `compare_engines` is the
no-ground-truth fallback: it reports how much the engines agree and which one is
the consensus.

## Development

```bash
uv pip install -e ".[test]"
pytest        # renders known text → OCR → asserts recovery + low CER
```

## Security

This server reads any file path the MCP client gives it — i.e. **any file readable by
the server process**. There is no sandbox by default. Run it only with a **trusted MCP
client**, and be aware that an LLM driving the tools could be prompted to read arbitrary
local files.

For defense-in-depth, set **`OCR_MCP_ALLOWED_DIRS`** (an `os.pathsep`-separated list of
directories) to restrict all tools to files under those roots:

```toml
[mcp_servers.ocr.env]
OCR_MCP_ALLOWED_DIRS = "D:\\scans;D:\\documents"
```

Also note: `batch_ocr` with a recursive glob (`**/*.png`) can match very large file
sets — scope your globs. The FineReader engine shells out to the local
`FineReaderOCR.exe` (list-form args, no shell) and reads the OS clipboard.

## License

MIT — see [LICENSE](LICENSE).

## Acknowledgements

[RapidOCR](https://github.com/RapidAI/RapidOCR) · [Tesseract](https://github.com/tesseract-ocr/tesseract) ·
[ABBYY FineReader](https://pdf.abbyy.com) · [jiwer](https://github.com/jitsi/jiwer) ·
[PyMuPDF](https://github.com/pymupdf/PyMuPDF) · [MCP](https://modelcontextprotocol.io)

TDQS

A4.1/5.0

Scored across 6 tools

Disambiguation5/5

Each tool serves a clearly distinct purpose: listing engines, OCR on single image, PDF, batch, cross-engine comparison, and accuracy evaluation. There is no overlap or ambiguity.

Naming Consistency4/5

Tool names follow a verb_noun pattern in snake_case, though some use 'ocr' as a verb prefix (ocr_image, ocr_pdf) while others use descriptive verbs (list_engines, compare_engines, evaluate_accuracy). This is mostly consistent and readable.

Tool Count5/5

Six tools is well-scoped for an OCR server, covering essential operations without bloat. Each tool earns its place.

Completeness4/5

Core OCR workflows are covered: single image, PDF, batch, engine listing, comparison, and accuracy evaluation. Minor gaps (e.g., no tool for engine configuration) but the surface is complete for typical use.

Maintenance

ActivityInactive
ResponsivenessNo issues