fix(pdf-server): npx DOMMatrix crash + broken MCPB bundle#584
Merged
Conversation
…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.
@modelcontextprotocol/ext-apps
@modelcontextprotocol/server-basic-preact
@modelcontextprotocol/server-basic-react
@modelcontextprotocol/server-basic-solid
@modelcontextprotocol/server-basic-svelte
@modelcontextprotocol/server-basic-vanillajs
@modelcontextprotocol/server-basic-vue
@modelcontextprotocol/server-budget-allocator
@modelcontextprotocol/server-cohort-heatmap
@modelcontextprotocol/server-customer-segmentation
@modelcontextprotocol/server-debug
@modelcontextprotocol/server-map
@modelcontextprotocol/server-pdf
@modelcontextprotocol/server-scenario-modeler
@modelcontextprotocol/server-shadertoy
@modelcontextprotocol/server-sheet-music
@modelcontextprotocol/server-system-monitor
@modelcontextprotocol/server-threejs
@modelcontextprotocol/server-transcript
@modelcontextprotocol/server-video-resource
@modelcontextprotocol/server-wiki-explorer
commit: |
… 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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two related distribution fixes (both broken since 1.3.0/#506):
1.
npxcrashes withDOMMatrix is not definedpdfjs-dist/legacy/build/pdf.mjsdoesnew DOMMatrix()at module scope. Its own polyfill loads@napi-rs/canvas(an optionalDependency), butnpxfrequently misses the platform-native binary (npm/cli#4828), sonpx @modelcontextprotocol/server-pdf --stdiocrashed.The server only uses pdfjs for text/metadata/form-field extraction — never canvas rendering — so no-op stubs in
pdfjs-polyfill.tssuffice. Kept--externalin the bun bundle so it executes before pdfjs's hoisted static import.2. MCPB bundle ships without runtime deps
mcpb packzips whatever is on disk; in this monorepo all deps are hoisted to rootnode_modules, so the published.mcpbshipped 15 files with nopdfjs-dist/ajv/expressand crashed on import in Claude Desktop.build-mcpb.mjsnow stagesdist/+ manifest into a clean temp dir, runs a non-workspacenpm install --omit=dev --omit=optional(~130MB of@napi-rs/canvasbinaries skipped — the polyfill makes them unnecessary), syncsmanifest.versiontopackage.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=optionalinstall starts cleanly;bun test164/164;.mcpbunzip +initialize/tools/listhandshake returns 8 tools.