From bebd141df2dd397afec0091d0592884522458708 Mon Sep 17 00:00:00 2001 From: d-turley <109699790+d-turley@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:20:09 -0700 Subject: [PATCH 1/2] fix: don't fail install when building without dev toolchain npm runs the root `prepare` script on every `npm install`, including when installing a single workspace example via `npm install` inside `examples/`. That flow does not install the root package's devDependencies, so `prepare`'s `npm run build` crashed with a cryptic `ERR_MODULE_NOT_FOUND: ts-to-zod`. Move `prepare` into scripts/prepare.mjs, which skips the SDK build with a helpful message when the build toolchain is missing instead of failing the install. Registry consumers are unaffected (prepare does not run for published packages and dist/ ships in the tarball); git installs still build because npm installs a git dependency's devDependencies before running prepare. Refs #687 Co-Authored-By: Claude Opus 4.8 (1M context) --- package.json | 2 +- scripts/prepare.mjs | 55 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 scripts/prepare.mjs diff --git a/package.json b/package.json index 8c6ead57b..37664cba3 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "examples:start": "NODE_ENV=development npm run build && bun examples/run-all.ts start", "examples:dev": "NODE_ENV=development bun examples/run-all.ts dev", "watch": "nodemon --watch src --ext ts,tsx --exec 'bun build.bun.ts'", - "prepare": "npm run build && husky", + "prepare": "node scripts/prepare.mjs", "docs": "typedoc", "docs:watch": "typedoc --watch", "generate:screenshots": "npm run build:all && docker run --rm -e EXAMPLE -e GENERATE_SCREENSHOTS=1 -v $(pwd):/work -w /work mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test tests/e2e/generate-grid-screenshots.spec.ts'", diff --git a/scripts/prepare.mjs b/scripts/prepare.mjs new file mode 100644 index 000000000..2b15877cf --- /dev/null +++ b/scripts/prepare.mjs @@ -0,0 +1,55 @@ +/** + * `prepare` lifecycle script. + * + * npm runs `prepare` on every `npm install`, including when someone installs a + * single workspace example via `npm install` inside `examples/`. That flow + * installs only that workspace's dependencies and does NOT install the root + * package's devDependencies (ts-to-zod, bun, tsx, esbuild, husky, ...), yet npm + * still runs this root `prepare`. Running the build there used to fail with a + * cryptic `ERR_MODULE_NOT_FOUND: ts-to-zod`. + * See https://github.com/modelcontextprotocol/ext-apps/issues/687. + * + * We detect a missing build toolchain and skip the build with a helpful message + * instead of crashing. Registry consumers are unaffected: `prepare` does not run + * for published packages and `dist/` ships in the tarball. Git installs still + * build, because npm installs a git dependency's devDependencies before running + * its `prepare`. + */ +import { execSync } from "node:child_process"; +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); + +// Root-only devDependencies that `npm run build` needs. If any is missing we are +// in a partial install (e.g. a workspace-child install) that cannot build. +const REQUIRED_TOOLING = ["ts-to-zod", "bun", "tsx"]; + +const missing = REQUIRED_TOOLING.filter((pkg) => { + try { + require.resolve(`${pkg}/package.json`); + return false; + } catch { + return true; + } +}); + +if (missing.length > 0) { + console.log( + `[prepare] Skipping SDK build: missing build tooling (${missing.join(", ")}).`, + ); + console.log( + "[prepare] This is expected when installing a single example. To build the " + + "SDK and run the examples, run `npm install` from the repository root.", + ); + process.exit(0); +} + +execSync("npm run build", { stdio: "inherit" }); + +// Install git hooks (husky). Best-effort: never fail the install if husky cannot +// run (e.g. when installing outside a git checkout). +try { + execSync("husky", { stdio: "inherit" }); +} catch { + // husky is optional for local development; ignore failures. +} From fefd82204a65c9d0da2a75da13597ae0c510a500 Mon Sep 17 00:00:00 2001 From: d-turley <109699790+d-turley@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:28:11 -0700 Subject: [PATCH 2/2] docs: install examples from the repository root The examples are npm workspaces of the repository root. Running `npm install` inside an example directory triggers the root `prepare` build without the root devDependencies installed, which fails (issue #687). Update the example READMEs to install from the repository root (which installs all workspaces and builds the SDK), then run the example from its directory. Refs #687 Co-Authored-By: Claude Opus 4.8 (1M context) --- examples/basic-host/README.md | 8 ++++++++ examples/basic-server-preact/README.md | 8 ++++++++ examples/basic-server-react/README.md | 8 ++++++++ examples/basic-server-solid/README.md | 8 ++++++++ examples/basic-server-svelte/README.md | 8 ++++++++ examples/basic-server-vanillajs/README.md | 8 ++++++++ examples/basic-server-vue/README.md | 8 ++++++++ examples/budget-allocator-server/README.md | 3 ++- examples/cohort-heatmap-server/README.md | 3 ++- examples/customer-segmentation-server/README.md | 3 ++- examples/integration-server/README.md | 8 ++++++++ examples/lazy-auth-server/README.md | 8 ++++++++ examples/map-server/README.md | 3 ++- examples/scenario-modeler-server/README.md | 3 ++- examples/shadertoy-server/README.md | 3 ++- examples/sheet-music-server/README.md | 3 ++- examples/system-monitor-server/README.md | 3 ++- examples/threejs-server/README.md | 3 ++- examples/transcript-server/README.md | 3 +++ examples/video-resource-server/README.md | 8 ++++++++ examples/wiki-explorer-server/README.md | 3 ++- 21 files changed, 103 insertions(+), 10 deletions(-) diff --git a/examples/basic-host/README.md b/examples/basic-host/README.md index c64cda75d..157ad2297 100644 --- a/examples/basic-host/README.md +++ b/examples/basic-host/README.md @@ -12,8 +12,16 @@ This basic host can also be used to test MCP Apps during local development. ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run start # Open http://localhost:8080 ``` diff --git a/examples/basic-server-preact/README.md b/examples/basic-server-preact/README.md index 6a75ddb07..4894135fa 100644 --- a/examples/basic-server-preact/README.md +++ b/examples/basic-server-preact/README.md @@ -57,8 +57,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/basic-server-react/README.md b/examples/basic-server-react/README.md index d2f2e0d7a..19b45a193 100644 --- a/examples/basic-server-react/README.md +++ b/examples/basic-server-react/README.md @@ -59,8 +59,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/basic-server-solid/README.md b/examples/basic-server-solid/README.md index 43811a2f9..a73068631 100644 --- a/examples/basic-server-solid/README.md +++ b/examples/basic-server-solid/README.md @@ -57,8 +57,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/basic-server-svelte/README.md b/examples/basic-server-svelte/README.md index ec6a0d26e..c4078c747 100644 --- a/examples/basic-server-svelte/README.md +++ b/examples/basic-server-svelte/README.md @@ -57,8 +57,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/basic-server-vanillajs/README.md b/examples/basic-server-vanillajs/README.md index 6445d8cab..7ef8ffb6b 100644 --- a/examples/basic-server-vanillajs/README.md +++ b/examples/basic-server-vanillajs/README.md @@ -58,8 +58,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/basic-server-vue/README.md b/examples/basic-server-vue/README.md index c484f5b93..e5ff2d52e 100644 --- a/examples/basic-server-vue/README.md +++ b/examples/basic-server-vue/README.md @@ -57,8 +57,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/budget-allocator-server/README.md b/examples/budget-allocator-server/README.md index d4da76f1c..897faf2b0 100644 --- a/examples/budget-allocator-server/README.md +++ b/examples/budget-allocator-server/README.md @@ -60,9 +60,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/cohort-heatmap-server/README.md b/examples/cohort-heatmap-server/README.md index c011933a6..a1d7136db 100644 --- a/examples/cohort-heatmap-server/README.md +++ b/examples/cohort-heatmap-server/README.md @@ -60,9 +60,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/customer-segmentation-server/README.md b/examples/customer-segmentation-server/README.md index 8f5cc23a9..a36ad1b8c 100644 --- a/examples/customer-segmentation-server/README.md +++ b/examples/customer-segmentation-server/README.md @@ -61,9 +61,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/integration-server/README.md b/examples/integration-server/README.md index d66ed743a..4e6f952c7 100644 --- a/examples/integration-server/README.md +++ b/examples/integration-server/README.md @@ -17,8 +17,16 @@ This example demonstrates all App SDK communication APIs and is used by the E2E ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/lazy-auth-server/README.md b/examples/lazy-auth-server/README.md index f2e754508..560ed96fc 100644 --- a/examples/lazy-auth-server/README.md +++ b/examples/lazy-auth-server/README.md @@ -16,8 +16,16 @@ The embedded OAuth authorization server is a deliberately minimal mock (HS256 JW ## Getting Started +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm start # → MCP endpoint at http://localhost:3097/mcp ``` diff --git a/examples/map-server/README.md b/examples/map-server/README.md index e1e044a84..5819647a4 100644 --- a/examples/map-server/README.md +++ b/examples/map-server/README.md @@ -52,9 +52,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/scenario-modeler-server/README.md b/examples/scenario-modeler-server/README.md index 8b4c18efc..ca0b43ae7 100644 --- a/examples/scenario-modeler-server/README.md +++ b/examples/scenario-modeler-server/README.md @@ -60,9 +60,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/shadertoy-server/README.md b/examples/shadertoy-server/README.md index e1390f672..f44ba3722 100644 --- a/examples/shadertoy-server/README.md +++ b/examples/shadertoy-server/README.md @@ -59,9 +59,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/sheet-music-server/README.md b/examples/sheet-music-server/README.md index 556b726df..8f3e25c31 100644 --- a/examples/sheet-music-server/README.md +++ b/examples/sheet-music-server/README.md @@ -55,9 +55,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/system-monitor-server/README.md b/examples/system-monitor-server/README.md index a754e606c..826dcc1b1 100644 --- a/examples/system-monitor-server/README.md +++ b/examples/system-monitor-server/README.md @@ -59,9 +59,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/threejs-server/README.md b/examples/threejs-server/README.md index 03175e4e5..e597e7e54 100644 --- a/examples/threejs-server/README.md +++ b/examples/threejs-server/README.md @@ -52,9 +52,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ``` diff --git a/examples/transcript-server/README.md b/examples/transcript-server/README.md index 3b3fa4221..52aa2a07f 100644 --- a/examples/transcript-server/README.md +++ b/examples/transcript-server/README.md @@ -61,7 +61,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ### Installation +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install ``` diff --git a/examples/video-resource-server/README.md b/examples/video-resource-server/README.md index 0d385f519..92f0c3b3d 100644 --- a/examples/video-resource-server/README.md +++ b/examples/video-resource-server/README.md @@ -45,8 +45,16 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Quick Start +The examples are npm workspaces that share the SDK built at the repository root, so install from there first: + ```bash +# from the repository root npm install +``` + +Then run this example from its directory: + +```bash npm run dev ``` diff --git a/examples/wiki-explorer-server/README.md b/examples/wiki-explorer-server/README.md index cc91b238d..49fb96db7 100644 --- a/examples/wiki-explorer-server/README.md +++ b/examples/wiki-explorer-server/README.md @@ -58,9 +58,10 @@ To test local modifications, use this configuration (replace `~/code/ext-apps` w ## Running -1. Install dependencies: +1. Install dependencies from the repository root (the examples are npm workspaces that share the SDK built there): ```bash + # from the repository root npm install ```