firecrawl / firecrawl/anydoc

Feature request: local OCR provider hook (--ocr command) - delegate OCR to a user-supplied engine

Open
#157 1 comment 3 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
21.5k
Forks
1.3k
Avg merge
42m
Merged PRs (30d)
17

Description

## Context

AnyDoc converts born-digital documents fully locally, and scanned/image-only PDFs fail fast with `NeedsOcr` (exit code 3 in the CLI). The only built-in completion path today is `--ocr hosted`, which uploads the whole document to Firecrawl Parse.

## Problem

For privacy-sensitive, air-gapped or regulated workflows there is no way to complete the pipeline locally. Users who already run local OCR engines (marker, PaddleOCR, Tesseract, ocrmypdf, ...) have to wrap the CLI externally: catch exit 3, re-route the file to their own engine, and merge the outputs themselves.

Related but different from #146: that issue asks for bundled/inbuilt OCR engines. This request asks for the smaller, philosophy-preserving option: a delegation hook. AnyDoc itself would still ship no models and make no network calls; the user brings the engine.

## Proposal

Add an escape hatch that delegates OCR to a local command instead of Firecrawl Parse:

```
anydoc input.pdf --ocr command --ocr-command "my-ocr {input} --pages {pages} --out {output}"
```

(or an env var like `ANYDOC_OCR_COMMAND`)

Contract sketch:

- anydoc invokes the command for the OCR-requiring pages (or for the whole file first, if per-page splitting is out of scope initially)
- the command writes markdown/text to a file or stdout
- anydoc merges the result into its normal document model and serializes it through the existing GFM serializer, so downstream formatting stays consistent

This would give the `ocr` option a local-first third mode: `none` (current default, exit 3) / `hosted` (existing) / `command` (new).

## Why this fits the project

- Keeps the "no ML models, no external services" core intact: no bundled models, no network calls, the hook is user-owned local execution
- Makes anydoc a complete one-CLI solution for agent pipelines (Claude Code / Codex skills, CI, batch jobs) that must guarantee documents never leave the machine
- Engine choice stays with the user: CPU (Tesseract), GPU (marker, PaddleOCR), whatever their hardware supports

## Real-world workaround we run today

We route anydoc -> exit 3 -> marker (GPU OCR) in an external wrapper and had to add a PDF-splitting triage for mixed PDFs, because a single image-only page rejects the whole file and throws away all text pages that did extract fine, matching #144. A native hook, ideally with per-page granularity, would let us delete most of that wrapper code.

Happy to test a prototype or contribute the wrapper contract details if there is interest.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start from the CLI's existing --ocr modes and the NeedsOcr exit path, then trace how extracted content enters the document model and existing GFM serializer. The scope is complete when a local command mode can be invoked with the proposed contract and its output is merged into the normal serialized result, with the initial page-granularity decision documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.