Skip to content

fix(pdf-server): npx DOMMatrix crash + broken MCPB bundle#584

Merged
ochafik merged 3 commits intomainfrom
ochafik/pdfjs-polyfill
Apr 2, 2026
Merged

fix(pdf-server): npx DOMMatrix crash + broken MCPB bundle#584
ochafik merged 3 commits intomainfrom
ochafik/pdfjs-polyfill

Conversation

@ochafik
Copy link
Copy Markdown
Contributor

@ochafik ochafik commented Apr 2, 2026

Two related distribution fixes (both broken since 1.3.0/#506):

1. npx crashes with DOMMatrix is not defined

pdfjs-dist/legacy/build/pdf.mjs does new DOMMatrix() at module scope. Its own polyfill loads @napi-rs/canvas (an optionalDependency), but npx frequently misses the platform-native binary (npm/cli#4828), so npx @modelcontextprotocol/server-pdf --stdio crashed.

The server only uses pdfjs for text/metadata/form-field extraction — never canvas rendering — so no-op stubs in pdfjs-polyfill.ts suffice. Kept --external in the bun bundle so it executes before pdfjs's hoisted static import.

2. MCPB bundle ships without runtime deps

mcpb pack zips whatever is on disk; in this monorepo all deps are hoisted to root node_modules, so the published .mcpb shipped 15 files with no pdfjs-dist/ajv/express and crashed on import in Claude Desktop.

build-mcpb.mjs now stages dist/ + manifest into a clean temp dir, runs a non-workspace npm install --omit=dev --omit=optional (~130MB of @napi-rs/canvas binaries skipped — the polyfill makes them unnecessary), syncs manifest.version to package.json, then packs. CI smoke-tests the extracted bundle starts.

Also: display_name "PDF (By Anthropic)""pdf-viewer" (spaces break MCP App UI rendering for MCPBs in Claude Desktop).

Thanks @bryan-anthropic for the analysis from the npm-to-mcpb pipeline.

Tested: npm pack + --omit=optional install starts cleanly; bun test 164/164; .mcpb unzip + initialize/tools/list handshake returns 8 tools.

…i-rs/canvas

pdfjs-dist/legacy/build/pdf.mjs does `new DOMMatrix()` at module scope.
Its own polyfill loads @napi-rs/canvas (an optionalDependency), but npx
frequently misses the platform-native binary (npm/cli#4828), so the
server crashed on `npx @modelcontextprotocol/server-pdf --stdio`:

    ReferenceError: DOMMatrix is not defined
        at pdfjs-dist/legacy/build/pdf.mjs:17078

The server only uses pdfjs for text/metadata/form-field extraction —
never canvas rendering — so no-op stubs suffice and avoid shipping
~130MB of native binaries.

The polyfill is a separate ESM module kept --external in the bun bundle
so it executes before pdfjs's hoisted static import; inlined body code
would run too late.

Broken since 1.3.0 (#506). Thanks to Bryan Thompson for the analysis
and fix shape from the npm-to-mcpb pipeline.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 2, 2026

Open in StackBlitz

@modelcontextprotocol/ext-apps

npm i https://pkg.pr.new/@modelcontextprotocol/ext-apps@584

@modelcontextprotocol/server-basic-preact

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-preact@584

@modelcontextprotocol/server-basic-react

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-react@584

@modelcontextprotocol/server-basic-solid

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-solid@584

@modelcontextprotocol/server-basic-svelte

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-svelte@584

@modelcontextprotocol/server-basic-vanillajs

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-vanillajs@584

@modelcontextprotocol/server-basic-vue

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-vue@584

@modelcontextprotocol/server-budget-allocator

npm i https://pkg.pr.new/@modelcontextprotocol/server-budget-allocator@584

@modelcontextprotocol/server-cohort-heatmap

npm i https://pkg.pr.new/@modelcontextprotocol/server-cohort-heatmap@584

@modelcontextprotocol/server-customer-segmentation

npm i https://pkg.pr.new/@modelcontextprotocol/server-customer-segmentation@584

@modelcontextprotocol/server-debug

npm i https://pkg.pr.new/@modelcontextprotocol/server-debug@584

@modelcontextprotocol/server-map

npm i https://pkg.pr.new/@modelcontextprotocol/server-map@584

@modelcontextprotocol/server-pdf

npm i https://pkg.pr.new/@modelcontextprotocol/server-pdf@584

@modelcontextprotocol/server-scenario-modeler

npm i https://pkg.pr.new/@modelcontextprotocol/server-scenario-modeler@584

@modelcontextprotocol/server-shadertoy

npm i https://pkg.pr.new/@modelcontextprotocol/server-shadertoy@584

@modelcontextprotocol/server-sheet-music

npm i https://pkg.pr.new/@modelcontextprotocol/server-sheet-music@584

@modelcontextprotocol/server-system-monitor

npm i https://pkg.pr.new/@modelcontextprotocol/server-system-monitor@584

@modelcontextprotocol/server-threejs

npm i https://pkg.pr.new/@modelcontextprotocol/server-threejs@584

@modelcontextprotocol/server-transcript

npm i https://pkg.pr.new/@modelcontextprotocol/server-transcript@584

@modelcontextprotocol/server-video-resource

npm i https://pkg.pr.new/@modelcontextprotocol/server-video-resource@584

@modelcontextprotocol/server-wiki-explorer

npm i https://pkg.pr.new/@modelcontextprotocol/server-wiki-explorer@584

commit: 3a89518

… spaces

`mcpb pack` zips whatever is on disk; in this monorepo all runtime deps
are hoisted to root node_modules, so the published .mcpb shipped without
pdfjs-dist/ajv/express/etc. and crashed on import in Claude Desktop.

build-mcpb.mjs stages dist/ + manifest into a clean temp dir, runs a
non-workspace `npm install --omit=dev --omit=optional` (the new
DOMMatrix polyfill makes @napi-rs/canvas's ~130MB of native binaries
unnecessary), syncs manifest.version to package.json, then packs.
Result: 12.3MB / 38.8MB unpacked, full MCP handshake + tools/list pass.

Also rename display_name "PDF (By Anthropic)" → "pdf-viewer" — spaces
in display_name break MCP App UI rendering for MCPBs in Claude Desktop.

CI now smoke-tests the extracted bundle starts (`dist/index.js --stdio`
prints "Ready") so a deps-less bundle can't ship again.
@ochafik ochafik changed the title fix(pdf-server): stub DOMMatrix/ImageData/Path2D for npx without @napi-rs/canvas fix(pdf-server): npx DOMMatrix crash + broken MCPB bundle Apr 2, 2026
@ochafik ochafik merged commit 04fed52 into main Apr 2, 2026
19 of 20 checks passed
ochafik added a commit that referenced this pull request Apr 2, 2026
Changes since 1.3.2:
- feat: add addEventListener/removeEventListener with DOM-model on* semantics (#573)
- feat(pdf-server): add save_as interact action (#580)
- feat(pdf-server): fit-to-page on fullscreen + pinch-to-zoom (#583)
- fix(pdf-server): npx DOMMatrix crash + broken MCPB bundle (#584)
- fix(pdf-server): viewer liveness, 1:1 batch results, fullscreen jitter (#579)
- fix(pdf-server): render page before O(numPages) annotation scans (#581)
- fix(pdf-server): radio + dropdown in fill_form/save (#577)
- fix(deps): bump path-to-regexp 8.3.0 → 8.4.1 to patch ReDoS CVEs (#576)
ochafik added a commit that referenced this pull request Apr 2, 2026
Changes since 1.3.2:
- feat: add addEventListener/removeEventListener with DOM-model on* semantics (#573)
- feat(pdf-server): add save_as interact action (#580)
- feat(pdf-server): fit-to-page on fullscreen + pinch-to-zoom (#583)
- fix(pdf-server): npx DOMMatrix crash + broken MCPB bundle (#584)
- fix(pdf-server): viewer liveness, 1:1 batch results, fullscreen jitter (#579)
- fix(pdf-server): render page before O(numPages) annotation scans (#581)
- fix(pdf-server): radio + dropdown in fill_form/save (#577)
- fix(deps): bump path-to-regexp 8.3.0 → 8.4.1 to patch ReDoS CVEs (#576)
- chore(deps): npm audit fix — sdk 1.29.0, systeminformation 5.31.5, +13 transitives (#585, #586)
ochafik pushed a commit that referenced this pull request Apr 2, 2026
Changes since 1.3.2:

SDK
- feat: add addEventListener/removeEventListener with DOM-model on* semantics (#573)

pdf-server
- feat: add save_as interact action (#580)
- feat: fit-to-page on fullscreen + pinch-to-zoom (#583)
- fix: npx DOMMatrix crash + broken MCPB bundle (#584)
- fix: viewer liveness, 1:1 batch results, fullscreen jitter (#579)
- fix: render page before O(numPages) annotation scans (#581)
- fix: radio + dropdown in fill_form/save (#577)

Dependencies
- chore: npm audit fix — sdk 1.29.0, systeminformation 5.31.5, +13 transitives (#585, #586)
- fix: bump path-to-regexp 8.3.0 → 8.4.1 to patch ReDoS CVEs (#576)
ochafik added a commit that referenced this pull request Apr 2, 2026
Changes since 1.3.2:

SDK
- feat: add addEventListener/removeEventListener with DOM-model on* semantics (#573)

pdf-server
- feat: add save_as interact action (#580)
- feat: fit-to-page on fullscreen + pinch-to-zoom (#583)
- fix: npx DOMMatrix crash + broken MCPB bundle (#584)
- fix: viewer liveness, 1:1 batch results, fullscreen jitter (#579)
- fix: render page before O(numPages) annotation scans (#581)
- fix: radio + dropdown in fill_form/save (#577)

Dependencies
- chore: npm audit fix — sdk 1.29.0, systeminformation 5.31.5, +13 transitives (#585, #586)
- fix: bump path-to-regexp 8.3.0 → 8.4.1 to patch ReDoS CVEs (#576)
ochafik added a commit that referenced this pull request Apr 2, 2026
* chore: bump ext-apps to 1.4.0

Changes since 1.3.2:

SDK
- feat: add addEventListener/removeEventListener with DOM-model on* semantics (#573)

pdf-server
- feat: add save_as interact action (#580)
- feat: fit-to-page on fullscreen + pinch-to-zoom (#583)
- fix: npx DOMMatrix crash + broken MCPB bundle (#584)
- fix: viewer liveness, 1:1 batch results, fullscreen jitter (#579)
- fix: render page before O(numPages) annotation scans (#581)
- fix: radio + dropdown in fill_form/save (#577)

Dependencies
- chore: npm audit fix — sdk 1.29.0, systeminformation 5.31.5, +13 transitives (#585, #586)
- fix: bump path-to-regexp 8.3.0 → 8.4.1 to patch ReDoS CVEs (#576)

* chore: update e2e snapshots [skip ci]

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant