Start here

Quick start & APIInstallOnline OCRCode generator

Models & pipelines

PP-OCRv6 modelsLanguagesPP-StructureV3PaddleOCR-VL

Deploy & integrate

Serving & APIPaddleOCR.jsMCP server

Fix & upgrade

TroubleshootingMigrate from 2.xReleases

Evaluate

Our benchmarkCompare OCR toolsLicense & cost

Tools

Online OCRInstall command builderCode generatorError fixer2.x → 3.x converterLanguage code finder

Language

English简体中文日本語Try OCR online
Deploy & integrate

PaddleOCR MCP server: OCR tools for Claude and other agents

paddleocr-mcp is the official Model Context Protocol server from the PaddleOCR team. It gives Claude, or any MCP host, one OCR or document-parsing tool backed by local inference, Baidu's hosted API, Qianfan, or your own PaddleOCR server. Below are the exact configs, and what happened when we connected it to a self-hosted server.

Checked against PaddleOCR 3.7.0Updated 11 min read
On this page
  1. Pick an inference mode first
  2. The three tools
  3. Install
  4. Claude Desktop configuration
  5. Claude Code, Cursor and other MCP hosts
  6. All environment variables and flags
  7. Local mode: making it fast enough
  8. What happened when we wired it to a self-hosted server
  9. Troubleshooting
  10. Privacy by mode
  11. Related: Agent Skills and the LangChain loader
  12. Questions

Fastest working setup. Run pip install -U paddleocr-mcp (Python 3.10+). Get an access token from AI Studio. Paste the "AI Studio" config below into claude_desktop_config.json and restart Claude. Images then go to Baidu's hosted API. For fully offline OCR, install "paddleocr-mcp[local-cpu]" instead and set PADDLEOCR_MCP_PPOCR_SOURCE to local.12

Package
paddleocr-mcp
Command: paddleocr_mcp
Latest version
0.8.5
PyPI, June 11, 2026
Python
3.10+
Built on FastMCP v2
Default model
PP-OCRv6
One model per server

Pick an inference mode first#

The MCP server is a thin adapter. It always runs on your machine, but the OCR itself runs wherever PADDLEOCR_MCP_PPOCR_SOURCE points. That choice decides what you install, what you pay and where your files go.1

Mode (PPOCR_SOURCE)Runs onNeedsModelsYour files go to
local (default)Your machine[local] extra + an engine, or [local-cpu]All 7Nowhere
aistudio ("Official API")Baidu AI StudioAI Studio access tokenAll 7Baidu's servers
qianfanBaidu AI Cloud QianfanQianfan API keyPP-StructureV3, PaddleOCR-VL onlyBaidu AI Cloud
self_hostedYour PaddleOCR serverA running basic serving instanceWhatever you serveYour server

The docs recommend local for "offline use and scenarios with strict data privacy requirements". They recommend the Official API for "quickly trying out features". Self-hosted gives you "serving advantages and high flexibility", but "only the basic serving solution is supported", not Triton-based high-stability serving.1

The three tools#

Each server process runs one model and exposes one tool. The tool depends on the model. To give Claude plain OCR and document parsing, register two servers under different names.13

PADDLEOCR_MCP_MODELTool nameWhat the model gets back
PP-OCRv5, PP-OCRv5-latin, PP-OCRv6ocrRecognized text lines from images and PDFs
PP-StructureV3pp_structurev3Markdown with titles, paragraphs, tables, images
PaddleOCR-VL, -1.5, -1.6paddleocr_vlMarkdown from the vision-language parser

Every tool takes the same arguments. This is the schema our client received from 0.8.5:34

ArgumentDefaultMeaning
input_data required—Absolute file path readable by the MCP server (~ expanded), HTTP(S) URL, raw Base64, or data URL. Relative paths are rejected.
output_mode"simple"simple = plain text; detailed = JSON
file_typenullimage or pdf, for HTTP backends that can't infer it
return_imagestrueInclude images in document-parsing output
runtime_paramsnullPipeline options, e.g. text_det_box_thresh, text_rec_score_thresh, use_doc_unwarping

In simple mode the ocr tool returns the text followed by a summary line. On our receipt it ended with Confidence: 99.3% | 27 text lines.4

Install#

pip install -U paddleocr-mcp
# Install the CPU PaddlePaddle framework in addition to local:
pip install "paddleocr-mcp[local-cpu]"
# Install document-parsing dependencies for local inference (inference engine not included):
pip install "paddleocr-mcp[local]"
git clone https://github.com/PaddlePaddle/PaddleOCR.git
pip install -e mcp_server

