Skip to main content
Glama

双路抽取 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_page 422 修复;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

说明

里程碑

dual_extract

双路+融合主入口(字段抽取)

M3(T03)

parse_text

文本路单跑(V2.0 起可选 OvisOCR2 校验,触发规则引擎四信号按需调用)

M2(T02)

vision_extract

视觉路单跑(PDF 或独立图片,v1.3 起支持 image_path

M2(T02)

extract_table

表格(跨页 + 大表分层 + CSV/XLSX)

M4(T04)

extract_formulas

公式(LaTeX + PNG 渲染)

M5(T04)

inspect_document

文档探查(页数/表格/图片/公式统计)

M6(T05)

validate_output

输出结构校验(schema/manifest)

M6(T05)

health

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:8010scripts/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=Falseimages_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 .env

4. 运行

# 开发期直跑(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 白名单双值,旧客户端零改动):

增量

落点

说明

meta.generation

extraction.jsonmeta.generation

生成环境信息:{generator, version, mineru_version, vlm, vlm_backend}(PRD §5.1)

artifact_id

extraction.json 顶层 + document.artifact_id

产物唯一身份:{pdf_stem}_{YYYYMMDD}_{seq:03d}(同 run 幂等复用)

fields[].field_id

extraction.jsonfields[] / aggregated_pages[]

字段审计 ID:{artifact_id}.field.{key_snake}.p{page}.{seq:03d}

quality_report.json

抽取类 Tool job 结束自动落盘({产物目录}/quality_report.json

质量报告:17 顶层键,overall 自动三态判定(达标/有条件达标/不达标)

tables[].cell_provenance

extract_table 输出(默认关DUAL_EXTRACT_CELL_PROVENANCE=true 开启)

单元格溯源五字段 {row, col, value, page, bbox};chunked 大表 >500 行只记录前 500 行 + warning

挂接约定(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 读取)

默认值

说明

DUAL_EXTRACT_MINERU_BASE_URL

http://127.0.0.1:8000

MinerU HTTP 端点

DUAL_EXTRACT_MINERU_TIMEOUT

120

MinerU 请求超时(秒)

DUAL_EXTRACT_OLLAMA_BASE_URL

http://127.0.0.1:11434

Ollama 端点

DUAL_EXTRACT_OLLAMA_MODEL

qwen3-vl:30b

视觉模型

DUAL_EXTRACT_OLLAMA_TIMEOUT

600

Ollama 超时(秒;冷启动模型加载可达)

DUAL_EXTRACT_OLLAMA_THINK

false

视觉路 thinking 开关(G2,默认关)

DUAL_EXTRACT_TEXT_BACKEND

mineru

文本路后端:mineru | mineru+ovisocr2(V2.0;默认 mineru 零加载/零调用)

DUAL_EXTRACT_OVISOCR2_BASE_URL

http://127.0.0.1:8010

OvisOCR2 独立进程 HTTP 端点(V2.0)

DUAL_EXTRACT_OVISOCR2_MODEL

ATH-MaaS/OvisOCR2

OvisOCR2 模型(ModelScope 仓库 id,V2.0)

DUAL_EXTRACT_OVISOCR2_PAGE_TIMEOUT

180

OvisOCR2 整页超时红线(秒;实测 96s × ~1.9 余量)

DUAL_EXTRACT_OVISOCR2_TABLE_TIMEOUT

90

OvisOCR2 单表超时(秒;拆表兜底 P2 预留)

DUAL_EXTRACT_OVISOCR2_CONF_THRESHOLD

0.80

表格低置信触发阈值(confidence < 此值 → 触发 OvisOCR2 校验)

DUAL_EXTRACT_OVISOCR2_TRUNC_RATIO

0.90

截断兜底比例(token_count ≥ 上限 × 此值 → 判截断降级用 MinerU)

DUAL_EXTRACT_OVISOCR2_MAX_NEW_TOKENS

12288

服务端生成上限(< 16384 官方上限,防死循环)

DUAL_EXTRACT_OUTPUT_DIR

./outputs

输出根目录(建议绝对路径)

DUAL_EXTRACT_OUTPUT_VERSIONED

false

true 时输出加时间戳子目录

DUAL_EXTRACT_CONFIDENCE_THRESHOLD

0.7

低置信阈值

DUAL_EXTRACT_PARALLEL

false

页并行(默认串行防 3090 OOM)

DUAL_EXTRACT_MAX_FILE_MB

500

输入 PDF 大小上限

DUAL_EXTRACT_MAX_PAGES

1000

页数上限

DUAL_EXTRACT_IMAGE_DPI

200

页图/图片 DPI

DUAL_EXTRACT_CROP_FIGURES

false

图表/印章裁剪开关

DUAL_EXTRACT_SINGLE_PATH_DEGRADE

true

单路降级开关

DUAL_EXTRACT_CELL_PROVENANCE

false

表格单元格溯源(V1.0;开启后 tables[].cell_provenance 记录 row/col/value/page/bbox,chunked 大表自动降级)

DUAL_EXTRACT_MODEL_JUDGE

false

模型裁判(默认关,v0.4 前不实现)

DUAL_EXTRACT_LOG_LEVEL

INFO

日志级别

DUAL_EXTRACT_TEMP_DIR

./tmp

临时目录(退出清理)

DUAL_EXTRACT_CSV_SPLIT_ROWS

500

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+ 再说)。

  • 详见 docs/architecture.md


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:自动降级(视觉路单跑或纯文本), 输出 warningsdegraded,不整体失败;

  • inspect_document:自动降级为纯 PyMuPDF 本地统计(页数/图片/文本字符), degraded=true + warnings 标注。

9.5 输出目录找不到产物

MCP 客户端 CWD 不可控,务必在 .envDUAL_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] 偏移)——commit bec69aa,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_page 422 修复(根因: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

Available Tools

8 tools
dual_extractB

dual_extract tool:双路融合主入口(M3,T03)。

V2.0(additive):新增可选 verify_pages —— 调用级显式指定 OvisOCR2 校验页(信号②;未指定/未启用 → 触发规则自行判定,默认零调用)。

Args: pdf_path: PDF 路径(必填)。 fields: 字段键(str | list[str] | dict;必填,禁止空)。 pages: 页号(int | list[int] | None;1-based)。 model: 视觉模型名(可选,默认 Settings.ollama_model)。 think: 视觉路 thinking 开关(bool | None;None → Settings.ollama_think)。 field_types: {字段键: 字段类型}(可选;未指定按值形态推断)。 verify_pages: 页号(int | list[int] | None;1-based;OvisOCR2 校验页)。

Returns: 结构化 JSON 文本(ExtractionOutput)。

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNo
pagesNo
thinkNo
fieldsNo
pdf_pathYes
field_typesNo
verify_pagesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully reveals defaults (model, think, field_types inference) and the verify_pages fallback behavior ('默认零调用'). However, it does not disclose whether the operation is read-only, what the 'dual paths' actually are, or how errors or unsupported inputs are handled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized with a short intro, a version note, an Args list, and a Returns line. It is reasonably concise, though internal jargon such as '信号②', 'M3,T03', and '触发规则' adds noise without aiding an agent's decision-making.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no annotations, the description covers parameter semantics and output format well, and an output schema exists for return values. Yet key operational context is missing: what the two fusion paths are, what OvisOCR2 verification means in practice, and how this 'main entry' relates to the specialized sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Every parameter is given additional meaning not present in the schema: types, defaults, 1-based indexing, and requiredness. This compensates strongly for the 0% schema description coverage. The main flaw is that the description marks fields as mandatory while the input schema does not list it as required, creating ambiguity about invocation validity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description frames the tool as a dual-channel fusion main entry and, through the Args/Returns sections, conveys that it extracts structured JSON from PDFs using field keys and page selections. However, it never explicitly says 'extract fields from a PDF' and does not distinguish itself from siblings like vision_extract or extract_table.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use dual_extract versus vision_extract, parse_text, extract_table, or inspect_document. The only conditional language ('未指定/未启用 → 触发规则自行判定') concerns verify_pages defaults, not task-to-tool routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extract_formulasA

extract_formulas tool:公式抽取(LaTeX + PNG,M5,T04)。

Args: pdf_path: PDF 路径(必填)。 pages: 页号(int | list[int] | None;1-based)。 render: 是否渲染 PNG(bool,默认 true)。 tex: 是否落盘 formulas.tex(bool,默认 false)。 sympy: 是否做 SymPy 校验(bool,默认 false)。

Returns: 结构化 JSON 文本(formulas.json 汇总)。

ParametersJSON Schema
NameRequiredDescriptionDefault
texNo
pagesNo
sympyNo
renderNo
pdf_pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It does disclose the effects of render (PNG), tex (writes formulas.tex), sympy (validation), and the JSON return type. However, it does not state where rendered PNG files are written, whether files can be overwritten, or whether the operation is safe/non-destructive, leaving the behavioral picture incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well-structured with labeled Args and Returns sections, and each parameter is on a single scannable line. Some space is wasted on the redundant 'extract_formulas tool' header and the unexplained 'M5, T04' code, but overall it is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter extraction tool with no annotations, the description covers all input semantics and the return type, and an output schema is present so return details need not be expanded. It lacks usage routing and PNG file-destination details, but an agent has most of the information needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the Args section fully compensates: all five parameters receive a semantic explanation, type, default, and for pages a 1-based convention. This adds substantial meaning beyond the bare schema and leaves no parameter ambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the action '公式抽取' (formula extraction) and the output modes 'LaTeX + PNG', making the tool's function specific and distinct from siblings like extract_table and parse_text. It is not a mere tautology, though it never explicitly contrasts with a sibling and includes cryptic 'M5/T04' identifiers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to choose extract_formulas over siblings such as vision_extract, dual_extract, or parse_text, and no exclusions or prerequisites beyond requiring pdf_path. The intended use case is only implied by the tool name and the phrase 公式抽取, not explicitly stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extract_tableA

extract_table tool:表格抽取(跨页 + 大表分层,M4,T04)。

Args: pdf_path: PDF 路径(必填)。 pages: 页号(int | list[int] | None;1-based)。 cross_page: 是否跨页合并(bool,默认 true)。 format: 导出格式(str | list[str];json/csv/xlsx 多选;默认 "json")。 render: 是否渲染页图(bool,默认 true)。

Returns: 结构化 JSON 文本(tables.json 汇总)。

ParametersJSON Schema
NameRequiredDescriptionDefault
pagesNo
formatNojson
renderNo
pdf_pathYes
cross_pageNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden. It discloses cross-page merging, large-table layering, optional page-image rendering, and a structured JSON return. However, it leaves side effects ambiguous (e.g., whether csv/xlsx exports write files) and includes the unexplained 'M4,T04' tag.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The Args/Returns layout is scannable and every parameter line provides useful semantics. The 'M4,T04' tag is unexplained and adds minor noise, but the structure remains efficient and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

All parameters are documented, and an output schema exists, so the return-value shape is not a critical gap. The main missing context is explicit selection guidance relative to sibling tools and clarification of how non-JSON export formats are handled.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description fully compensates by adding types, defaults, requiredness, 1-based page numbering, accepted format values, and rendering meaning for all five parameters. This is essential detail that goes well beyond the sparse input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly names the operation as table extraction from a PDF and mentions cross-page merging and large-table layering, which adds useful specificity. It does not explicitly contrast the tool with siblings like parse_text or extract_formulas, but the intent is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use for PDF table extraction, especially across pages or with large tables, but it never states when to prefer this tool over alternatives such as vision_extract, dual_extract, or extract_formulas. There are no explicit when-not-to-use conditions or alternative recommendations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

healthA

health tool:MinerU + Ollama 双服务探活。

注意:其余 7 个工具均为 async handler;FastMCP 1.29 对同步 handler 会在 running loop 内直接同步调用,内部再 asyncio.run 会嵌套报错, 故此处统一为 async + await(health_service.check 仍保留同步兜底)。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral burden. It discloses that the tool probes two specific services and includes a note about async/sync implementation details. It does not explicitly state side-effect freedom or failure behavior, though an output schema exists and the operation is inherently read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is concise, but the long '注意' section about FastMCP 1.29 handler internals and asyncio.run nesting is irrelevant to an agent selecting or invoking the tool. This implementation detail should be removed or moved to developer documentation; it does not earn its place in the tool description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter health probe with an output schema, the essential information is present: what is being probed (MinerU + Ollama) and that it is a liveness check. The async note is extraneous but not harmful, and the missing failure semantics are likely covered by the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema confirms 100% coverage with no required properties. Per the rubric, zero parameters receive a baseline of 4; no additional parameter documentation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'MinerU + Ollama 双服务探活' (liveness probe for both MinerU and Ollama services), giving a specific verb and resource. It clearly distinguishes this tool from the seven extraction/processing siblings, so an agent can tell what it is for without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The purpose implies when to use it (check service health), and the sibling tools are obviously unrelated, but there is no explicit guidance on when to call this versus alternatives. There are also no exclusions or prerequisites mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inspect_documentC

inspect_document tool:文档探查(M6,P1,轻量)。

Args: pdf_path: PDF 路径(必填)。

Returns: 结构化 JSON 文本(PRD §4.6:pages/tables/images/formulas/text_chars)。

ParametersJSON Schema
NameRequiredDescriptionDefault
pdf_pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states that it returns structured JSON and implies it's a read operation, but it does not explicitly confirm that it's non-destructive, nor does it mention error handling, file validation, or any side effects. The internal references like 'M6, P1' and 'PRD §4.6' add noise without behavioral clarity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the purpose, but it includes internal project codes like 'M6, P1' and 'PRD §4.6' that are irrelevant to an AI agent. The Args/Returns structure is clear, but the extraneous metadata detracts from cleanliness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter) and the existence of an output schema, the description partially covers the return content but misses crucial usage guidance and behavioral details. It does not explain when to choose this tool over siblings, what happens on invalid input, or whether it is safe to call repeatedly. The absence of annotations makes these gaps more significant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema defines only pdf_path as a required string, and the description adds 'PDF 路径(必填)' which merely repeats that it's required. No additional meaning is provided about the path format, whether it's local or remote, or any constraints. Since schema description coverage is 0%, the description should compensate but fails to add substantive value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: it inspects a PDF document and returns structured JSON containing pages, tables, images, formulas, and text characters. This is specific about the verb (inspect) and resource (PDF document), but it does not explicitly differentiate from siblings like parse_text or extract_table, so it doesn't fully distinguish itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus alternatives. The description mentions '轻量' (lightweight), which could imply it's a quick overview, but it never states when to prefer it over parse_text, extract_table, or other siblings. There are no explicit usage conditions or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

