A simple, robust, and highly optimized API and Model Context Protocol (MCP) server for Optical Character Recognition (OCR) on documents.
- Overview
- Features
- Installation & Setup
- Configuration
- Deployment & Running
- Usage & Integrations
- Project Structure
- Development & Quality Assurance
- Contributing
- License
This project provides fast, fully offline OCR capabilities tailored for edge devices and non-GPU environments. It leverages RapidOCR and ONNXRuntime under the hood to ensure rapid processing without relying on heavy deep-learning frameworks like PyTorch or expensive cloud APIs.
It is designed following SOLID and CUPID principles, keeping the architecture stateless and easily integrable with Large Language Models (LLMs) via FastMCP.
- Broad Format Support: Seamlessly processes standard images (PNG, JPG), multipage PDFs (via
pypdfium2), and multipage TIFFs (viaPillow). - Fully Offline & CPU-Optimized: Runs beautifully on edge devices with configurable thread counts and memory limits.
- Dual Interfaces: Exposes both a standard REST API (FastAPI) and an MCP Server (FastMCP via SSE and stdio).
- Cloud Ready: Natively wrapped for serverless deployment on Azure Functions.
- Secure & Configurable: Features configurable CORS, host bindings, and strict file size limits to prevent edge OOMs.
- Python 3.10+
- uv (Extremely fast Python package manager)
Clone the repository and sync the environment:
git clone https://github.com/21010/mcp-ocr-api.git
cd mcp-ocr-api
uv syncConfigure the server using environment variables (managed via pydantic-settings). Defaults are highly optimized for edge limits:
| Variable | Default | Description |
|---|---|---|
OCR_HOST |
0.0.0.0 |
The network interface the API binds to. |
OCR_PORT |
8000 |
The port for the FastAPI server. |
OCR_CORS_ORIGINS |
["*"] |
Allowed CORS origins for the web API. |
OCR_API_KEY |
None |
Optional API Key to secure the REST endpoint. |
OCR_MAX_FILE_SIZE |
10485760 (10MB) |
Maximum allowed upload file size. |
OCR_INTRA_OP_THREADS |
2 |
ONNX runtime intra-op threads. |
OCR_INTER_OP_THREADS |
1 |
ONNX runtime inter-op threads. |
OCR_MAX_CONCURRENT |
1 |
Max concurrent OCR jobs allowed. |
uv run mcp-ocr-apiThe API starts on http://localhost:8000. Swagger docs at /docs.
uv run mcp-ocr-stdioStarts the FastMCP server, allowing LLMs to connect directly via standard input/output.
A fully optimized Dockerfile and docker-compose.yml are provided.
docker compose up --build -dThis project is configured to run on Azure Functions via the Python v2 programming model. Run locally:
func startDeploy directly to Azure:
func azure functionapp publish <YourFunctionAppName>Health Check
curl http://localhost:8000/healthOCR File Upload
curl -X POST http://localhost:8000/api/v1/ocr \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-F "file=@/absolute/path/to/document.pdf"To use this OCR server as a tool in Claude Desktop, add the following to your claude_desktop_config.json:
{
"mcpServers": {
"mcp-ocr": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/mcp-ocr-api",
"mcp-ocr-stdio"
]
}
}
}Once connected, you can prompt the LLM naturally:
- "Read the text from the document located at
C:/Users/user/Desktop/scanned.pdf" - "I have this base64 string of an image. Can you tell me what it says?
iVBORw0..."
mcp-ocr-api/
├── pyproject.toml # Dependency management via `uv`
├── Dockerfile # Container definition for production
├── docker-compose.yml # Compose file for easy orchestration
├── function_app.py # Azure Functions v2 entry point
├── host.json # Azure Functions configuration
├── src/
│ └── mcp_ocr/
│ ├── api/ # FastAPI application and routing
│ ├── core/ # Configuration and settings management
│ ├── mcp/ # FastMCP server definition and tools
│ ├── services/ # Core business logic (RapidOCR integration)
│ └── main.py # Entry points for CLI scripts
└── tests/ # Unit, Integration, and MCP testing
This project enforces strict code quality and security checks.
Run the Test Suite
uv run pytestRun Linting & Formatting
uv run ruff check .
uv run ruff format .Run Static Type Checking
uv run pyrefly checkRun Security Analysis
uv run bandit -c pyproject.toml -r srcA fully automated CI/CD pipeline is provided in .github/workflows/azure-functions-deploy.yml. On every push to the main branch, the pipeline will:
- Setup Python and
uv. - Run code linting (
ruff), security scans (bandit), and unit tests (pytest). - Automatically export dependencies and deploy the application to your configured Azure Function App.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Ensure all tests and linters pass (
uv run pytest,uv run ruff check .) - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.