Check it with paddleocr_mcp --help. The base package already depends on paddleocr>=3.7.0, so the three API modes need nothing else. In our fresh venv the API-mode install took 73 seconds. [local] adds paddleocr[doc-parser]. [local-cpu] also adds paddlepaddle>=3.2.1. The docs "strongly" recommend a separate virtual environment.124

For a GPU, use [local] and install paddlepaddle-gpu yourself, as on our install page. The local-cpu pin allows the PyPI 3.3.x builds. We saw those crash PaddleOCR 3.7.0 CPU inference in our tests, so if local OCR fails with ConvertPirAttribute2RuntimeAttribute, see troubleshooting.

Claude Desktop configuration#

Open claude_desktop_config.json, add one of the blocks below, and restart Claude Desktop:1

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

The configs are verbatim from the official docs. Their examples use PP-OCRv5; change it to PP-OCRv6 (the server default) or to any model in the table above.1

{
  "mcpServers": {
    "paddleocr": {
      "command": "paddleocr_mcp",
      "args": [],
      "env": {
        "PADDLEOCR_MCP_MODEL": "PP-OCRv5",
        "PADDLEOCR_MCP_PPOCR_SOURCE": "aistudio",
        "PADDLEOCR_MCP_AISTUDIO_ACCESS_TOKEN": "<your-access-token>"
      }
    }
  }
}
{
  "mcpServers": {
    "paddleocr": {
      "command": "paddleocr_mcp",
      "args": [],
      "env": {
        "PADDLEOCR_MCP_MODEL": "PP-OCRv5",
        "PADDLEOCR_MCP_PPOCR_SOURCE": "local"
      }
    }
  }
}
{
  "mcpServers": {
    "paddleocr": {
      "command": "paddleocr_mcp",
      "args": [],
      "env": {
        "PADDLEOCR_MCP_MODEL": "PaddleOCR-VL",
        "PADDLEOCR_MCP_PPOCR_SOURCE": "qianfan",
        "PADDLEOCR_MCP_QIANFAN_API_KEY": "<your-api-key>"
      }
    }
  }
}
{
  "mcpServers": {
    "paddleocr": {
      "command": "paddleocr_mcp",
      "args": [],
      "env": {
        "PADDLEOCR_MCP_MODEL": "PP-OCRv5",
        "PADDLEOCR_MCP_PPOCR_SOURCE": "self_hosted",
        "PADDLEOCR_MCP_SELF_HOSTED_BASE_URL": "<your-server-url>"
      }
    }
  }
}
  • Self-hosted URL: give the base URL only, e.g. http://127.0.0.1:8080, "without path suffixes such as /ocr or /layout-parsing". The MCP server adds the right suffix for the pipeline.1
  • Command not found? If paddleocr_mcp isn't on the PATH Claude Desktop sees (common with virtualenvs), set command to the absolute path, e.g. /home/you/.venvs/ocr/bin/paddleocr_mcp.1
  • Debug output: add "args": ["--verbose"].1

Without installing: uvx#

With uv installed, uvx fetches and runs the package on demand. The env vars work the same way. This is the official local-CPU example:1

jsonclaude_desktop_config.json
{
  "mcpServers": {
   "paddleocr": {
    "command": "uvx",
    "args": [
      "--from",
      "paddleocr-mcp[local-cpu]",
      "paddleocr_mcp"
    ],
    "env": {
      "PADDLEOCR_MCP_MODEL": "PP-OCRv5",
      "PADDLEOCR_MCP_PPOCR_SOURCE": "local"
    }
   }
  }
}

For the API modes, use "paddleocr-mcp" without the extra.1

Claude Code, Cursor and other MCP hosts#

The official doc covers Claude Desktop and says the steps "are also applicable to other MCP hosts with minor adjustments". Any host that accepts the standard mcpServers JSON (command, args, env) can take the blocks above as they are.1 For Claude Code, the CLI adds a stdio server with -e for each variable. The commands below are derived by us from claude mcp add --help:5

bash
# stdio: Claude Code starts paddleocr_mcp itself
claude mcp add paddleocr \
  -e PADDLEOCR_MCP_MODEL=PP-OCRv6 \
  -e PADDLEOCR_MCP_PPOCR_SOURCE=aistudio \
  -e PADDLEOCR_MCP_AISTUDIO_ACCESS_TOKEN=your-token \
  -- paddleocr_mcp

