Skip to main content

MCP server exposing PaddleOCR remote jobs for PDF/image-to-Markdown conversion

Project description

PaddleOCR MCP Server

通过 PaddleOCR 官方 API 将 PDF 或图片转换为 Markdown。服务直接暴露 PaddleOCR 远端任务的提交、查询和保存三个阶段,不创建第二套本地后台任务。

设计概览

ocr_submit(file_path 或 file_url)
    ↓ 返回 PaddleOCR 远端 job_id
ocr_status(job_id)
    ↓ 调用方按需重复查询,直到 state=done
ocr_save(job_id, output_dir)
    ↓ 下载 JSONL、逐页 Markdown 和图片
full.md

PaddleOCR 的 job_id 是唯一任务状态源。MCP Server 不保存本地 job 表,因此进程 重启后仍可继续查询或保存已有远端任务。每个 MCP 调用都是一次短请求,不依赖 MCP Host 是否支持 progressToken

本 Server 只暴露 Tools,不提供 Resources 或 Prompts。

环境要求

  • Python >= 3.13
  • PaddleOCR AI Studio access token
  • 推荐使用 uv / uvx 运行

获取 token:https://aistudio.baidu.com/account/accessToken

Server 从环境变量读取 token:

PADDLEOCR_ACCESS_TOKEN

不要把 token 写入提示词、提交到 Git,或输出到 MCP 日志。

安装与 MCP Host 配置

推荐固定版本,避免未来破坏性升级影响现有 Host:

{
  "mcpServers": {
    "paddle-ocr": {
      "command": "uvx",
      "args": ["paddle-ocr-server==0.3.0"],
      "env": {
        "PADDLEOCR_ACCESS_TOKEN": "your-token"
      }
    }
  }
}

运行最新版本时可使用:

PADDLEOCR_ACCESS_TOKEN=your-token uvx paddle-ocr-server

本地开发配置:

{
  "mcpServers": {
    "paddle-ocr": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/servers/paddle-ocr",
        "run",
        "paddle-ocr-server"
      ],
      "env": {
        "PADDLEOCR_ACCESS_TOKEN": "your-token"
      }
    }
  }
}

Tool:ocr_submit

提交本地文件或远程 URL,立即返回 PaddleOCR 的远端任务 ID。本 Tool 不等待 OCR 完成。

参数

参数 类型 必需 默认值 说明
file_path string | null 二选一 null MCP Server 所在机器可读取的 PDF/图片路径
file_url string | null 二选一 null PaddleOCR 服务可访问的文件 URL
use_chart_recognition boolean true 是否启用图表识别
model string PaddleOCR-VL-1.6 PaddleOCR 模型名称

file_pathfile_url 必须且只能提供一个。本地路径是 Server 机器上的路径, 不是远程 MCP Host 或用户电脑上的任意路径。

当前固定关闭以下 PaddleOCR 可选处理:

useDocOrientationClassify = false
useDocUnwarping = false

返回值

{
  "job_id": "remote-paddle-job-id",
  "state": "submitted"
}

这里的 submitted 表示 MCP 已取得远端 job_id,不是 PaddleOCR 的实时任务状态。 后续状态以 ocr_status 为准。

Tool:ocr_status

查询一次 PaddleOCR 远端状态,不在 Server 内循环等待。推荐由 Agent 或 Host 每 5 秒左右调用一次;没有必要每秒高频查询。

参数

参数 类型 必需 说明
job_id string ocr_submit 返回的远端任务 ID

返回值

{
  "job_id": "remote-paddle-job-id",
  "state": "running",
  "extracted_pages": 92,
  "total_pages": 343,
  "start_time": "2026-07-10 10:26:57",
  "end_time": null,
  "result_url": null,
  "error": null
}
字段 类型 说明
job_id string 远端任务 ID
state string PaddleOCR 返回的原始状态;实测处理中为 running,完成为 done
extracted_pages number 已处理页数;远端尚未返回进度时为 0
total_pages number | null 总页数;任务刚提交时可能为 null
start_time string | null 远端 startTime 原值;不猜测或转换时区
end_time string | null 远端 endTime 原值;通常完成后才存在
result_url string | null 完成后的 JSONL 下载地址;处理中通常为 null
error string | null 远端错误信息

任务刚提交时,PaddleOCR 可能只返回 jobIdstate,暂时没有页数和时间字段; 这是正常状态,不应当视为解析失败。页数按远端批次更新,可能连续几次查询保持不变。

