Content
# PaddleOCR MCP Server
[](README_EN.md)
MCP Server that enables non-image-supported text models (like DeepSeek V4) to "see images".
## Principle
PaddleOCR MCP Server provides OCR text recognition capabilities for AI. AI calls the `recognize` tool, and MCP automatically extracts images from the current session transcript and returns all text content in the images.
## Installation
### 1. Create Environment and Install Dependencies
Supports **conda** or **venv**. For Windows GPU version, install from Paddle official CUDA dedicated source, not directly from default PyPI.
#### Method 1: conda (recommended for easy GPU dependency management)
```bash
conda create -n paddle_ocr python=3.10
conda activate paddle_ocr
# Windows GPU (select according to your CUDA version)
python -m pip install paddlepaddle-gpu==3.3.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/ # CUDA 11.8
python -m pip install paddlepaddle-gpu==3.3.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/ # CUDA 12.6
python -m pip install paddlepaddle-gpu==3.3.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu129/ # CUDA 12.9
# Windows CPU / macOS / Linux
pip install paddlepaddle paddleocr fastmcp
# For users in China, add Baidu mirror for paddleocr/fastmcp
pip install paddleocr fastmcp -i https://mirror.baidu.com/pypi/simple
```
#### Method 2: venv / virtualenv
```bash
# Create and activate virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# Install dependencies (Windows GPU select according to CUDA version)
pip install paddlepaddle-gpu paddleocr fastmcp
# Windows CPU / macOS / Linux
# pip install paddlepaddle paddleocr fastmcp
```
> **CPU users**: Replace `paddlepaddle-gpu` with `paddlepaddle`.
>
> **Windows can't find `paddlepaddle-gpu` version?** Confirm Python is 3.9-3.13 64-bit version and use the official source installation with CUDA version number.
PaddleOCR will automatically download model weights (~140MB) from ModelScope and cache in project `models/` directory for the first use.
### 2. Register MCP Server
PaddleOCR supports the following four AI programming tools:
| Platform | Configuration File (User-level) | Configuration File (Project-level) | Configuration Format | Status |
|------|-------------------|-------------------|:--:|:--:|
| **Claude Code** | `~/.claude.json` `mcpServers` field | `<project>/.mcp.json` | JSON | Tested |
| **Codex** | `~/.codex/config.toml` | `<project>/.codex/config.toml` | TOML | Not tested |
| **Cursor** | `~/.cursor/mcp.json` | `<project>/.cursor/mcp.json` | JSON | Not tested |
| **Trae** | `~/.trae/mcp.json` | `<project>/.trae/mcp.json` | JSON | Not tested |
> Recommended **user-level registration** - configure once, all projects can use.
#### Claude Code (tested)
Edit `~/.claude.json`, add in `mcpServers` field:
```json
{
"mcpServers": {
"PaddleOCR": {
"command": "E:/soft/anaconda3/envs/paddle_ocr/python.exe",
"args": ["E:/soft/OCR/Paddle_ocr/mcp_server.py"]
}
}
}
```
> **Note**: If `~/.claude.json` already has `mcpServers` field, merge `PaddleOCR` into it, don't create a new top-level `mcpServers`.
If using venv, change `command` to `.venv\Scripts\python.exe` (Windows) or `.venv/bin/python` (macOS / Linux).
#### Codex (not tested)
```toml
[mcp_servers.PaddleOCR]
command = "E:/soft/anaconda3/envs/paddle_ocr/python.exe"
args = ["E:/soft/OCR/Paddle_ocr/mcp_server.py"]
startup_timeout_sec = 30
tool_timeout_sec = 120
```
Or use CLI to add:
```bash
codex mcp add PaddleOCR -- "E:/soft/anaconda3/envs/paddle_ocr/python.exe" "E:/soft/OCR/Paddle_ocr/mcp_server.py"
```
Restart Codex terminal, `codex mcp list` to verify.
#### Cursor (not tested)
```json
{
"mcpServers": {
"PaddleOCR": {
"command": "E:/soft/anaconda3/envs/paddle_ocr/python.exe",
"args": ["E:/soft/OCR/Paddle_ocr/mcp_server.py"]
}
}
}
```
Restart Cursor, Settings → MCP panel should display green indicator.
#### Trae (not tested)
```json
{
"mcpServers": {
"PaddleOCR": {
"command": "E:/soft/anaconda3/envs/paddle_ocr/python.exe",
"args": ["E:/soft/OCR/Paddle_ocr/mcp_server.py"]
}
}
}
```
> Trae's `command` **must use absolute path**, not just `python`. Ensure Trae's Python interpreter is consistent with conda/venv environment.
Restart Trae IDE, MCP panel displays green indicator.
#### Precautions
- **Choose one registration method** (recommended user-level). If both user-level and project-level configure the same MCP, it will be loaded twice, leading to duplicate processes.
- All platforms' `command` and `args` paths need to be replaced with actual paths on your machine.
- macOS / Linux users change `python.exe` path to `python` or conda/venv environment's `bin/python`.
#### Verification
After restarting IDE, ask AI which tools are available, should see `mcp__paddleocr__recognize`, `mcp__paddleocr__recognize_batch`, `mcp__paddleocr__list_languages`, `mcp__paddleocr__set_language`, and `mcp__paddleocr__ocr_status`.
## Usage Scenarios
### Method 1: Drag Image to Claude Code
Drag image file directly into Claude Code input box, dialog will display `[Unsupported Image]` mark. AI will automatically call OCR to recognize image text.
### Method 2: Copy Image and Paste to Claude Code
Copy image (screenshot tool `Ctrl+C`, right-click copy image, etc.) and paste in Claude Code input box with `Ctrl+V`. Same will display `[Unsupported Image]` mark, AI will automatically recognize.
### Method 3: Explicitly Specify Image File Path
Directly tell AI the complete path of the image in the conversation, AI will call `recognize(image_path="C:/path/to/image.png")` for recognition.
```
Help me look at this image: C:\Users\Administrator\Desktop\screenshot.png
```
### Method 4: Batch Recognition
If need to recognize multiple local images at once, let AI call:
```
Please recognize the following images: C:\a.png, C:\b.png, C:\c.png
```
AI will call `recognize_batch(image_paths=["C:/a.png", "C:/b.png", "C:/c.png"])`.
Worker processes image list one by one. Model loads only at startup, subsequent requests don't need to preheat GPU.
## Improve Tool Invocation Accuracy
Claude Code's external models (like DeepSeek) may ignore MCP tool's own `instructions`, causing AI not to call OCR actively.
**Solution**: Write tool usage instructions explicitly in `CLAUDE.md`. Since `CLAUDE.md` is system-level prompt injection, priority is higher than MCP tool's own instructions, external models are more likely to comply.
Add at the end of `CLAUDE.md`:
```markdown
## Image Processing (when model can't see images)
When user message contains [Unsupported Image] mark, call `mcp__paddleocr__recognize` without parameters.
MCP will automatically extract images from current session transcript and perform OCR.
Then report recognition result as "read the following content from image".
```
> **Why this works**: MCP tool's own `instructions` are passed in tool definition form, some models pay less attention to them during tool calling decisions. While `CLAUDE.md` is system-level instruction, models are more likely to follow.
## Hardware Requirements
| | Minimum | Recommended |
|----------|---------------------|------------------------|
| GPU | NVIDIA GTX 1050 4GB | NVIDIA RTX 3060+ 8GB |
| VRAM | 4 GB | 8 GB+ |
| RAM | 4 GB | 8 GB+ |
| CUDA | 11.2+ | 12.x |
| cuDNN | 8.x | 9.x |
| Disk | ~200MB (model) | SSD |
Without GPU, automatically fallback to CPU mode, 5-10 times slower but still usable.
## Tools
### recognize
Recognize all text in the image.
- **Parameters**:
- `image_path` — complete path of image file (optional, automatically extract from transcript if not provided)
- `output_format` — output format: `text` (default) / `json` / `markdown`
- **Return**:
```json
{
"success": true,
"source": "transcript",
"images_found": 2,
"results": [
{
"index": 0,
"image": "screenshot.png",
"text_count": 3,
"texts": [{"text": "first line", "confidence": 0.99}],
"full_text": "first line\nsecond line"
}
]
}
```
#### output_format Description
- `text`: return `texts` and `full_text` (default).
- `json`: add `box` (four-point coordinates) and `confidence` in `texts`.
- `markdown`: return `markdown` field for direct insertion into documents.
Example:
```
Recognize this image in JSON format: C:\screenshot.png
```
AI will call `recognize(image_path="C:/screenshot.png", output_format="json")`.
### recognize_batch
Batch recognize multiple local images.
- **Parameters**:
- `image_paths` — list of image paths (required)
- `output_format` — output format: `text` (default) / `json` / `markdown`
- **Return**: same unified structure as `recognize`, `source` is `"batch"`
### list_languages
List language codes supported by PaddleOCR.
- **Return**: language list with `code` and `name`
### set_language
Switch OCR language model. Subsequent recognition requests will use the new language.
- **Parameter**: `lang` — language code, e.g., `en`, `japan`, `korean`
- **Return**: `{"success": true, "language": "en", "status": "ready"}`
> Switching language will reload model, taking a few seconds, recommend calling at the beginning of the session or when necessary.
### ocr_status
Check OCR engine status.
- **Return**: `{"success": true, "loaded": true, "status": "ready"}`
## Screenshot vs. Photo: Switch Recognition Mode
Default mode targets screenshots, UI interfaces, and code optimization. Can switch via environment variables without code modification.
**Default mode** (lightweight, loads detection + recognition models):
```bash
# No extra settings needed, default values are fine
PADDLEOCR_USE_TEXTLINE_ORIENTATION=false
PADDLEOCR_USE_DOC_ORIENTATION_CLASSIFY=false
PADDLEOCR_USE_DOC_UNWARPING=false
```
This mode uses ~900MB memory, inference takes ~0.3 seconds. Suitable for most scenarios.
**High-precision mode** (for photos, scanned documents, rotated/bent text):
```bash
PADDLEOCR_USE_TEXTLINE_ORIENTATION=true
PADDLEOCR_USE_DOC_ORIENTATION_CLASSIFY=true
PADDLEOCR_USE_DOC_UNWARPING=true
```
| Parameter | Effect | Applicable Scenarios |
|------|------|----------|
| `use_textline_orientation` | detect if text line is inverted (180°) | phone held upside down, rotated screenshot |
| `use_doc_orientation_classify` | detect document orientation (0°/90°/180°/270°) | horizontally shot vertical documents, rotated PDFs |
| `use_doc_unwarping` | flatten curved paper | shooting book pages, curved paper |
Cost is loading 4 models, memory increases to ~1.7GB, inference slightly slower but accuracy significantly improved.
**Multi-language**: switch via `PADDLEOCR_LANG`, e.g., `en`, `japan`, `korean`, `chinese_cht`, default is `ch`.
**CPU mode**: set `PADDLEOCR_CUDA_VISIBLE_DEVICES=""` to force use CPU (PaddleOCR uses GPU by default, set to empty string to disable CUDA).
## Architecture
```
Claude Code starts → read ~/.claude.json → start mcp_server.py (lightweight main process, ~85MB)
→ AI calls recognize() → main process spawns python ocr_worker.py (subprocess, ~900MB)
→ OCR complete → subprocess resident (default 300 seconds, adjustable via PADDLEOCR_IDLE_TIMEOUT)
→ no new requests, automatically exit, release GPU
```
| Process | Memory | Lifecycle |
|------|------|----------|
| mcp_server.py | ~85 MB | during Claude Code session |
| ocr_worker.py | ~900 MB | reusable within OCR idle timeout, exit after timeout |
## Environment Variables
| Variable | Default Value | Description |
|------|--------|------|
| `PADDLEOCR_CACHE` | `<script directory>/models` | model cache directory |
| `PADDLEOCR_SITE_PACKAGES` | (empty) | conda/venv's `Lib/site-packages` path for adding CUDA DLL directories |
| `PADDLEOCR_PYTHON` | (auto-detect) | absolute path of Python interpreter used to launch worker subprocess |
| `PADDLEOCR_IDLE_TIMEOUT` | `300` | worker idle auto-exit time (seconds) |
| `PADDLEOCR_LOG_LEVEL` | `INFO` | log level: `DEBUG` / `INFO` / `WARNING` / `ERROR` |
| `PADDLEOCR_LANG` | `ch` | OCR language: `ch` / `en` / `japan` / `korean` / `chinese_cht` etc. |
| `PADDLEOCR_CUDA_VISIBLE_DEVICES` | (empty) | specify used GPU, e.g., `0` or `0,1`; set to empty string to force CPU |
| `PADDLEOCR_USE_TEXTLINE_ORIENTATION` | `false` | text line orientation detection |
| `PADDLEOCR_USE_DOC_ORIENTATION_CLASSIFY` | `false` | document orientation classification |
| `PADDLEOCR_USE_DOC_UNWARPING` | `false` | document unwarping |
| `CLAUDE_PROJECTS_ROOT` | `~/.claude/projects` | transcript file search root directory |
| `CLAUDE_CODE_SESSION_ID` | Claude Code auto-injected | current session ID for precise transcript location, avoid window mix-up |
### Passing environment variables in MCP configuration example
#### Claude Code
```json
{
"mcpServers": {
"PaddleOCR": {
"command": "E:/soft/anaconda3/envs/paddle_ocr/python.exe",
"args": ["E:/soft/OCR/Paddle_ocr/mcp_server.py"],
"env": {
"PADDLEOCR_LANG": "ch",
"PADDLEOCR_USE_TEXTLINE_ORIENTATION": "true",
"PADDLEOCR_USE_DOC_ORIENTATION_CLASSIFY": "true",
"PADDLEOCR_USE_DOC_UNWARPING": "true"
}
}
}
}
```
## License
This project uses [MIT](LICENSE) open-source license.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available