# or run one shared server over Streamable HTTP and point clients at it
paddleocr_mcp --model PP-OCRv6 --ppocr_source local --http   # listens on 127.0.0.1:8000
claude mcp add --transport http paddleocr http://127.0.0.1:8000/mcp

We checked the HTTP endpoint. paddleocr_mcp --http answered an MCP initialize request on http://127.0.0.1:8000/mcp and identified itself as "PaddleOCR PP-OCRv6 MCP server". --host and --port are only accepted together with --http. Without it the server exits with "Host and port arguments are only valid when using HTTP transport".34

The official demos also show the server in VS Code alongside the filesystem MCP server, and in Claude Desktop with the Notion MCP server.1

All environment variables and flags#

Every setting can be an environment variable (for the host config) or a CLI flag (for the command line). Note the mix of dashes and underscores in the flag names. Copy them exactly.1

Environment variableCLI flagDefaultUsed for
PADDLEOCR_MCP_MODEL--modelPP-OCRv6Model, and therefore the tool
PADDLEOCR_MCP_PPOCR_SOURCE--ppocr_sourcelocallocal / aistudio / qianfan / self_hosted
PADDLEOCR_MCP_AISTUDIO_ACCESS_TOKEN--aistudio_access_token—Required for aistudio
PADDLEOCR_MCP_AISTUDIO_BASE_URL--aistudio-base-url—Optional custom AI Studio endpoint
PADDLEOCR_MCP_AISTUDIO_REQUEST_TIMEOUT--aistudio-request-timeout120 sPer HTTP request to AI Studio
PADDLEOCR_MCP_AISTUDIO_POLL_TIMEOUT--aistudio-poll-timeout600 sTotal wait for an AI Studio job
PADDLEOCR_MCP_QIANFAN_API_KEY--qianfan_api_key—Required for qianfan
PADDLEOCR_MCP_QIANFAN_BASE_URL--qianfan-base-urlhttps://qianfan.baidubce.com/v2/ocrQianfan endpoint
PADDLEOCR_MCP_SELF_HOSTED_BASE_URL--self-hosted-base-url—Required for self_hosted
PADDLEOCR_MCP_HTTP_TIMEOUT--http-timeout600 sRead timeout for qianfan / self_hosted
PADDLEOCR_MCP_DEVICE--device—local only, e.g. gpu:0
PADDLEOCR_MCP_PIPELINE_CONFIG--pipeline_config—local only; absolute path to an exported pipeline YAML
—--httpoffStreamable HTTP instead of stdio
—--host / --port127.0.0.1 / 8000HTTP mode only
—--verboseoffVerbose logging

Official command-line examples:1

bash
# PP-OCRv5 + Official API + stdio
PADDLEOCR_MCP_AISTUDIO_ACCESS_TOKEN=xxxxxx paddleocr_mcp --model PP-OCRv5 --ppocr_source aistudio

# PP-StructureV3 + Local Inference + stdio
paddleocr_mcp --model PP-StructureV3 --ppocr_source local

# OCR + Self-hosted API + Streamable HTTP
paddleocr_mcp --model PP-OCRv5 --ppocr_source self_hosted --self-hosted-base-url http://127.0.0.1:8080 --http

Local mode: making it fast enough#

Local mode loads a full PaddleOCR pipeline inside the MCP process. Plain OCR is fine on a CPU: PP-OCRv6 tiers run in 0.3–2.9 s per page in our benchmark. Document parsing is heavier. The docs suggest exporting a slimmer pipeline config and pointing PADDLEOCR_MCP_PIPELINE_CONFIG at it. This is their example for PP-StructureV3:1

pythonexport_config.py
from paddleocr import PPStructureV3

pipeline = PPStructureV3(
    use_doc_orientation_classify=False, # Disable document image orientation classification
    use_doc_unwarping=False,            # Disable text image unwarping
    use_textline_orientation=False,     # Disable text line orientation classification
    use_formula_recognition=False,      # Disable formula recognition
    use_seal_recognition=False,         # Disable seal text recognition
    use_table_recognition=False,        # Disable table recognition
    use_chart_recognition=False,        # Disable chart parsing
    # Use lightweight models
    text_detection_model_name="PP-OCRv5_mobile_det",
    text_recognition_model_name="PP-OCRv5_mobile_rec",
    layout_detection_model_name="PP-DocLayout-S",
)

