# pdf2zh-next-mcp

[![PyPI](https://img.shields.io/pypi/v/pdf2zh-next-mcp)](https://pypi.org/project/pdf2zh-next-mcp/)
[![License](https://img.shields.io/pypi/l/pdf2zh-next-mcp)](LICENSE)

MCP server for PDF translation using [pdf2zh-next](https://github.com/funstory-ai/BabelDOC) as the PDF processing backend. Designed for **Claude Desktop**.

Instead of translating each segment independently (which loses context), this server extracts all segments at once and lets the LLM translate them together — preserving terminology consistency and context across the entire document.

> **Using Claude Code?** Check out [pdf2zh-next-skill](https://github.com/JaeHyeon-KAIST/pdf2zh-next-skill) — a lightweight skill-based approach without MCP overhead. It handles large PDFs better by leveraging Claude Code's direct file I/O and auto-continuation.

## How it works

```
┌─────────────────────────────────────────────────┐
│  Claude Desktop                                  │
│                                                  │
│  1. extract_segments  ──→  segments + formulas   │
│  2. LLM translates all segments at once          │
│  3. assemble_translated  ──→  final PDF          │
└─────────────────────────────────────────────────┘
```

The LLM sees every segment before translating — so terminology stays consistent, cross-page sentences flow naturally, and formula placeholders are preserved correctly.

## Prerequisites

[pdf2zh-next](https://github.com/funstory-ai/BabelDOC) must be installed separately:

```bash
uv tool install pdf2zh-next
```

Verify installation:

```bash
pdf2zh_next --version
```

> You need [uv](https://docs.astral.sh/uv/) to install both pdf2zh-next and this server.

## Installation

### From PyPI (recommended)

```bash
uv tool install pdf2zh-next-mcp
```

### From GitHub

```bash
uv tool install git+https://github.com/JaeHyeon-KAIST/pdf2zh-next-mcp
```

### From source

```bash
git clone https://github.com/JaeHyeon-KAIST/pdf2zh-next-mcp
cd pdf2zh-next-mcp
uv sync
```

## Setup

Add to your Claude Desktop MCP config:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

**If installed from PyPI or GitHub:**

```json
{
  "mcpServers": {
    "pdf-translate": {
      "command": "uvx",
      "args": ["pdf2zh-next-mcp"]
    }
  }
}
```

**If running from source:**

```json
{
  "mcpServers": {
    "pdf-translate": {
      "command": "uv",
      "args": [
        "run",
        "--directory", "/path/to/pdf2zh-next-mcp",
        "python", "-m", "pdf2zh_next_mcp.main"
      ]
    }
  }
}
```

> **Tip:** If Claude Desktop can't find `uvx`, use the absolute path (e.g., `/opt/homebrew/bin/uvx` on macOS, `C:\Users\you\.local\bin\uvx.exe` on Windows).

## Usage

Just ask:

> "Translate this PDF to Korean: /path/to/paper.pdf"

Behind the scenes:
1. `extract_segments` analyzes the PDF layout and returns all text segments
2. The LLM translates everything at once (with full context)
3. `assemble_translated` injects translations and generates the final PDF

Output files:
- `*-mono.pdf` — translated PDF
- `*-dual.pdf` — bilingual side-by-side
- `*-glossary.json` — terminology glossary

## Limitations

- **Large PDFs (~30+ pages):** Claude Desktop has a per-turn output token limit. For documents with many segments, the translation may fail mid-process with "response could not be fully generated". For large PDFs, use [pdf2zh-next-skill](https://github.com/JaeHyeon-KAIST/pdf2zh-next-skill) with Claude Code instead.
- **MCP tool result size:** Segments are paginated to stay within Claude Desktop's 25K token limit per tool response. This is handled automatically.

## Troubleshooting

### `BabeldocError: cannot unpack non-iterable NoneType object`

BabelDOC needs CMap files for font character mapping. If its automatic download times out, install them manually:

```bash
cd ~/Downloads
curl -L https://github.com/funstory-ai/BabelDOC-Assets/archive/refs/heads/main.zip -o BabelDOC-Assets.zip
unzip BabelDOC-Assets.zip
mkdir -p ~/.cache/babeldoc/cmap
cp BabelDOC-Assets-main/cmap/*.json ~/.cache/babeldoc/cmap/
```

This is a one-time setup. The cache path is the same on all platforms.

## License

MIT
