Skip to content

Repository files navigation

MCP OCR Service

Python Version uv FastAPI MCP Linting: Ruff Security: Bandit Azure Functions CI/CD

A simple, robust, and highly optimized API and Model Context Protocol (MCP) server for Optical Character Recognition (OCR) on documents.

Table of Contents


Overview

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.

Features

  • Broad Format Support: Seamlessly processes standard images (PNG, JPG), multipage PDFs (via pypdfium2), and multipage TIFFs (via Pillow).
  • 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.

Installation & Setup

Prerequisites

  • Python 3.10+
  • uv (Extremely fast Python package manager)

Local Setup

Clone the repository and sync the environment:

git clone https://github.com/21010/mcp-ocr-api.git
cd mcp-ocr-api
uv sync

Configuration

Configure 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.

Deployment & Running

1. Run the REST API & MCP SSE Endpoint

uv run mcp-ocr-api

The API starts on http://localhost:8000. Swagger docs at /docs.

2. Run the MCP Server (stdio mode)

uv run mcp-ocr-stdio

Starts the FastMCP server, allowing LLMs to connect directly via standard input/output.

3. Docker Deployment

A fully optimized Dockerfile and docker-compose.yml are provided.

docker compose up --build -d

4. Azure Functions Deployment

This project is configured to run on Azure Functions via the Python v2 programming model. Run locally:

func start

Deploy directly to Azure:

func azure functionapp publish <YourFunctionAppName>

Usage & Integrations

Via REST API

Health Check

curl http://localhost:8000/health

OCR 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"

LLM Client Setup (Claude Desktop)

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..."

Project Structure

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

Development & Quality Assurance

This project enforces strict code quality and security checks.

Run the Test Suite

uv run pytest

Run Linting & Formatting

uv run ruff check .
uv run ruff format .

Run Static Type Checking

uv run pyrefly check

Run Security Analysis

uv run bandit -c pyproject.toml -r src

CI/CD (GitHub Actions)

A fully automated CI/CD pipeline is provided in .github/workflows/azure-functions-deploy.yml. On every push to the main branch, the pipeline will:

  1. Setup Python and uv.
  2. Run code linting (ruff), security scans (bandit), and unit tests (pytest).
  3. Automatically export dependencies and deploy the application to your configured Azure Function App.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Ensure all tests and linters pass (uv run pytest, uv run ruff check .)
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A fast, fully offline OCR API and MCP server optimized for edge environments without GPUs.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages