Skip to main content
Glama
idin9

idin9-doc-ocr-mcp

by idin9
README.md
# idin9-doc-ocr-mcp

Standalone **Model Context Protocol (MCP)** server for document OCR and **Thai tax invoice**
processing, with automated scanner ingestion (SMB/Shared Folder) and SQLite storage.

The server extracts tax invoices from PDFs and scanned images, parses the 13 core Thai
tax-invoice fields, applies three-tier routing (success / need-train / failed), and stores
results in SQLite. It can also poll an SMB scanner share or watch a local drop folder.

## Features

- **Digital + scanned documents** — PyMuPDF for embedded text, Tesseract (`tha+eng`) with
  image pre-processing (grayscale, de-noise, adaptive threshold, de-skew) for scans.
- **Thai tax invoice parsing** — supplier/buyer, 13-digit tax IDs, line items, summary,
  currency, and capture-rate scoring.
- **Three-tier routing**
  - `success` — 100% capture + valid totals + buyer verification → `processed/YYYY-MM/`
  - `need_train` — 80–99% capture → `Need-Train/`
  - `failed` — < 80% capture or non-tax document → `failed/`
- **Automated ingestion** — SMBv2/v3 scanner share polling and watchdog folder watching.
- **SQLite storage** — WAL mode, tax invoices + canonical contacts tables, full CRUD.
- **MCP tools** — exposed via FastMCP for Hermes / Claude Desktop / any MCP client.

## Requirements

- Python 3.11+
- Tesseract OCR with Thai + English language packs (`tesseract-ocr-tha`, `tesseract-ocr-eng`)
- Access to a scanner SMB share (optional)

### Debian / Ubuntu Tesseract install

```bash
sudo apt-get update
sudo apt-get install -y tesseract-ocr tesseract-ocr-tha tesseract-ocr-eng
```

## Installation

```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # then edit values
```

## Configuration

Copy `.env.example` to `.env` and adjust:

| Variable | Description |
| --- | --- |
| `SCAN_DROP_DIR` | Local/mounted scanner drop folder |
| `SMB_HOST`, `SMB_SHARE`, `SMB_USER`, `SMB_PASSWORD`, `SMB_DOMAIN` | SMB scanner share (leave blank to disable) |
| `DB_PATH` | SQLite database path |
| `TESSERACT_CMD`, `OCR_LANGUAGES`, `OCR_DPI` | OCR engine settings |
| `MIN_EMBEDDED_TEXT_CHARS` | Threshold to decide digital vs scanned extraction |

## Running

```bash
python -m src.mcp_server
```

Or with Docker:

```bash
docker compose up --build
```

## MCP Client Configuration

### Hermes

```json
{
  "mcpServers": {
    "idin9-doc-ocr-mcp": {
      "command": "python",
      "args": ["-m", "src.mcp_server"],
      "cwd": "/path/to/idin9-doc-ocr-mcp",
      "env": {
        "TESSERACT_CMD": "tesseract",
        "OCR_LANGUAGES": "tha+eng"
      }
    }
  }
}
```

### Claude Desktop

```json
{
  "mcpServers": {
    "idin9-doc-ocr-mcp": {
      "command": "python",
      "args": ["-m", "src.mcp_server"],
      "cwd": "/path/to/idin9-doc-ocr-mcp"
    }
  }
}
```

## Available Tools

| Tool | Purpose |
| --- | --- |
| `ocr_extract_invoice(file_path)` | Extract a single PDF/image invoice |
| `ocr_batch_process(folder_path?)` | Process all pending files in a folder |
| `ocr_poll_scanner_share()` | Pull & process new files from the SMB share |
| `ocr_get_record(invoice_id?, invoice_number?)` | Retrieve a stored record |
| `ocr_list_records(status?, limit=50)` | List records with filters |
| `ocr_manage_contact(action, tax_id, company_name?)` | CRUD on contacts |
| `ocr_review_queue(limit=50)` | List low-confidence (`need_train`) records awaiting human confirmation |
| `ocr_review_record(invoice_id, action, reviewer, notes?, corrected?)` | Confirm (→ success) or reject (→ failed) a review item |
| `ocr_system_health()` | DB/SMB/queue health report |

## Human Review Workflow (Multi-User)

Documents that score **80–99% capture** (or have valid totals but an unverified
buyer) are routed to `Need-Train/` and stored with status `need_train`. These are
held for human confirmation before they are trusted as final.

Two interfaces are provided, both backed by the same SQLite database:

### 1. MCP tools (for Claude Desktop / Hermes)

- `ocr_review_queue()` → returns pending items.
- `ocr_review_record(invoice_id, action="confirm"|"reject", reviewer, notes?, corrected?)`
  - **confirm** → status becomes `success`, file moves to `processed/YYYY-MM/`,
    reviewer identity and optional corrected fields are stored.
  - **reject** → status becomes `failed`, file moves to `failed/`.

### 2. Web UI (for manual multi-user review)

Run the review web server:

```bash
python -m src.webui
# or: idin9-doc-ocr-webui
# optional port: WEBUI_PORT=8080 python -m src.webui
```

Open `http://localhost:8080`. The queue lists every pending invoice; opening one
shows an editable form (header, supplier, buyer, summary) plus the raw OCR text.
A reviewer enters their name, then **Confirms as correct** or **Rejects as bad**.
The reviewer name is remembered via a cookie and recorded on the record
(`reviewer`, `reviewed_at`, `review_notes`, `review_status`).

The `tax_invoices` table gains these review columns: `review_status`
(`pending`/`confirmed`/`rejected`), `reviewer`, `reviewed_at`, `review_notes`.

## Data Layout

```
data/
  drop/        # scanner drop folder (watchdog)
  staging/     # temporary download area (SMB)
  processed/YYYY-MM/   # successful extractions
  Need-Train/           # 80-99% capture, for review/training
  failed/               # <80% capture or non-tax documents
  idin9_doc_ocr.db      # SQLite database
```

## Development & Tests

```bash
pip install -e ".[dev]"
pytest
```

## License

MIT

TDQS

B3.2/5.0

Scored across 9 tools

Disambiguation4/5

Most tools have clearly distinct purposes: extraction, batch processing, scanner polling, record retrieval, review, contact management, and health checks. The only slight overlap is between ocr_batch_process and ocr_poll_scanner_share, since both process files from directory-like sources.

Naming Consistency4/5

All tools share the ocr_ prefix and use snake_case, which creates a strong predictable pattern. However, ocr_batch_process and ocr_system_health deviate from the strict verb_noun structure used by most other tools.

Tool Count5/5

Nine tools is well-scoped for an OCR invoice processing server covering ingestion, extraction, retrieval, review, contacts, and system health. Each tool serves a meaningful part of the workflow without redundancy or bloat.

Completeness4/5

The toolset covers the main OCR invoice lifecycle: extract, batch process, poll scanner, retrieve/list records, review low-confidence results, manage contacts, and check health. Minor gaps exist, such as no direct update/delete for processed invoice records outside the review flow or explicit reprocessing of failed items.

Maintenance

ActivityMaintained
ResponsivenessNo issues