result_url 可能是临时签名地址,不要记录或分享完整 URL。通常无需直接使用它, 将 job_id 传给 ocr_save 即可。

Tool:ocr_save

重新查询远端状态,确认 state=done 后下载并保存结果。如果任务仍在处理中,本 Tool 会明确报错,不会在内部等待。

参数

参数 类型 必需 说明
job_id string 已完成的远端任务 ID
output_dir string MCP Server 所在机器上的输出目录

返回值

返回生成的 full.md 路径,例如:

/data/ocr/book/full.md

输出结构

output_dir/
├── full.md
├── pages/
│   ├── page_0.md
│   ├── page_1.md
│   └── ...
└── imgs/
    └── ...
  • pages/page_N.md:按所有 JSONL 批次中的 layoutParsingResults 连续编号
  • full.md:使用 \n\n---\n\n 连接全部页面
  • imgs/:Markdown 引用的远端图片

PaddleOCR 的 JSONL 一行可能包含多个页面,不能假设“一行等于一页”。Server 会 遍历所有 layoutParsingResults 后连续编号。

复用同一个 output_dir 时,Server 会覆盖本次页面并删除不再存在的 pages/page_数字.md,但不会删除其他人工文件。为避免保留不再引用的旧图片,生产 使用中仍推荐每个文档使用独立输出目录。

Markdown 后处理

保存前会进行以下轻量处理:

  • 去掉行内公式 $ ... $ 边界处的空格
  • 将块公式整理为独立的 $$
  • 将三个及以上连续换行压缩为两个

因此输出并非远端 Markdown 的逐字节原样副本。

推荐的 Agent 调用策略

1. 调用 ocr_submit,保存 job_id。
2. 等待约 5 秒。
3. 调用 ocr_status:
   - state=done:进入第 4 步;
   - state=failed/error:向用户报告 error;
   - 其他状态:报告 extracted_pages/total_pages,继续等待。
4. 调用 ocr_save。
5. 返回 full.md 路径,并按需要交给后续翻译或摘要工具。

不要在 Agent 内另造一套本地 job ID;直接持有 PaddleOCR 的 job_id 即可。

错误行为

  • 缺少 token:抛出环境变量未设置错误
  • file_pathfile_url 未提供或同时提供:拒绝提交
  • 本地路径不存在或不是普通文件:拒绝提交
  • job_id 为空:拒绝查询或保存
  • 远端任务未完成:ocr_save 返回当前状态和页数
  • 远端任务失败:返回 PaddleOCR 错误信息
  • 完成响应缺少 result_url:拒绝生成不完整结果
  • 图片路径试图逃逸 output_dir:拒绝写入

网络错误和 PaddleOCR HTTP 错误会直接传递给 MCP 调用方。目前不在 Server 内自动 重试提交请求,以避免创建重复远端任务。

从 0.2.x 升级

0.3.0 是破坏性升级:

  • 删除阻塞式 ocr_pdf
  • 新增 ocr_submitocr_statusocr_save
  • 不再使用 MCP progress notification
  • 轮询责任从 Server 移到 Agent/Host

旧调用方必须按新的三阶段流程调整。

本地开发

cd servers/paddle-ocr
uv sync
uv run pytest -v
uv run paddle-ocr-server

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paddle_ocr_server-0.3.0.tar.gz (62.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paddle_ocr_server-0.3.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file paddle_ocr_server-0.3.0.tar.gz.

File metadata

  • Download URL: paddle_ocr_server-0.3.0.tar.gz
  • Upload date:
  • Size: 62.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for paddle_ocr_server-0.3.0.tar.gz
Algorithm Hash digest
SHA256 99713e01c7bbf9bcb8a6c877ed873c8a23d4566e47be4adc62bd159a1eb08a65
MD5 910c802acf1691639af1220f5d0acf73
BLAKE2b-256 f1635ccfe902985a9c6ce0925e89ca1a13a2212e972be34989907396d2cccddd

See more details on using hashes here.

File details

Details for the file paddle_ocr_server-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for paddle_ocr_server-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 425448e8681690f4554a69e46775e4a65abc082674f5d3141d667311296d4c78
MD5 16724c4dd900fc2c92f5a194eb91bdac
BLAKE2b-256 eed81e354361dc99282d78519cb2c2f154c8e008c24882a07e3e8b8919d8bb54

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page