parse_textC

parse_text tool:MinerU 文本路单跑。

V2.0(additive):新增可选 verify_pages —— 调用级显式指定 OvisOCR2 校验页(信号②;未指定/未启用 → 触发规则自行判定,默认零调用)。

Args: pdf_path: PDF 路径(必填)。 pages: 页号(int | list[int] | None;1-based)。 verify_pages: 页号(int | list[int] | None;1-based;OvisOCR2 校验页)。

Returns: 结构化 JSON 文本(ParseTextOutput)。

ParametersJSON Schema
NameRequiredDescriptionDefault
pagesNo
pdf_pathYes
verify_pagesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It does not mention side effects, permissions, rate limits, or how the tool interacts with the PDF. It only states that it returns structured JSON, which is minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with Args and Returns, but includes jargon like '信号②' and '触发规则自行判定' that are unclear to a general agent. It is not excessively long but could be tightened and made more accessible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no explicit purpose statement, the description is incomplete. It does not explain what happens on invalid pages, error handling, or how the output relates to the input. An agent cannot fully predict behavior from this alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains pdf_path as required, pages and verify_pages as int/list/None with 1-based indexing, and clarifies verify_pages is for OvisOCR2 validation. This adds meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'MinerU 文本路单跑' which is a vague pipeline reference rather than a clear statement of what the tool does. It mentions returning structured JSON but never explicitly says it extracts or parses text from a PDF, leaving the core action ambiguous for an agent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use parse_text versus siblings like vision_extract, dual_extract, extract_table, or extract_formulas. No conditions, exclusions, or alternative routing are mentioned, so an agent cannot determine the appropriate context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_outputB

