dual-extract-mcp
Uses Ollama to run a local Qwen3-VL vision model for visual extraction of PDF fields, tables, and formulas, enabling fully offline AI-powered document understanding.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dual-extract-mcpExtract all fields from the PDF at C:\docs\sample.pdf"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
双路抽取 MCP Server(dual-extract-mcp)
把「MinerU 文本/版面路 + Qwen3-VL 视觉路 + 双路融合裁决」封装成 MCP 工具集(8 个 Tool), 让 Claude Desktop / Cursor 等 MCP 客户端通过 stdio 调用,对本地 PDF 做结构化文档理解 (字段抽取 / 表格 / 公式 / 探查 / 校验)。完全本地、离线、零外部 API。 V2.0 起升级为形态 2「三源两段」:MinerU 结构主路 + OvisOCR2 按需校验 → 文本路内部融合 → 现有 Fusion Engine 二元契约零改动。
状态:v2.0.1(2026-08-10):形态 2「三源两段」——MinerU 结构主路 + OvisOCR2 按需校验 → 文本路内部融合 → 现有 Fusion Engine 二元契约零改动;OvisOCR2 服务端
POST /parse_page422 修复;D-2 真连实测 PASS(p213 95.71% 201/210、p8 95.45% 84/88,实质错值 0);674 回归全绿(+9 deselected)传输:stdio(本期不监听端口)
语言:Python 3.11+(受管 3.13.14 实测可用)
1. 功能一览(8 个 Tool)
Tool | 说明 | 里程碑 |
| 双路+融合主入口(字段抽取) | M3(T03) |
| 文本路单跑(V2.0 起可选 OvisOCR2 校验,触发规则引擎四信号按需调用) | M2(T02) |
| 视觉路单跑(PDF 或独立图片,v1.3 起支持 | M2(T02) |
| 表格(跨页 + 大表分层 + CSV/XLSX) | M4(T04) |
| 公式(LaTeX + PNG 渲染) | M5(T04) |
| 文档探查(页数/表格/图片/公式统计) | M6(T05) |
| 输出结构校验(schema/manifest) | M6(T05) |
| MinerU + Ollama + OvisOCR2 三服务探活(OvisOCR2 可选) | M1 |
完整输入/输出契约见
docs/api.md。
Related MCP server: mdify-mcp
2. 环境要求
Python 3.11+(Windows 优先,Linux 兼容)
本地已部署:
MinerU 服务
http://127.0.0.1:8000(/health返回{"status":"ok"})Ollama
http://127.0.0.1:11434(含qwen3-vl:30b视觉模型)OvisOCR2(可选,V2.0 文本路校验增强):独立进程
http://127.0.0.1:8010(scripts/ovisocr2_server.py+ 独立 venv;默认text_backend=mineru不加载/ 不调用,DUAL_EXTRACT_TEXT_BACKEND=mineru+ovisocr2显式开启)
OvisOCR2 部署(独立 venv,不进主项目 pyproject 依赖;命令以
scripts/ovisocr2_server.py模块 docstring 为权威,V2.0 真连实测验证):# 1. 建独立 venv(复用系统 CUDA 可选 --system-site-packages;用户本机标准命令) python -m venv .venv-ovisocr2 .\.venv-ovisocr2\Scripts\Activate.ps1 # 2. 安装依赖(版本对齐调研实测,与脚本 docstring 一致) pip install "transformers==5.14.1" "torch>=2.6.0,<3.0" ` "fastapi>=0.110.0" "uvicorn>=0.29.0" "pillow>=10.0.0" "modelscope>=1.15.0" # 3. 启动(默认 127.0.0.1:8010;与 MinerU :8000 / Ollama :11434 错开) # 不传 --model 时默认从 ModelScope 下载 ATH-MaaS/OvisOCR2 python scripts/ovisocr2_server.py # 本地模型快照加载(已下载过时用,免重复下载;快照含 model.safetensors) python scripts/ovisocr2_server.py --host 127.0.0.1 --port 8010 ` --model "C:/Users/Administrator/.cache/modelscope/models/ATH-MaaS--OvisOCR2/snapshots/master" # 4. 健康检查(常驻显存 ~1.6GB;模型加载一次常驻,与 Qwen3-VL 串行不并发) curl http://127.0.0.1:8010/health # → {"status":"ok","model":...,"gpu_mem_mb":1626}⚠️ transformers 5.x 坑位(脚本 docstring 权威,服务端已封装,用户无需传参): 显式
eos_token_id=[248046, 248044]防死循环;temperature参数在 Qwen3_5 架构 无效必须省略;do_sample=False;images_kwargs={"min_pixels":448*448,"max_pixels":2880*2880};enable_thinking=False。
⚠️ 沙箱提示:本沙箱内
python -m venv会静默失败,须用受管 Python 建 venv (C:\Users\Administrator\.workbuddy\binaries\python\versions\3.13.12\python.exe -m venv .venv)。 用户本机无此坑,按下方标准命令即可。
3. 安装
# 1. 建 venv(受管 Python 3.13.14;用户本机可直接 python -m venv .venv)
C:\Users\Administrator\.workbuddy\binaries\python\versions\3.13.12\python.exe -m venv .venv
# 2. 激活 + 安装(含测试依赖)
.\.venv\Scripts\Activate.ps1
pip install -e ".[test]"
# 3. 复制配置模板并按需修改(可选;不配则用默认值)
Copy-Item .env.example .env4. 运行
# 开发期直跑(stdio 交互;起几秒确认无报错即可 Ctrl+C)
python -m dual_extract.server
# 或等价的 console script
mcp-server接入 Claude Desktop(claude_desktop_config.json)
{
"mcpServers": {
"dual-extract": {
"command": "D:/Dual-Extract-MCP/.venv/Scripts/python.exe",
"args": ["D:/Dual-Extract-MCP/src/dual_extract/server.py"]
}
}
}接入 Cursor
~/.cursor/mcp.json:
{
"mcpServers": {
"dual-extract": {
"command": "D:/Dual-Extract-MCP/.venv/Scripts/python.exe",
"args": ["D:/Dual-Extract-MCP/src/dual_extract/server.py"]
}
}
}B1:MCP 客户端 CWD 不可控,建议在
.env中把DUAL_EXTRACT_OUTPUT_DIR配成绝对路径。
5. 测试
# 单元测试(默认跳过 smoke)
pytest -q
# 冒烟:真连本机 MinerU/Ollama(需服务在线)
pytest -m smoke -q当前回归:674 passed + 9 deselected(2026-08-10 v2.0.1 全量回归核实,含新增 OvisOCR2 相关测试)。 历史演进:v0.2.1 353 passed → V1.0 406 passed → V1.3.0 615 passed → V2.0.1 674 passed。
5.1 V1.0 增量说明(2026-08-03)
V1.0 在 v0.2.1 基础上新增 5 项可选/默认关能力(全部 additive,当时 schema_version 为 "1.0";当前统一 "1.1",validate_output 兼容 1.0/1.1 白名单双值,旧客户端零改动):
增量 | 落点 | 说明 |
|
| 生成环境信息: |
|
| 产物唯一身份: |
|
| 字段审计 ID: |
| 抽取类 Tool job 结束自动落盘( | 质量报告:17 顶层键, |
|
| 单元格溯源五字段 |
挂接约定(artifact_manifest,V1.0 P2):产物唯一身份由
artifact_id+manifest.json的 SHA256 + 相对路径 三元组确定——artifact_id标识「哪次抽取」,SHA256 保证「内容未被篡改」,相对路径定位「文件在哪」。详见docs/最终输出说明.md§4 /docs/api.md§2.4。
6. 配置项(全部前缀 DUAL_EXTRACT_,仅 config.py 读取)
键 | 默认值 | 说明 |
|
| MinerU HTTP 端点 |
|
| MinerU 请求超时(秒) |
|
| Ollama 端点 |
|
| 视觉模型 |
|
| Ollama 超时(秒;冷启动模型加载可达) |
|
| 视觉路 thinking 开关(G2,默认关) |
|
| 文本路后端: |
|
| OvisOCR2 独立进程 HTTP 端点(V2.0) |
|
| OvisOCR2 模型(ModelScope 仓库 id,V2.0) |
|
| OvisOCR2 整页超时红线(秒;实测 96s × ~1.9 余量) |
|
| OvisOCR2 单表超时(秒;拆表兜底 P2 预留) |
|
| 表格低置信触发阈值(confidence < 此值 → 触发 OvisOCR2 校验) |
|
| 截断兜底比例(token_count ≥ 上限 × 此值 → 判截断降级用 MinerU) |
|
| 服务端生成上限(< 16384 官方上限,防死循环) |
|
| 输出根目录(建议绝对路径) |
|
| true 时输出加时间戳子目录 |
|
| 低置信阈值 |
|
| 页并行(默认串行防 3090 OOM) |
|
| 输入 PDF 大小上限 |
|
| 页数上限 |
|
| 页图/图片 DPI |
|
| 图表/印章裁剪开关 |
|
| 单路降级开关 |
|
| 表格单元格溯源(V1.0;开启后 |
|
| 模型裁判(默认关,v0.4 前不实现) |
|
| 日志级别 |
|
| 临时目录(退出清理) |
|
| CSV 分片行数 |
7. 真实样例用法
# 1. 探查:先「ls」一份 PDF 再决定抽取策略
# inspect_document 返回 {pages, tables, images, formulas, text_chars}
# 样例:232 页财报 → 421 图 / 213,232 字符(MinerU 不可达时自动降级 PyMuPDF)
# 2. 双路字段抽取
# dual_extract(pdf_path="D:/samples/中芯国际_年报.pdf",
# fields=["公司代码","公司简称","法定代表人","报告期","资产总计"],
# field_types={"资产总计":"money","报告期":"date"})
# 3. 表格(跨页 + 大表分层 + CSV/XLSX)
# extract_table(pdf_path="D:/samples/中芯国际_年报.pdf", pages=[10,11],
# format=["json","csv"], cross_page=true)
# 4. 公式
# extract_formulas(pdf_path="D:/samples/中芯国际_年报.pdf", pages=[20],
# render=true, tex=false)
# 5. 校验结果
# validate_output(output_dir="D:/Dual-Extract-MCP/outputs/中芯_年报")
# → {"schema_version": "1.1", "ok": true, "errors": [], "manifest_ok": true}
# (产物目录含 extraction.json + manifest.json;manifest 记录各产物 SHA256,
# validate_output 会与磁盘实文件比对,防产物漂移/被篡改)
# 6. 独立图片字段抽取(v1.3+,截图/扫描件/名单/表格照片,无需先包 PDF)
# vision_extract(image_path="D:/samples/名单.png",
# fields=["公司代码","公司简称","注册资本"])
# → document.source_image 填充 / source_pdf 空串 / 字段 page:0
# 7. OvisOCR2 文本路校验增强(v2.0+,形态 2「三源两段」)
# DUAL_EXTRACT_TEXT_BACKEND=mineru+ovisocr2 python -m dual_extract.server
# dual_extract(pdf_path="D:/samples/中芯国际_年报.pdf",
# fields=["公司代码","短期借款"],
# verify_pages=[1,2]) # 调用级指定校验页(信号②)
# → meta.generation.text_extractors=["mineru","ovisocr2"];
# warnings 含 ovisocr2_crosscheck:p1:rate=1.0 等校验信号;
# 默认 text_backend=mineru 不加载/不调用(零回归)8. 项目结构(四层架构,依赖单向向下)
MCP Layer server.py → mcp/{tools,handlers,converters}.py
↓
Service Layer services/*.py(extract/parse/vision/table/formula/inspect/validate/health)
↓
Pipeline Layer pipelines/*.py + fusion/*.py
↓
Adapter Layer adapters/base.py(接口缝)+ mineru/ollama/storage/ovisocr2 实现与外部服务唯一耦合点 = 四个 Adapter 的 Protocol 接口(
MinerUAdapter/OllamaAdapter/StorageAdapter/OvisOCR2Adapter)。铁律:不建注册表、不预写第二后端(Docling/云模型/对象存储 v0.4+ 再说)。
9. 常见问题(FAQ)
9.1 VPN 代理导致 localhost 请求 502 / 超时(trust_env 陷阱)
Windows 上挂极光 VPN(端口 29290)时,Python httpx 默认 trust_env=True 会读取系统
注册表代理,把 http://127.0.0.1:8000 的 localhost 请求也走代理 → 502。
本项目所有 Adapter 的 httpx.AsyncClient 一律 trust_env=False,无需手动处理。
若在自定义脚本里直接调 httpx,请同样加 trust_env=False。
9.2 Ollama 冷启动 600s 超时
qwen3-vl:30b(30B 模型)首次加载进显存可能耗时 1-5 分钟,第一请求容易超时。
本项目 DUAL_EXTRACT_OLLAMA_TIMEOUT 默认 600 秒,足够冷启动;
若你的显存/磁盘更慢,可调大该值。探活(health)用固定 8s 短超时,不受此影响。
9.3 3090 24G 显存:默认串行防 OOM
qwen3-vl:30b 在 3090 24G 下并行多页易 OOM。默认 DUAL_EXTRACT_PARALLEL=false(串行),
页图渲染也是串行(F1)。若显存充裕可开并行,但建议先压测单页显存占用。
9.4 MinerU 不可达时怎么办
dual_extract/vision_extract/parse_text:自动降级(视觉路单跑或纯文本), 输出warnings标degraded,不整体失败;inspect_document:自动降级为纯 PyMuPDF 本地统计(页数/图片/文本字符),degraded=true+warnings标注。
9.5 输出目录找不到产物
MCP 客户端 CWD 不可控,务必在 .env 把 DUAL_EXTRACT_OUTPUT_DIR 配成绝对路径
(如 D:/Dual-Extract-MCP/outputs)。产物按 pdf_stem 分目录:
{输出根}/{pdf文件名}/extraction.json + manifest.json。
10. Roadmap
v0.2-alpha gate(T01-T03 = M1-M3):骨架 + 单路 + 双路融合闭环 ✅
T04(M4-M5):表格 + 公式 ✅
T05(M6-M7):inspect/validate + 安全加固 + 降级完善 + 文档 ✅
v0.2.0(2026-08-03 转正):G4 gate 真连验收 PASS(8 Tool 真连全通 + 3 P1 修复闭环 + 349 回归全绿)✅
v0.2.1(2026-08-03 发版):BUG-4 MinerUAdapter 子区间页号偏移修复(
parse(pages=[7])时产物 page_idx 从 0 重编号,blocks 全标 page=1;应按 pages[0] 偏移)——commitbec69aa,353 回归全绿(4 个 BUG-4 专项回归)✅V1.0(2026-08-03 增量):
meta.generation/artifact_id/fields[].field_id/quality_report.json自动产出 /tables[].cell_provenance(默认关)——5 项 additive 增量,406 回归全绿,QA 独立验证 PASS ✅V1.2.0(2026-08-04):对齐《程序输出规范 v1.1》六项增量(source/pipeline/models 镜像、0.95 封顶、字段级 source、schema 1.1、cleaning_report、manifest 收敛)——582 回归全绿 ✅
V1.2.1(2026-08-04):MinerU 适配器降级/异常双 bug 修复(HTTP 相对路径 500 + CLI -p 误传)——586 回归全绿 ✅
V1.2.2(2026-08-05):health asyncio 嵌套修复 + BUG-5/6/7 表格取值修复——608 回归全绿 ✅
V1.3.0(2026-08-09):vision_extract 新增 image_path 独立图片输入——615 回归全绿 ✅
V2.0.0(2026-08-09):OvisOCR2 文本路校验增强接入(形态 2「三源两段」)——MinerU 结构主路 + OvisOCR2 按需校验 → 文本路内部融合 → 现有 Fusion Engine 二元契约零改动;纯 additive,
schema_version保持"1.1",默认text_backend=mineru零加载/零调用——674 回归全绿 ✅V2.0.1(2026-08-10):OvisOCR2 服务端
POST /parse_page422 修复(根因:ParsePageRequest/ParsePageResponse原是create_app()内部局部类,FastAPI 局部 Pydantic model 请求体识别失败 → 提升为模块级)+ D-2 真连实测 PASS(p213 95.71% 201/210、p8 95.45% 84/88,均 ≥95% 达标,实质错值 0)+ D-8 文档同步——bugfix 无 API 变更,674 回归全绿 ✅调研完成:复杂表格页降载策略(docs/复杂表格页降载策略.md)+ OvisOCR2 vs MinerU 对比(docs/OvisOCR2_vs_MinerU_对比报告.md)+ 模型分类与升级路线(docs/模型分类与升级路线.md)
后续登记(保持 roadmap):
OvisOCR2 文本路 Adapter 立项(需先补 16k 截断兜底设计)→ ✅ 已完成(V2.0);VLM 线评估 Qwen3.6-35B-A3B(排在 OvisOCR2 之后);模型裁判(C3 默认关)→ v0.4 前不实现(保留原条目)多后端注册表(Docling/云模型/对象存储)→ 保持 roadmap
详细设计见 docs/技术方案设计_双路抽取MCP.md / docs/双路抽取MCP_架构设计.md /
docs/双路抽取MCP_PRD.md / docs/architecture.md / docs/api.md。
输出质量评估(三层框架 + 可执行脚本)见 docs/输出质量评估指南.md / tools/assess_output_quality.py。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceA local MCP server that extracts text-layer content from PDF files, enabling AI agents to inspect, extract text, outlines, and page content.
- Alicense-qualityDmaintenanceMCP server that gives LLMs the power to convert PDFs to Markdown on the fly using a local Ollama vision model.Apache 2.0
- AlicenseAqualityBmaintenanceA local-first MCP server that ingests PDFs, extracts structure, and provides semantic search and sequential navigation tools for AI clients to query and learn from documents.10MIT
- AlicenseAqualityCmaintenanceFast, local PDF parsing as an MCP server with text extraction, bounding boxes, OCR, and visual citations. No cloud or API key required.5MIT
Related MCP Connectors
Generate PDFs from templates via AI chat. Works with Claude, ChatGPT, Cursor, and any MCP client.
Turn any PDF into structured JSON via AI + OCR: invoices, bank statements, contracts.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/magicyuanh/Dual-Extract-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server