From 89b6ac273ba266ab75bf1650e692139d74d03343 Mon Sep 17 00:00:00 2001 From: evolve-product-tick Date: Wed, 14 Oct 2026 02:38:26 +0000 Subject: [PATCH] fix: npm wrapper never enforces PDFMUX_MIN_VERSION on an already-installed pdfmux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isPdfmuxInstalled() only checked `import pdfmux` succeeds, not that the resolved version meets PDFMUX_MIN_VERSION — so a stale pdfmux on whatever python3/python the wrapper finds (which can differ from the environment backing the user's own `pdfmux` CLI) ran silently instead of upgrading. Reported as NameetP/pdfmux#10 ("MCP server mode produces garbled Korean text while the CLI works correctly on the same PDF") — plausible root cause is exactly this: two installs of pdfmux, drifted apart, and the wrapper never noticed because it never checked. --- CHANGELOG.md | 8 ++++++++ npm-wrapper/index.js | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37f405e..bb38a90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased — `pdfmux-mcp` (npm) no longer silently serves a stale pdfmux + +### Fixed + +- **The `npx -y pdfmux-mcp` wrapper accepted any already-importable `pdfmux`, even one below its own declared `PDFMUX_MIN_VERSION`.** Reported as "MCP server mode produces garbled Korean text while the CLI works correctly on the same PDF" (`NameetP/pdfmux#10`): the wrapper's `python3`/`python` can resolve to a different environment than the one backing the user's own `pdfmux` CLI binary, and the old check (`isPdfmuxInstalled`) only asked "does `import pdfmux` succeed," never "is it new enough." A stale install on that other environment runs silently instead of the version the wrapper advertises installing. + - **Fix:** `npm-wrapper/index.js`'s `getInstalledVersion()` + `versionAtLeast()` compare the resolved environment's actual `pdfmux.__version__` against `PDFMUX_MIN_VERSION` and reinstall/upgrade when it falls short, same as the already-correct "not installed at all" path. + - Not yet published to npm — `npm view pdfmux-mcp version` still serves `1.4.0` with this fix unreleased; publishing is a Tier-2 founder action, same gate as a PyPI release. + ## Unreleased — table cells no longer depend on what pymupdf4llm did to PyMuPDF ### Fixed diff --git a/npm-wrapper/index.js b/npm-wrapper/index.js index 127b449..f4eef2e 100644 --- a/npm-wrapper/index.js +++ b/npm-wrapper/index.js @@ -31,18 +31,29 @@ function findPython() { return null; } -function isPdfmuxInstalled(python) { +function getInstalledVersion(python) { try { - execSync(`${python} -c "import pdfmux; print(pdfmux.__version__)"`, { + return execSync(`${python} -c "import pdfmux; print(pdfmux.__version__)"`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], - }); - return true; + }).trim(); } catch { - return false; + return null; } } +function versionAtLeast(version, minVersion) { + const parts = (v) => v.split(".").map((n) => parseInt(n, 10) || 0); + const a = parts(version); + const b = parts(minVersion); + for (let i = 0; i < Math.max(a.length, b.length); i++) { + const x = a[i] || 0; + const y = b[i] || 0; + if (x !== y) return x > y; + } + return true; +} + function installPdfmux(python) { console.error("[pdfmux-mcp] Installing pdfmux..."); try { @@ -66,7 +77,21 @@ function main() { process.exit(1); } - if (!isPdfmuxInstalled(python)) { + // Bug (reported as "pdfmux-mcp garbles Korean text, pdfmux CLI doesn't" — + // NameetP/pdfmux#10): this check used to only ask "is pdfmux importable at + // all," so a stale pdfmux already present on whatever `python3`/`python` + // this wrapper resolves to (which can be a different install than the + // user's own `pdfmux` CLI binary) was accepted silently, even below + // PDFMUX_MIN_VERSION. Two installs drifting apart is exactly the kind of + // silent inconsistency this product's extraction claims are supposed to + // rule out — it must not exist in its own install path. + const installedVersion = getInstalledVersion(python); + if (!installedVersion || !versionAtLeast(installedVersion, PDFMUX_MIN_VERSION)) { + if (installedVersion) { + console.error( + `[pdfmux-mcp] Installed pdfmux ${installedVersion} is older than the required ${PDFMUX_MIN_VERSION} — upgrading.` + ); + } if (!installPdfmux(python)) { process.exit(1); }