validate_output tool:输出结构校验(M6,C1)。

Args: output_dir: 待校验目录(绝对或相对路径;必须位于输出根内)。

Returns: 结构化 JSON 文本({ok, errors, manifest_ok})。

ParametersJSON Schema
NameRequiredDescriptionDefault
output_dirYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses that output_dir must be within the output root and that the return value is structured JSON with keys {ok, errors, manifest_ok}, which is helpful. However, it does not explicitly state that validation is non-destructive, what the validation actually checks, how errors are reported, or whether any manifest is required.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and logically structured with a summary plus Args/Returns sections. It has almost no filler, though the opening repeats the tool name and the M6/C1 tag adds little without context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter validation tool, the description covers purpose, the parameter, a key constraint, and the return shape. It is incomplete though: it does not say when to prefer this tool over siblings, what structural checks are performed, or the meaning of manifest_ok/errors beyond the key names. The presence of an output schema mitigates the return-format gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must explain the parameter, and it does: output_dir is the directory to validate, accepts absolute or relative paths, and must lie within the output root. This adds real meaning beyond the bare schema type, though 'output root' is not defined and no example value is given.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the tool performs output structure validation ('输出结构校验') and identifies the target resource as a directory to validate. It is sufficiently distinct from the sibling extraction/inspection tools, though it is expressed as a noun phrase rather than a clear verb+resource action and the M6/C1 shorthand is unexplained.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus siblings such as inspect_document or health. The description provides a path constraint but no exclusions, prerequisites, or alternative routing, so the agent must infer the tool's role from its name and context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vision_extractB