# The configuration file is saved to `PP-StructureV3.yaml`
pipeline.export_paddlex_config_to_yaml("PP-StructureV3.yaml")

For the PaddleOCR-VL models the docs are blunt: "CPU inference is not recommended." Use a GPU, or switch to self_hosted or an API mode for those.1

What happened when we wired it to a self-hosted server#

We installed 0.8.5 in a clean venv. We pointed it at PaddleX basic serving running PP-OCRv6 small in Docker (setup in our serving guide) and called the ocr tool over stdio with an MCP client.4

1 · HostClaude / MCP clientCalls ocr with an absolute path.
2 · stdiopaddleocr_mcpReads the file and Base64-encodes it.
3 · HTTPPOST /ocrYour PaddleX server runs PP-OCRv6.
4 · ResultText to the modelLines + "Confidence: 99.3% | 27 text lines".
  • First call failed. Passing only input_data (an absolute .jpg path), the client got just Error calling tool 'ocr'. With --verbose, the server log showed HTTP 422 (self_hosted/ocr). The MCP server had sent the image as Base64 without a file type, and PaddleX rejects that with "File type cannot be determined". This is the same 422 we hit calling the server directly.
  • Adding "file_type": "image" fixed it. All 27 lines came back. Hosts normally let the model fill in arguments, and the tool description does tell it to set file_type for HTTP backends. If you see failures, tell the assistant to "use file_type image" (or pdf).
  • Error details are hidden from the host. The server is created with mask_error_details=True, so a relative path, a bad token or a 422 all look the same to the client. Run with "args": ["--verbose"] and read the server's stderr log.3

Troubleshooting#

SymptomCause and fix
Server doesn't appear in Claudepaddleocr_mcp isn't on the host's PATH. Use the absolute path in command, then fully restart the host.
Error: The AI Studio access token is required.Set PADDLEOCR_MCP_AISTUDIO_ACCESS_TOKEN. Note this is not the same name as the SDKs' PADDLEOCR_ACCESS_TOKEN.
Error: Model 'PP-OCRv6' is not supported with qianfan source.Qianfan only offers PP-StructureV3 and PaddleOCR-VL.
Error: The self-hosted service base URL is required.Set PADDLEOCR_MCP_SELF_HOSTED_BASE_URL (base URL, no /ocr).
Relative paths are not supported (in the log)Use an absolute path. It must exist on the machine running the MCP server, not on the self-hosted backend.
Error calling tool in self-hosted modeUsually the 422 above: pass file_type. Check with --verbose.
Local mode is slow or runs out of memoryUse a lighter model or an exported, slimmed PADDLEOCR_MCP_PIPELINE_CONFIG. Avoid PaddleOCR-VL on CPU.
Huge token usage with PP-StructureV3 / VLResults can include images. Set return_images to false, or tell the model you don't need image content.
A complex URL fails in local modeA documented limitation. Download the file and pass an absolute path.

The docs also list "cannot process PDF document inputs that are Base64 encoded" as a local-mode limitation. The 0.8.5 source now writes Base64 PDFs to a temporary file in local mode, so this may be outdated. We didn't test it. Passing a path is the safe choice.13

Privacy by mode#

  • local: files never leave the machine. Model weights download once (from Hugging Face by default) and are cached in ~/.paddlex.
  • self_hosted: files go only to the server you name. With http:// on a network, they travel unencrypted, so use HTTPS or keep it on localhost.
  • aistudio / qianfan: files are uploaded to Baidu's services and counted against your quota (3,000 pages per model per day on AI Studio).8 Don't use these for documents you can't share with a third party.
  • In every mode, the OCR text is sent to your LLM provider as a tool result, because that's the point. Local OCR keeps the image private, but not the words in it.

PaddleOCR Agent Skills#

Two official skills, paddleocr-text-recognition and paddleocr-doc-parsing, for Skills-capable apps such as Claude Code. Both call the hosted API through the paddleocr api CLI. They need Python 3.9+, paddleocr>=3.7.0 and PADDLEOCR_ACCESS_TOKEN.6

bash
npx skills add PaddlePaddle/PaddleOCR -g --skill paddleocr-text-recognition -y
npx skills add PaddlePaddle/PaddleOCR -g --skill paddleocr-doc-parsing -y

For Claude Code, the docs put the token in .claude/settings.local.json:

json.claude/settings.local.json
{
  "env": {
    "PADDLEOCR_ACCESS_TOKEN": "<ACCESS_TOKEN>"
  }
}

