* fix(pdf-server): stub DOMMatrix/ImageData/Path2D for npx without @napi-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.
* fix(pdf-server): MCPB bundle missing runtime deps + display_name with 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.
* fix(pdf-server): list interact in MCPB manifest tools (was stale since #491)
214 lines
5.8 KiB
YAML
214 lines
5.8 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
prettier-fix:
|
|
name: Auto-fix formatting
|
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ github.head_ref }}
|
|
token: ${{ github.token }}
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
- run: npm run prettier:fix
|
|
|
|
- name: Commit formatting changes
|
|
run: |
|
|
git diff --quiet && exit 0
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add -A
|
|
git commit -m "style: auto-fix prettier formatting"
|
|
git push
|
|
|
|
build:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
name: Linux x64
|
|
- os: ubuntu-24.04-arm
|
|
name: Linux ARM64
|
|
- os: windows-latest
|
|
name: Windows x64
|
|
- os: windows-11-arm
|
|
name: Windows ARM64
|
|
- os: macos-latest
|
|
name: macOS ARM64
|
|
|
|
name: Build (${{ matrix.name }})
|
|
runs-on: ${{ matrix.os }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Verify no private URLs in package-lock.json
|
|
shell: bash
|
|
run: '! grep -E "\"resolved\": \"https?://" package-lock.json | grep -v registry.npmjs.org'
|
|
|
|
- name: Verify example dependency versions
|
|
shell: bash
|
|
run: node scripts/check-versions.mjs
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
- run: npm run build
|
|
|
|
- name: Validate TypeDoc links
|
|
if: runner.os == 'Linux' && matrix.name == 'Linux x64'
|
|
run: npm exec typedoc -- --treatValidationWarningsAsErrors --emit none
|
|
|
|
- run: npm run examples:build
|
|
|
|
- name: Verify generated schemas are up-to-date
|
|
shell: bash
|
|
run: |
|
|
npm run generate:schemas
|
|
git diff --exit-code src/generated/ || (echo "Generated schemas are out of date. Run 'npm run generate:schemas' and commit." && exit 1)
|
|
|
|
- name: Verify synced snippets are up-to-date
|
|
shell: bash
|
|
run: |
|
|
npm run sync:snippets
|
|
git diff --exit-code src/ docs/ || (echo "Synced snippets are out of date. Run 'npm run sync:snippets' and commit." && exit 1)
|
|
|
|
- run: npm test
|
|
|
|
- run: npm run prettier
|
|
|
|
- name: Build MCPB bundle (pdf-server)
|
|
if: runner.os == 'Linux' && matrix.name == 'Linux x64'
|
|
run: node build-mcpb.mjs
|
|
working-directory: examples/pdf-server
|
|
|
|
- name: Smoke-test MCPB bundle starts
|
|
if: runner.os == 'Linux' && matrix.name == 'Linux x64'
|
|
run: |
|
|
unzip -q pdf-server.mcpb -d .mcpb-smoke
|
|
node .mcpb-smoke/dist/index.js --stdio < /dev/null 2>&1 | tee /tmp/mcpb-smoke.log
|
|
grep -q "Ready" /tmp/mcpb-smoke.log
|
|
working-directory: examples/pdf-server
|
|
|
|
e2e:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- uses: astral-sh/setup-uv@v7
|
|
|
|
- run: npm ci
|
|
|
|
- name: Install Playwright browsers
|
|
run: npx playwright install --with-deps chromium
|
|
|
|
- name: Run E2E tests
|
|
run: npx playwright test --reporter=list
|
|
|
|
- name: Upload test results
|
|
uses: actions/upload-artifact@v6
|
|
if: failure()
|
|
with:
|
|
name: test-results
|
|
path: test-results/
|
|
retention-days: 7
|
|
|
|
# Test build in Windows WSL (Ubuntu)
|
|
build-wsl:
|
|
name: Build (Windows WSL)
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: Vampire/setup-wsl@v6
|
|
with:
|
|
distribution: Ubuntu-24.04
|
|
|
|
- name: Install Node.js in WSL
|
|
shell: wsl-bash {0}
|
|
run: |
|
|
sudo apt-get update
|
|
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
|
sudo apt-get install -y nodejs
|
|
|
|
- name: Build and test in WSL
|
|
shell: wsl-bash {0}
|
|
run: |
|
|
npm ci
|
|
npm run build
|
|
npm run examples:build
|
|
npm test
|
|
npm run prettier
|
|
|
|
# Test that the package can be installed from git (triggers prepare script)
|
|
test-git-install:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
name: Linux x64
|
|
- os: ubuntu-24.04-arm
|
|
name: Linux ARM64
|
|
- os: windows-latest
|
|
name: Windows x64
|
|
- os: windows-11-arm
|
|
name: Windows ARM64
|
|
- os: macos-latest
|
|
name: macOS ARM64
|
|
|
|
name: Test git install (${{ matrix.name }})
|
|
runs-on: ${{ matrix.os }}
|
|
|
|
steps:
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
|
|
- name: Create test project and install from git
|
|
shell: bash
|
|
env:
|
|
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
|
HEAD_REF: ${{ github.head_ref || github.ref_name }}
|
|
run: |
|
|
mkdir test-project
|
|
cd test-project
|
|
npm init -y
|
|
# Install from the PR branch (use head repo for fork PRs)
|
|
npm install "git+https://github.com/${HEAD_REPO}#${HEAD_REF}"
|
|
# Verify the package is usable (ESM import)
|
|
node --input-type=module -e "import { App } from '@modelcontextprotocol/ext-apps'; console.log('Import successful:', typeof App)"
|