pdf-capture-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. pdf_capture_mcp-0.1.0/.github/workflows/ci.yml +38 -0
  2. pdf_capture_mcp-0.1.0/.github/workflows/publish.yml +34 -0
  3. pdf_capture_mcp-0.1.0/.gitignore +35 -0
  4. pdf_capture_mcp-0.1.0/LICENSE +33 -0
  5. pdf_capture_mcp-0.1.0/PKG-INFO +39 -0
  6. pdf_capture_mcp-0.1.0/README.md +347 -0
  7. pdf_capture_mcp-0.1.0/pyproject.toml +69 -0
  8. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/__init__.py +3 -0
  9. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/__main__.py +35 -0
  10. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/classifier.py +125 -0
  11. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/config.py +78 -0
  12. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/engines/__init__.py +75 -0
  13. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/engines/base.py +47 -0
  14. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/engines/marker_engine.py +162 -0
  15. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/engines/mineru_engine.py +351 -0
  16. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/engines/pymupdf_engine.py +141 -0
  17. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/extractors/__init__.py +1 -0
  18. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/extractors/formulas.py +140 -0
  19. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/extractors/tables.py +126 -0
  20. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/extractors/tatr.py +118 -0
  21. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/llm_client.py +376 -0
  22. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/processors/__init__.py +1 -0
  23. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/processors/images.py +115 -0
  24. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/processors/layout.py +139 -0
  25. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/quality/__init__.py +1 -0
  26. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/quality/qc_gate.py +165 -0
  27. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/server.py +794 -0
  28. pdf_capture_mcp-0.1.0/src/pdf_capture_mcp/types.py +65 -0
  29. pdf_capture_mcp-0.1.0/tests/conftest.py +9 -0
  30. pdf_capture_mcp-0.1.0/tests/e2e_manual.py +134 -0
  31. pdf_capture_mcp-0.1.0/tests/test_server.py +66 -0
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v5
15
+ - run: uv sync --extra dev
16
+ - run: uv run ruff check src/ tests/
17
+ - run: uv run ruff format --check src/ tests/
18
+
19
+ typecheck:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: astral-sh/setup-uv@v5
24
+ - run: uv sync --extra dev
25
+ - run: uv run mypy src/pdf_capture_mcp/ --ignore-missing-imports
26
+
27
+ test:
28
+ runs-on: ${{ matrix.os }}
29
+ strategy:
30
+ matrix:
31
+ os: [ubuntu-latest, macos-latest]
32
+ python-version: ["3.11", "3.12"]
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - uses: astral-sh/setup-uv@v5
36
+ - run: uv python install ${{ matrix.python-version }}
37
+ - run: uv sync --extra dev --python ${{ matrix.python-version }}
38
+ - run: uv run pytest tests/ -v --tb=short
@@ -0,0 +1,34 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: astral-sh/setup-uv@v5
13
+ - name: Build package
14
+ run: uv build
15
+ - name: Upload artifacts
16
+ uses: actions/upload-artifact@v4
17
+ with:
18
+ name: dist
19
+ path: dist/
20
+
21
+ publish:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ id-token: write # Required for PyPI trusted publishing
26
+ steps:
27
+ - name: Download artifacts
28
+ uses: actions/download-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+ - uses: astral-sh/setup-uv@v5
33
+ - name: Publish to PyPI
34
+ run: uv publish --trusted-publishing always
@@ -0,0 +1,35 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+
9
+ # Virtual environments
10
+ .venv/
11
+ venv/
12
+ uv.lock
13
+
14
+ # Testing & tooling caches
15
+ .pytest_cache/
16
+ .mypy_cache/
17
+ .ruff_cache/
18
+ .coverage
19
+ htmlcov/
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/
24
+ .qoder/
25
+
26
+ # OS
27
+ .DS_Store
28
+
29
+ # Local artifacts
30
+ *.log
31
+ tmp/
32
+ ._*
33
+ .pytest_cache/
34
+ .ruff_cache/
35
+ .venv/
@@ -0,0 +1,33 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Third-party license notices:
26
+
27
+ - marker-pdf (Apache 2.0): https://github.com/datalab-to/marker
28
+ - MinerU (AGPL-3.0): https://github.com/opendatalab/MinerU
29
+ MinerU is invoked as a separate subprocess and is not linked into this package.
30
+ - pdfplumber (MIT): https://github.com/jsvine/pdfplumber
31
+ - Table Transformer (MIT): https://github.com/microsoft/table-transformer
32
+ - DePlot (Apache 2.0): https://github.com/google-research/google-research/tree/master/deplot
33
+ - pymupdf4llm (Apache 2.0): https://github.com/pymupdf/pymupdf4llm
@@ -0,0 +1,39 @@
1
+ Metadata-Version: 2.4
2
+ Name: pdf-capture-mcp
3
+ Version: 0.1.0
4
+ Summary: Multi-phase PDF capture pipeline as an MCP server. Convert PDF to high-quality structured Markdown.
5
+ Project-URL: Repository, https://github.com/ChenHongYu2026/pdf-capture-mcp
6
+ Project-URL: Issues, https://github.com/ChenHongYu2026/pdf-capture-mcp/issues
7
+ Author: ChenHongYu2026
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: extraction,markdown,mcp,ocr,pdf
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: fastmcp<4,>=3.2.0
19
+ Requires-Dist: httpx>=0.27
20
+ Requires-Dist: numpy>=1.26
21
+ Requires-Dist: pdfplumber>=0.11.0
22
+ Requires-Dist: pillow>=10.0
23
+ Requires-Dist: pymupdf4llm>=0.0.17
24
+ Requires-Dist: pypdf>=5.0
25
+ Provides-Extra: all
26
+ Requires-Dist: marker-pdf>=2.0; extra == 'all'
27
+ Requires-Dist: torch>=2.0; extra == 'all'
28
+ Requires-Dist: transformers>=4.40; extra == 'all'
29
+ Provides-Extra: dev
30
+ Requires-Dist: mypy>=1.15; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.15; extra == 'dev'
34
+ Provides-Extra: marker
35
+ Requires-Dist: marker-pdf>=2.0; extra == 'marker'
36
+ Provides-Extra: ml
37
+ Requires-Dist: torch>=2.0; extra == 'ml'
38
+ Requires-Dist: transformers>=4.40; extra == 'ml'
39
+ Provides-Extra: vlm
@@ -0,0 +1,347 @@
1
+ <a id="english"></a>
2
+
3
+ # pdf-capture-mcp
4
+
5
+ **English** | [中文](#chinese)
6
+
7
+ Multi-phase PDF capture pipeline as an [MCP](https://modelcontextprotocol.io) server.
8
+ Convert PDF documents into high-quality structured Markdown — with formula recognition,
9
+ table extraction, layout cleaning, and a built-in quality gate.
10
+
11
+ [![CI](https://github.com/ChenHongYu2026/pdf-capture-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/ChenHongYu2026/pdf-capture-mcp/actions/workflows/ci.yml)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
13
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
14
+
15
+ ## Features
16
+
17
+ - **Triple extraction engines**
18
+ - [pymupdf4llm](https://github.com/pymupdf/pymupdf4llm) (built-in) — zero setup, fast, always available
19
+ - [marker](https://github.com/datalab-to/marker) (recommended) — highest quality for complex layouts
20
+ - [MinerU](https://github.com/opendatalab/MinerU) (optional) — best for multi-column/InDesign PDFs, auto-managed in an isolated venv
21
+ - **7 MCP tools** — `pdf_to_markdown`, `extract_tables`, `classify_document`, `pdf_info`, `setup_vlm`, `check_environment`, `install_engine`
22
+ - **Optional VLM enhancement** — plug in any vision-capable model (Qwen-VL, GLM-4V, MiniMax, Moonshot, OpenAI, local Ollama…) for better table/formula extraction. **No extra dependencies needed** — works out of the box with the base install.
23
+ - **Quality gate** — multi-dimensional QC (text completeness, heading structure, formula integrity, table coverage)
24
+ - **Progressive setup** — works immediately with zero config; enhance with marker/VLM on demand
25
+ - **Privacy-first** — API keys are stored locally with `chmod 600` and never echoed back in responses
26
+
27
+ ## Quick Start
28
+
29
+ ### 1. Install
30
+
31
+ ```bash
32
+ # Base package (pymupdf engine + VLM support, ~80MB) — works immediately
33
+ pip install pdf-capture-mcp
34
+
35
+ # With marker engine (recommended for complex PDFs, includes PyTorch, ~2.5GB)
36
+ pip install "pdf-capture-mcp[marker]"
37
+
38
+ # Everything (marker + TATR table detection + DePlot charts, ~3GB)
39
+ pip install "pdf-capture-mcp[all]"
40
+ ```
41
+
42
+ ### 2. Add to your MCP client
43
+
44
+ For Qoder / Claude Desktop / Cursor, add to your `mcp.json`:
45
+
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "pdf-capture": {
50
+ "command": "uvx",
51
+ "args": ["pdf-capture-mcp"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ With marker engine (recommended):
58
+
59
+ ```json
60
+ {
61
+ "mcpServers": {
62
+ "pdf-capture": {
63
+ "command": "uvx",
64
+ "args": ["pdf-capture-mcp[marker]"]
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ Or if installed via pip:
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "pdf-capture": {
76
+ "command": "pdf-capture-mcp"
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### 3. Use it
83
+
84
+ Ask your AI agent things like:
85
+
86
+ > "Convert ~/Downloads/paper.pdf to Markdown"
87
+ > "Extract all tables from this report"
88
+ > "Is this PDF a scanned document?"
89
+
90
+ The server works immediately with the built-in pymupdf engine. For higher quality on
91
+ complex layouts, the agent can install marker on demand (or you can pre-install it).
92
+
93
+ ## Tools
94
+
95
+ | Tool | Description |
96
+ |------|-------------|
97
+ | `pdf_to_markdown` | Full pipeline: extract → clean → QC → structured Markdown |
98
+ | `extract_tables` | Table extraction (pdfplumber rules + optional TATR deep learning) |
99
+ | `classify_document` | Document type detection (academic paper, consulting report, …) |
100
+ | `pdf_info` | Fast metadata: page count, text layer, scanned detection |
101
+ | `setup_vlm` | Configure optional VLM enhancement (any vision-capable provider) |
102
+ | `check_environment` | Verify engines, dependencies, and filesystem compatibility |
103
+ | `install_engine` | Install marker/ml engines on behalf of the user |
104
+
105
+ ## VLM Enhancement (Optional)
106
+
107
+ VLM re-extracts complex tables and broken formulas from page images.
108
+ Works with **any provider whose model supports image input**:
109
+
110
+ | Provider | Example model | API base |
111
+ |----------|--------------|----------|
112
+ | Alibaba Qwen | `qwen-vl-max` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
113
+ | Zhipu AI | `glm-4v` | `https://open.bigmodel.cn/api/paas/v4` |
114
+ | MiniMax | `minimax-m3` | `https://api.minimaxi.com/v1` |
115
+ | Moonshot | `moonshot-v1-vision` | `https://api.moonshot.cn/v1` |
116
+ | OpenAI | `gpt-4o` | `https://api.openai.com/v1` |
117
+ | Ollama (local) | `llama3.2-vision` | `http://localhost:11434/v1` |
118
+
119
+ Set your key via environment variable (recommended — never typed into chat):
120
+
121
+ ```bash
122
+ export PDF_CAPTURE_VLM_API_KEY=your_key_here
123
+ ```
124
+
125
+ Then tell your agent: *"Enable VLM with qwen-vl-max"* — it validates vision capability
126
+ before saving. **Note: using VLM consumes your API tokens.**
127
+
128
+ ## MinerU Engine (Optional)
129
+
130
+ For the highest extraction quality on complex layouts (multi-column, InDesign PDFs):
131
+
132
+ ```bash
133
+ pdf-capture-mcp setup-mineru # requires Python 3.11 on PATH
134
+ ```
135
+
136
+ Models (~2GB) auto-download from ModelScope on first extraction.
137
+
138
+ ## Environment Variables
139
+
140
+ | Variable | Default | Description |
141
+ |----------|---------|-------------|
142
+ | `PDF_CAPTURE_ENGINE` | `auto` | Default engine: `marker` / `mineru` / `pymupdf` / `auto` |
143
+ | `PDF_CAPTURE_VLM_API_KEY` | — | VLM API key (preferred over passing in chat) |
144
+ | `PDF_CAPTURE_CACHE_DIR` | `~/.cache/pdf-capture-mcp` | Model & config cache |
145
+ | `PDF_CAPTURE_MINERU_VENV` | `<cache>/venv-mineru` | MinerU venv location |
146
+ | `PDF_CAPTURE_LOG_LEVEL` | `INFO` | Logging level |
147
+ | `MINERU_MODEL_SOURCE` | `modelscope` | MinerU model source: `modelscope` / `huggingface` / `local` |
148
+
149
+ ## Development
150
+
151
+ ```bash
152
+ git clone https://github.com/ChenHongYu2026/pdf-capture-mcp.git
153
+ cd pdf-capture-mcp
154
+ uv sync --extra dev
155
+ uv run pytest tests/ -v
156
+ uv run ruff check src/ tests/
157
+ uv run mypy src/pdf_capture_mcp/
158
+ ```
159
+
160
+ ## Troubleshooting
161
+
162
+ | Problem | Solution |
163
+ |---------|----------|
164
+ | `Operation not supported` during install | External/exFAT drive: `export UV_LINK_MODE=copy` then retry |
165
+ | `uvx: command not found` | Install uv: `curl -LsSf https://astral.sh/uv/install.sh \| sh` |
166
+ | MCP server not appearing in tools | Restart your MCP client; check `mcp.json` syntax |
167
+ | marker engine slow on first run | Downloads ~1GB models on first use; cached afterwards |
168
+ | Python version too low | Requires 3.11+: `uv python install 3.11` |
169
+
170
+ ## License
171
+
172
+ MIT — see [LICENSE](LICENSE).
173
+
174
+ Third-party notices: MinerU (AGPL-3.0, invoked as a separate subprocess, not linked),
175
+ marker (Apache-2.0), pdfplumber (MIT), Table Transformer (MIT), pymupdf4llm (Apache-2.0).
176
+
177
+ ---
178
+
179
+ <a id="chinese"></a>
180
+
181
+ # pdf-capture-mcp(中文)
182
+
183
+ [English](#english) | **中文**
184
+
185
+ 多阶段 PDF 捕获管线,以 [MCP](https://modelcontextprotocol.io) 服务器形式提供。
186
+ 将 PDF 文档转换为高质量结构化 Markdown —— 支持公式识别、表格提取、版面清洁和内置质量门控。
187
+
188
+ ## 功能特性
189
+
190
+ - **三提取引擎**
191
+ - [pymupdf4llm](https://github.com/pymupdf/pymupdf4llm)(内置)—— 零配置、快速、始终可用
192
+ - [marker](https://github.com/datalab-to/marker)(推荐)—— 复杂版面提取质量最高
193
+ - [MinerU](https://github.com/opendatalab/MinerU)(可选)—— 多栏/InDesign 排版最佳,自动管理独立虚拟环境
194
+ - **7 个 MCP 工具** —— `pdf_to_markdown`、`extract_tables`、`classify_document`、`pdf_info`、`setup_vlm`、`check_environment`、`install_engine`
195
+ - **可选 VLM 增强** —— 接入任何具备视觉能力的模型(通义千问 Qwen-VL、智谱 GLM-4V、MiniMax、月之暗面 Moonshot、OpenAI、本地 Ollama 等),提升表格/公式提取质量。**无需额外依赖**,基础安装即可使用。
196
+ - **质量门控** —— 多维度 QC 评估(文本完整度、标题结构、公式完好率、表格覆盖率)
197
+ - **渐进式配置** —— 零配置即可工作;按需增强 marker/VLM
198
+ - **隐私优先** —— API Key 以 `chmod 600` 权限本地存储,绝不在响应中回显
199
+
200
+ ## 快速开始
201
+
202
+ ### 1. 安装
203
+
204
+ ```bash
205
+ # 基础包(pymupdf 引擎 + VLM 支持,约 80MB)—— 安装即可用
206
+ pip install pdf-capture-mcp
207
+
208
+ # 含 marker 引擎(推荐复杂 PDF,包含 PyTorch,约 2.5GB)
209
+ pip install "pdf-capture-mcp[marker]"
210
+
211
+ # 完整安装(marker + TATR 表格检测 + DePlot 图表提取,约 3GB)
212
+ pip install "pdf-capture-mcp[all]"
213
+ ```
214
+
215
+ ### 2. 添加到 MCP 客户端
216
+
217
+ Qoder / Claude Desktop / Cursor 用户,在 `mcp.json` 中添加:
218
+
219
+ ```json
220
+ {
221
+ "mcpServers": {
222
+ "pdf-capture": {
223
+ "command": "uvx",
224
+ "args": ["pdf-capture-mcp"]
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ 含 marker 引擎(推荐):
231
+
232
+ ```json
233
+ {
234
+ "mcpServers": {
235
+ "pdf-capture": {
236
+ "command": "uvx",
237
+ "args": ["pdf-capture-mcp[marker]"]
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ 如果已通过 pip 安装:
244
+
245
+ ```json
246
+ {
247
+ "mcpServers": {
248
+ "pdf-capture": {
249
+ "command": "pdf-capture-mcp"
250
+ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ ### 3. 开始使用
256
+
257
+ 直接对你的 AI 助手说:
258
+
259
+ > “把 ~/Downloads/论文.pdf 转成 Markdown”
260
+ > “提取这份报告里的所有表格”
261
+ > “这个 PDF 是扫描件吗?”
262
+
263
+ 服务器使用内置 pymupdf 引擎即可立即工作。对于复杂版面,助手可按需安装 marker 引擎。
264
+
265
+ ## 工具列表
266
+
267
+ | 工具 | 说明 |
268
+ |------|------|
269
+ | `pdf_to_markdown` | 完整管线:提取 → 清洁 → QC → 结构化 Markdown |
270
+ | `extract_tables` | 表格提取(pdfplumber 规则 + 可选 TATR 深度学习) |
271
+ | `classify_document` | 文档类型检测(学术论文、咨询报告等) |
272
+ | `pdf_info` | 快速元数据:页数、文本层、扫描件检测 |
273
+ | `setup_vlm` | 配置可选的 VLM 增强(支持任何具备视觉能力的供应商) |
274
+ | `check_environment` | 校验引擎、依赖和文件系统兼容性 |
275
+ | `install_engine` | 代用户安装 marker/ml 引擎 |
276
+
277
+ ## VLM 增强(可选)
278
+
279
+ VLM 会从页面图像中重新提取复杂表格和损坏的公式。
280
+ 支持**任何模型具备图片输入能力的供应商**:
281
+
282
+ | 供应商 | 示例模型 | API 地址 |
283
+ |--------|----------|----------|
284
+ | 阿里通义千问 | `qwen-vl-max` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
285
+ | 智谱 AI | `glm-4v` | `https://open.bigmodel.cn/api/paas/v4` |
286
+ | MiniMax | `minimax-m3` | `https://api.minimaxi.com/v1` |
287
+ | 月之暗面 | `moonshot-v1-vision` | `https://api.moonshot.cn/v1` |
288
+ | OpenAI | `gpt-4o` | `https://api.openai.com/v1` |
289
+ | Ollama(本地) | `llama3.2-vision` | `http://localhost:11434/v1` |
290
+
291
+ 推荐通过环境变量设置 Key(避免在对话中输入):
292
+
293
+ ```bash
294
+ export PDF_CAPTURE_VLM_API_KEY=你的密钥
295
+ ```
296
+
297
+ 然后告诉助手:"启用 VLM,用 qwen-vl-max" —— 系统会先验证模型的视觉能力再保存配置。
298
+ **注意:使用 VLM 功能会消耗你的 Token。**
299
+
300
+ ## MinerU 引擎(可选)
301
+
302
+ 针对复杂版面(多栏、InDesign 排版 PDF)获得最高提取质量:
303
+
304
+ ```bash
305
+ pdf-capture-mcp setup-mineru # 需要 PATH 中有 Python 3.11
306
+ ```
307
+
308
+ 首次提取时会从 ModelScope 自动下载模型(约 2GB)。
309
+
310
+ ## 环境变量
311
+
312
+ | 变量 | 默认值 | 说明 |
313
+ |------|--------|------|
314
+ | `PDF_CAPTURE_ENGINE` | `auto` | 默认引擎:`marker` / `mineru` / `pymupdf` / `auto` |
315
+ | `PDF_CAPTURE_VLM_API_KEY` | — | VLM API Key(推荐方式,避免对话中传递) |
316
+ | `PDF_CAPTURE_CACHE_DIR` | `~/.cache/pdf-capture-mcp` | 模型与配置缓存目录 |
317
+ | `PDF_CAPTURE_MINERU_VENV` | `<cache>/venv-mineru` | MinerU 虚拟环境位置 |
318
+ | `PDF_CAPTURE_LOG_LEVEL` | `INFO` | 日志级别 |
319
+ | `MINERU_MODEL_SOURCE` | `modelscope` | MinerU 模型源:`modelscope` / `huggingface` / `local` |
320
+
321
+ ## 本地开发
322
+
323
+ ```bash
324
+ git clone https://github.com/ChenHongYu2026/pdf-capture-mcp.git
325
+ cd pdf-capture-mcp
326
+ uv sync --extra dev
327
+ uv run pytest tests/ -v
328
+ uv run ruff check src/ tests/
329
+ uv run mypy src/pdf_capture_mcp/
330
+ ```
331
+
332
+ ## 故障排查
333
+
334
+ | 问题 | 解决方案 |
335
+ |------|----------|
336
+ | 安装时报 `Operation not supported` | 外置/exFAT 磁盘:`export UV_LINK_MODE=copy` 后重试 |
337
+ | `uvx: command not found` | 安装 uv:`curl -LsSf https://astral.sh/uv/install.sh \| sh` |
338
+ | MCP 服务器未出现在工具列表 | 重启 MCP 客户端;检查 `mcp.json` 格式 |
339
+ | marker 引擎首次运行慢 | 首次使用需下载约 1GB 模型,后续使用缓存 |
340
+ | Python 版本过低 | 需要 3.11+:`uv python install 3.11` |
341
+
342
+ ## 许可证
343
+
344
+ MIT —— 详见 [LICENSE](LICENSE)。
345
+
346
+ 第三方声明:MinerU(AGPL-3.0,通过独立子进程调用,未链接)、
347
+ marker(Apache-2.0)、pdfplumber(MIT)、Table Transformer(MIT)、pymupdf4llm(Apache-2.0)。
@@ -0,0 +1,69 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "pdf-capture-mcp"
7
+ version = "0.1.0"
8
+ description = "Multi-phase PDF capture pipeline as an MCP server. Convert PDF to high-quality structured Markdown."
9
+ license = "MIT"
10
+ requires-python = ">=3.11"
11
+ authors = [{ name = "ChenHongYu2026" }]
12
+ keywords = ["pdf", "markdown", "mcp", "extraction", "ocr"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Topic :: Text Processing :: Markup :: Markdown",
20
+ ]
21
+ dependencies = [
22
+ "fastmcp>=3.2.0,<4",
23
+ "pymupdf4llm>=0.0.17",
24
+ "pdfplumber>=0.11.0",
25
+ "pypdf>=5.0",
26
+ "Pillow>=10.0",
27
+ "numpy>=1.26",
28
+ "httpx>=0.27",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ marker = ["marker-pdf>=2.0"]
33
+ ml = ["torch>=2.0", "transformers>=4.40"]
34
+ vlm = [] # VLM uses OpenAI-compatible HTTP API via httpx (already a base dep)
35
+ all = ["pdf-capture-mcp[marker,ml]"]
36
+ dev = [
37
+ "pytest>=8.0",
38
+ "pytest-asyncio>=0.24",
39
+ "ruff>=0.15",
40
+ "mypy>=1.15",
41
+ ]
42
+
43
+ [project.scripts]
44
+ pdf-capture-mcp = "pdf_capture_mcp.__main__:main"
45
+
46
+ [project.urls]
47
+ Repository = "https://github.com/ChenHongYu2026/pdf-capture-mcp"
48
+ Issues = "https://github.com/ChenHongYu2026/pdf-capture-mcp/issues"
49
+
50
+ [tool.hatch.build.targets.wheel]
51
+ packages = ["src/pdf_capture_mcp"]
52
+
53
+ [tool.ruff]
54
+ line-length = 100
55
+ target-version = "py311"
56
+
57
+ [tool.ruff.lint]
58
+ select = ["E", "F", "I", "N", "W", "UP"]
59
+
60
+ [tool.mypy]
61
+ # No python_version pin: numpy's type stubs use PEP 695 syntax (3.12+),
62
+ # which mypy rejects when targeting 3.11. Checks run against the active interpreter.
63
+ warn_return_any = true
64
+ warn_unused_configs = true
65
+ ignore_missing_imports = true
66
+
67
+ [tool.pytest.ini_options]
68
+ testpaths = ["tests"]
69
+ asyncio_mode = "auto"
@@ -0,0 +1,3 @@
1
+ """pdf-capture-mcp: Multi-phase PDF capture pipeline as an MCP server."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,35 @@
1
+ """Entry point: python -m pdf_capture_mcp"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+
7
+
8
+ def main() -> None:
9
+ """Start the PDF Capture MCP server."""
10
+ from pdf_capture_mcp.config import setup_logging
11
+ from pdf_capture_mcp.server import mcp
12
+
13
+ setup_logging()
14
+
15
+ # Handle setup-mineru subcommand
16
+ if len(sys.argv) > 1 and sys.argv[1] == "setup-mineru":
17
+ from pdf_capture_mcp.engines.mineru_engine import ensure_mineru_env
18
+
19
+ try:
20
+ python_exe = ensure_mineru_env()
21
+ print(f"MinerU environment ready: {python_exe}")
22
+ except RuntimeError as exc:
23
+ print(f"ERROR: {exc}", file=sys.stderr)
24
+ sys.exit(1)
25
+ return
26
+
27
+ # Determine transport
28
+ if "--sse" in sys.argv:
29
+ mcp.run(transport="sse")
30
+ else:
31
+ mcp.run(transport="stdio")
32
+
33
+
34
+ if __name__ == "__main__":
35
+ main()