vision_extract tool:视觉路单跑。

V1.3:新增 image_path 参数(独立图片输入,与 pdf_path 互斥二选一)。

Args: pdf_path: PDF 路径(与 image_path 互斥;二者必传其一)。 fields: 字段键(str | list[str] | dict;必填)。 pages: 页号(int | list[int] | None;1-based;图片输入忽略)。 model: 模型名(可选,默认 Settings.ollama_model)。 image_path: 独立图片文件路径(PNG/JPG 等,V1.3 新增)。

Returns: 结构化 JSON 文本(VisionExtractOutput)。

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNo
pagesNo
fieldsNo
pdf_pathNo
image_pathNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries full burden for behavioral disclosure. It only mentions that pages is ignored for image input and that the return is structured JSON. It omits side effects, external model invocation, network/API usage, file format limitations, and error behavior, which are important for a vision-based extraction tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The structured Arg/Returns layout is efficient and easy to scan. The version note about V1.3 image_path is slightly extraneous but not harmful; the summary phrase '视觉路单跑' is terse to the point of opacity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers parameter semantics and return type, which is adequate given an output schema exists. However, it does not explain the actual extraction behavior, supported input formats beyond PNG/JPG, or how this tool fits among the sibling extraction/parsing tools. For a 5-parameter tool with no annotations, this leaves meaning gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The Args section documents every parameter with types, constraints, and defaults (e.g., pdf_path vs image_path mutual exclusivity, fields being required, pages being 1-based/ignored for images, model defaulting to Settings.ollama_model). This fully compensates for the 0% schema description coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line '视觉路单跑' is a vague shorthand for visual waybill extraction rather than an explicit verb+resource statement. The Args/Returns sections imply an extraction task, and the tool name 'vision_extract' helps, but the description does not clearly define what the tool does or how it differs from siblings like extract_table or dual_extract.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives input constraints ('pdf_path and image_path are mutually exclusive and one must be provided'; 'pages ignored for image input') but never states when to choose this tool over sibling extractors, nor any scenario-based guidance. It is limited to parameter mechanics, not use-case routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv2.0.1
    • First observeddual_extract
    • First observedextract_formulas
    • First observedextract_table
    • First observedhealth
    • First observedinspect_document
    • First observedparse_text
    • First observedvalidate_output
    • First observedvision_extract

TDQS

B3.3/5.0

Scored across 8 tools

Disambiguation4/5

The extraction tools are separated by pipeline (text, vision, dual), and table/formula/inspection/validation/health tools occupy distinct roles. The only mild ambiguity is among parse_text, vision_extract, and dual_extract, but their descriptions clearly label them as separate routes.

Naming Consistency4/5

Most tools follow a verb_noun pattern: inspect_document, validate_output, parse_text, vision_extract, extract_table, extract_formulas. Minor inconsistencies exist: health is a bare noun, and parse_text uses 'parse' while others use 'extract'.

Tool Count5/5

8 tools is well-scoped for a PDF dual-extraction service: one preflight inspector, three extraction routes, two specialized extractors, one output validator, and one health check. No tool feels redundant.

Completeness5/5

The tool surface covers the full workflow: inspect_document preflights, parse_text/vision_extract/dual_extract handle text/vision/fusion extraction, extract_table and extract_formulas cover specialized content, validate_output closes the loop, and health covers service dependencies. No critical dead-end or missing operation is apparent.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A local MCP server that extracts text-layer content from PDF files, enabling AI agents to inspect, extract text, outlines, and page content.
    -
  • A
    license
    A
    quality
    D
    maintenance
    A 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.
    10
    MIT