The npm package paddleocr-skills is not referenced by the official docs.

LangChain: langchain-paddleocr#

PaddleOCRVLLoader loads PDFs and images as LangChain Documents using the PaddleOCR-VL models on the hosted API. It is version 0.2.2 and needs Python 3.10+.7

pythonloader.py
from langchain_paddleocr import PaddleOCRVLLoader
from pydantic import SecretStr

loader = PaddleOCRVLLoader(
    file_path="path/to/document.pdf",
    base_url="your-api-endpoint",
    model="PaddleOCR-VL-1.5",
    access_token=SecretStr("your-access-token")  # Optional if using environment variable `PADDLEOCR_ACCESS_TOKEN`
)

docs = loader.load()

The default base_url in the source is https://paddleocr.aistudio-app.com.

Want to OCR without any agent? See the serving & API guide, the Python quick start, or try PP-OCRv6 in our browser tool.

Questions#

Does Claude need the PaddleOCR MCP server to read images?

No. Claude can read images on its own. The MCP server is useful when you want PaddleOCR's output specifically: exact line-level text from long or dense documents, multi-page PDFs, table and layout parsing to Markdown via PP-StructureV3 or PaddleOCR-VL, or OCR that runs locally.

Is paddleocr-mcp free?

The package is free and its source files are Apache-2.0 (its PyPI metadata has no license field). Local and self-hosted modes cost only your hardware. The AI Studio mode uses the hosted API's free daily quota. Qianfan is a Baidu AI Cloud service with its own terms.

Which mode keeps my documents private?

local and self_hosted. In aistudio and qianfan, files are uploaded to Baidu. In every mode, the extracted text goes to whichever LLM you're using.

Can one server provide both OCR and document parsing?

No. Each instance runs one model and exposes one tool. Register two entries, for example paddleocr with PP-OCRv6 and paddleocr-docs with PP-StructureV3.

Why does the MCP server ignore my PADDLEOCR_ACCESS_TOKEN?

The MCP server reads a different variable for the same AI Studio token: PADDLEOCR_MCP_AISTUDIO_ACCESS_TOKEN. The SDKs, CLI, skills and LangChain loader read PADDLEOCR_ACCESS_TOKEN. Set the MCP one in the server's env block.

Does it work with Cursor, VS Code or other MCP clients?

The docs say the Claude Desktop steps apply to other MCP hosts "with minor adjustments", and they show a VS Code demo. Any host that launches stdio servers from a command plus env vars, or connects to Streamable HTTP at /mcp, can use it.

Why does the tool reject my file path?

Paths must be absolute and must exist on the machine running the MCP server. Relative paths are rejected by design. URLs, raw Base64 and data URLs are accepted too.

Sources

  1. Official MCP server documentation: docs/version3.x/integrations/mcp_server.en.md (models and tools 16–20, modes 22–26, install 95–117, Claude Desktop 123–186, local inference 191–261, Qianfan 269–298, self-hosted 300–328, uvx 330–382, CLI 384–408, parameter table 416–433, known limitations 435–439).
  2. PyPI paddleocr-mcp: version 0.8.5 uploaded 2026-06-11, requires_python >=3.10, extras local and local-cpu, no license field in the metadata (source files carry Apache-2.0 headers). Checked 2026-10-27.
  3. paddleocr-mcp source in the PaddleOCR repo, mcp_server/paddleocr_mcp/: selection.py (default model, model→tool map, Qianfan restriction), tasks/base.py:60-106 (tool parameters, error masking), inference/shared/input_contract.py:33-37 (accepted inputs), __main__.py (validation messages, FastMCP streamable HTTP).
  4. Our test, 2026-10-28: pip install -U paddleocr-mcp (0.8.5) into a fresh Python 3.13 venv, run over stdio with a FastMCP client in self_hosted mode against PaddleX basic serving (PP-OCRv6 small, CPU) in Docker. See our serving guide for the server setup.
  5. Claude Code CLI 2.1.312, output of claude mcp add --help (checked 2026-10-28).
  6. Official Agent Skills documentation: docs/version3.x/integrations/skills.en.md; skill files under skills/.
  7. langchain-paddleocr: README and source; PyPI 0.2.2 (2026-06-11), requires_python >=3.10.
  8. AI Studio access token page: aistudio.baidu.com/account/accessToken. Hosted-API quota (3,000 pages per model per day): AI Studio quota doc, read 2026-10-27.
Updated October 27, 2026·How we verify facts