From b8ad6ba20ff56f32ca19115ffe8c561287ff75d7 Mon Sep 17 00:00:00 2001 From: Andrew Khadder Date: Thu, 16 Jul 2026 18:50:00 -0700 Subject: [PATCH 1/2] refactor: base Apps protocol on core --- .husky/pre-commit | 7 +- build.bun.ts | 1 + examples/basic-host/package.json | 2 +- examples/basic-server-preact/package.json | 4 +- examples/basic-server-react/package.json | 2 +- examples/basic-server-solid/package.json | 4 +- examples/basic-server-svelte/package.json | 4 +- examples/basic-server-vanillajs/package.json | 4 +- examples/basic-server-vue/package.json | 4 +- examples/budget-allocator-server/package.json | 2 +- examples/cohort-heatmap-server/package.json | 2 +- .../customer-segmentation-server/package.json | 2 +- examples/debug-server/package.json | 2 +- examples/integration-server/package.json | 4 +- examples/lazy-auth-server/package.json | 2 +- examples/map-server/package.json | 4 +- examples/pdf-server/package.json | 4 +- examples/quickstart/package.json | 2 +- examples/scenario-modeler-server/package.json | 2 +- examples/shadertoy-server/package.json | 2 +- examples/sheet-music-server/package.json | 2 +- examples/system-monitor-server/package.json | 2 +- examples/threejs-server/package.json | 4 +- examples/transcript-server/package.json | 2 +- examples/video-resource-server/package.json | 4 +- examples/wiki-explorer-server/package.json | 4 +- package-lock.json | 268 +++++++-------- package.json | 21 +- scripts/generate-schemas.ts | 10 +- src/app-bridge.ts | 287 +++++++--------- src/app.ts | 220 ++++++------ src/events.ts | 313 ++++++++---------- src/generated/schema.ts | 17 +- src/mcp-types.ts | 32 ++ src/message-transport.ts | 6 +- src/react/useApp.tsx | 2 +- src/spec.types.ts | 2 +- src/types.ts | 6 +- src/v2-invariants.test.ts | 17 +- typedoc.config.mjs | 9 + 40 files changed, 627 insertions(+), 661 deletions(-) create mode 100644 src/mcp-types.ts diff --git a/.husky/pre-commit b/.husky/pre-commit index ae5b3c73c..68b03f7a6 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -7,9 +7,10 @@ export NVM_DIR="$HOME/.nvm" [ -d "/opt/homebrew/bin" ] && export PATH="/opt/homebrew/bin:$PATH" # homebrew (macOS ARM) [ -d "/usr/local/bin" ] && export PATH="/usr/local/bin:$PATH" # homebrew (macOS Intel) -# Verify no private registry URLs in package-lock.json -if grep -E '"resolved": "https?://' package-lock.json | grep -v registry.npmjs.org > /dev/null; then - echo "ERROR: package-lock.json contains non-npmjs.org URLs" +# Verify no private registry URLs in package-lock.json. Fork preview packages +# are public artifacts and are intentionally allowed alongside npmjs.org. +if grep -E '"resolved": "https?://' package-lock.json | grep -Ev 'registry\.npmjs\.org|pkg\.pr\.new' > /dev/null; then + echo "ERROR: package-lock.json contains non-public registry URLs" echo "Run: docker run --rm -i -v \$PWD:/src -w /src node:latest npm i --registry=https://registry.npmjs.org/" exit 1 fi diff --git a/build.bun.ts b/build.bun.ts index 77308a32e..328657dc4 100644 --- a/build.bun.ts +++ b/build.bun.ts @@ -37,6 +37,7 @@ function buildJs( const PEER_EXTERNALS = [ "@modelcontextprotocol/client", "@modelcontextprotocol/core", + "@modelcontextprotocol/core/protocol", "@modelcontextprotocol/server", "zod", ]; diff --git a/examples/basic-host/package.json b/examples/basic-host/package.json index 5b735fc67..b4b563561 100644 --- a/examples/basic-host/package.json +++ b/examples/basic-host/package.json @@ -11,7 +11,7 @@ "dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\"" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/ext-apps": "^1.7.0", "react": "^19.2.0", "react-dom": "^19.2.0", diff --git a/examples/basic-server-preact/package.json b/examples/basic-server-preact/package.json index fa0c65b25..77ec6469c 100644 --- a/examples/basic-server-preact/package.json +++ b/examples/basic-server-preact/package.json @@ -24,11 +24,11 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "preact": "^10.0.0", diff --git a/examples/basic-server-react/package.json b/examples/basic-server-react/package.json index 06177e22a..9e8651625 100644 --- a/examples/basic-server-react/package.json +++ b/examples/basic-server-react/package.json @@ -37,7 +37,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", diff --git a/examples/basic-server-solid/package.json b/examples/basic-server-solid/package.json index c61b95e6c..d39ac5491 100644 --- a/examples/basic-server-solid/package.json +++ b/examples/basic-server-solid/package.json @@ -24,11 +24,11 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "solid-js": "1.9.10", diff --git a/examples/basic-server-svelte/package.json b/examples/basic-server-svelte/package.json index 54b4bc0c0..457b0a414 100644 --- a/examples/basic-server-svelte/package.json +++ b/examples/basic-server-svelte/package.json @@ -24,11 +24,11 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "svelte": "^5.0.0", diff --git a/examples/basic-server-vanillajs/package.json b/examples/basic-server-vanillajs/package.json index d37d0109a..3afbad4d4 100644 --- a/examples/basic-server-vanillajs/package.json +++ b/examples/basic-server-vanillajs/package.json @@ -24,11 +24,11 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" diff --git a/examples/basic-server-vue/package.json b/examples/basic-server-vue/package.json index a704bf871..8d6e23ef7 100644 --- a/examples/basic-server-vue/package.json +++ b/examples/basic-server-vue/package.json @@ -24,11 +24,11 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "vue": "^3.5.0", diff --git a/examples/budget-allocator-server/package.json b/examples/budget-allocator-server/package.json index 011a1857f..d953bebd9 100644 --- a/examples/budget-allocator-server/package.json +++ b/examples/budget-allocator-server/package.json @@ -29,7 +29,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", diff --git a/examples/cohort-heatmap-server/package.json b/examples/cohort-heatmap-server/package.json index 3c57bb2b7..42be7b6bb 100644 --- a/examples/cohort-heatmap-server/package.json +++ b/examples/cohort-heatmap-server/package.json @@ -29,7 +29,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", diff --git a/examples/customer-segmentation-server/package.json b/examples/customer-segmentation-server/package.json index 09bab3b36..de0f757cd 100644 --- a/examples/customer-segmentation-server/package.json +++ b/examples/customer-segmentation-server/package.json @@ -29,7 +29,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", diff --git a/examples/debug-server/package.json b/examples/debug-server/package.json index 71bc681f3..cdfdea7a6 100644 --- a/examples/debug-server/package.json +++ b/examples/debug-server/package.json @@ -37,7 +37,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "zod": "^4.1.13" }, "devDependencies": { diff --git a/examples/integration-server/package.json b/examples/integration-server/package.json index 62bf835cd..00269b697 100644 --- a/examples/integration-server/package.json +++ b/examples/integration-server/package.json @@ -15,11 +15,11 @@ "serve": "bun --watch main.ts" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", diff --git a/examples/lazy-auth-server/package.json b/examples/lazy-auth-server/package.json index b740d55b1..4c8960825 100644 --- a/examples/lazy-auth-server/package.json +++ b/examples/lazy-auth-server/package.json @@ -24,7 +24,7 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "jose": "^6.0.0" diff --git a/examples/map-server/package.json b/examples/map-server/package.json index 52d6ead09..524723c78 100644 --- a/examples/map-server/package.json +++ b/examples/map-server/package.json @@ -26,11 +26,11 @@ "serve": "bun --watch main.ts" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" diff --git a/examples/pdf-server/package.json b/examples/pdf-server/package.json index e6a63f110..63c6f4e76 100644 --- a/examples/pdf-server/package.json +++ b/examples/pdf-server/package.json @@ -26,11 +26,11 @@ }, "dependencies": { "@cantoo/pdf-lib": "^2.6.5", - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "pdfjs-dist": "^5.0.0", diff --git a/examples/quickstart/package.json b/examples/quickstart/package.json index 4355317a1..ab0cba511 100644 --- a/examples/quickstart/package.json +++ b/examples/quickstart/package.json @@ -18,7 +18,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0" }, diff --git a/examples/scenario-modeler-server/package.json b/examples/scenario-modeler-server/package.json index dce203663..29d8e8952 100644 --- a/examples/scenario-modeler-server/package.json +++ b/examples/scenario-modeler-server/package.json @@ -29,7 +29,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", diff --git a/examples/shadertoy-server/package.json b/examples/shadertoy-server/package.json index 26d3bf32e..a565a725c 100644 --- a/examples/shadertoy-server/package.json +++ b/examples/shadertoy-server/package.json @@ -27,7 +27,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" diff --git a/examples/sheet-music-server/package.json b/examples/sheet-music-server/package.json index 5227b08cd..54216a938 100644 --- a/examples/sheet-music-server/package.json +++ b/examples/sheet-music-server/package.json @@ -27,7 +27,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "abcjs": "^6.4.4", "cors": "^2.8.5", "express": "^5.1.0", diff --git a/examples/system-monitor-server/package.json b/examples/system-monitor-server/package.json index e5fdf568c..e241a3d75 100644 --- a/examples/system-monitor-server/package.json +++ b/examples/system-monitor-server/package.json @@ -29,7 +29,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", diff --git a/examples/threejs-server/package.json b/examples/threejs-server/package.json index 8468ae356..da2d513ee 100644 --- a/examples/threejs-server/package.json +++ b/examples/threejs-server/package.json @@ -26,11 +26,11 @@ "serve": "bun --watch main.ts" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", diff --git a/examples/transcript-server/package.json b/examples/transcript-server/package.json index 26dc4b568..653a769f4 100644 --- a/examples/transcript-server/package.json +++ b/examples/transcript-server/package.json @@ -27,7 +27,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" diff --git a/examples/video-resource-server/package.json b/examples/video-resource-server/package.json index 15afa8914..81bb207c1 100644 --- a/examples/video-resource-server/package.json +++ b/examples/video-resource-server/package.json @@ -24,11 +24,11 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" diff --git a/examples/wiki-explorer-server/package.json b/examples/wiki-explorer-server/package.json index 81a759a75..fc1b4a0fd 100644 --- a/examples/wiki-explorer-server/package.json +++ b/examples/wiki-explorer-server/package.json @@ -26,11 +26,11 @@ "serve": "bun --watch main.ts" }, "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cheerio": "^1.0.0", "cors": "^2.8.5", "express": "^5.1.0", diff --git a/package-lock.json b/package-lock.json index 82b954b55..84e514780 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,9 @@ }, "devDependencies": { "@boneskull/typedoc-plugin-mermaid": "^0.2.0", - "@modelcontextprotocol/client": "2.0.0-beta.3", - "@modelcontextprotocol/core": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", + "@modelcontextprotocol/core": "https://pkg.pr.new/khandrew1/typescript-sdk/@modelcontextprotocol/core@387b904", + "@modelcontextprotocol/server": "2.0.0-beta.4", "@playwright/test": "1.57.0", "@types/bun": "^1.3.2", "@types/node": "20.19.27", @@ -52,14 +52,20 @@ "node": ">=20" }, "peerDependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", - "@modelcontextprotocol/core": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", + "@modelcontextprotocol/core": "https://pkg.pr.new/khandrew1/typescript-sdk/@modelcontextprotocol/core@387b904", + "@modelcontextprotocol/server": "2.0.0-beta.4", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "zod": "^3.25.0 || ^4.0.0" }, "peerDependenciesMeta": { + "@modelcontextprotocol/client": { + "optional": true + }, + "@modelcontextprotocol/server": { + "optional": true + }, "react": { "optional": true }, @@ -72,7 +78,7 @@ "name": "@modelcontextprotocol/ext-apps-basic-host", "version": "1.7.4", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/ext-apps": "^1.7.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -98,11 +104,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "preact": "^10.0.0", @@ -131,7 +137,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", @@ -160,11 +166,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "solid-js": "1.9.10", @@ -190,11 +196,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "svelte": "^5.0.0", @@ -220,11 +226,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" @@ -248,11 +254,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "vue": "^3.5.0", @@ -281,7 +287,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", @@ -309,7 +315,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", @@ -341,7 +347,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", @@ -369,7 +375,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "zod": "^4.1.13" }, "bin": { @@ -391,11 +397,11 @@ "examples/integration-server": { "version": "1.7.4", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", @@ -425,7 +431,7 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "jose": "^6.0.0" @@ -449,11 +455,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" @@ -478,11 +484,11 @@ "license": "MIT", "dependencies": { "@cantoo/pdf-lib": "^2.6.5", - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "pdfjs-dist": "^5.0.0", @@ -517,7 +523,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0" }, @@ -549,7 +555,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", @@ -582,7 +588,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" @@ -609,7 +615,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "abcjs": "^6.4.4", "cors": "^2.8.5", "express": "^5.1.0", @@ -637,7 +643,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "chart.js": "^4.4.0", "cors": "^2.8.5", "express": "^5.1.0", @@ -663,11 +669,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "react": "^19.2.0", @@ -701,7 +707,7 @@ "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" @@ -726,11 +732,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cors": "^2.8.5", "express": "^5.1.0", "zod": "^4.1.13" @@ -754,11 +760,11 @@ "version": "1.7.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", "@modelcontextprotocol/express": "2.0.0-beta.3", "@modelcontextprotocol/ext-apps": "^1.7.0", "@modelcontextprotocol/node": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/server": "2.0.0-beta.4", "cheerio": "^1.0.0", "cors": "^2.8.5", "express": "^5.1.0", @@ -1162,9 +1168,9 @@ } }, "node_modules/@cantoo/pdf-lib": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@cantoo/pdf-lib/-/pdf-lib-2.7.2.tgz", - "integrity": "sha512-M+NYHU8nk8/XhaggiF7khx4R1GHxBOCKM0YmbKQZDga8BDxLmOC5b9HUEd9bmlIZQayRzz8kE/797MCSPEMhAA==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/@cantoo/pdf-lib/-/pdf-lib-2.7.4.tgz", + "integrity": "sha512-tMet5mSJOESLAvSw/NnVoty2L7hHtWGtXt7CjxL4jeq1r3fg8lB7+sO0qKRyqR3kxeWfa8W5C5IuyNtHSVaTeQ==", "license": "MIT", "dependencies": { "@pdf-lib/standard-fonts": "^1.0.0", @@ -2282,11 +2288,12 @@ "license": "MIT" }, "node_modules/@modelcontextprotocol/client": { - "version": "2.0.0-beta.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.0.0-beta.3.tgz", - "integrity": "sha512-o9z9YCGNxWNdklPdjcD0tr8pocC9OgjdArqgx3OjPMlTe0M/SSPC2olOJs5ueq77HSpz36mND0f0KteqEhKF3A==", + "version": "2.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.0.0-beta.4.tgz", + "integrity": "sha512-VNHA/UXDk7mCpVl+jOg5B4WMRRD2OEl+it360Lhi6HiCbrIB2f6pZ0cqSDKXQVUtZvqnhdQHzZAM9h8EKWhq/A==", "license": "MIT", "dependencies": { + "@modelcontextprotocol/core": "2.0.0-beta.4", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", @@ -2299,10 +2306,9 @@ } }, "node_modules/@modelcontextprotocol/core": { - "version": "2.0.0-beta.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.0.0-beta.3.tgz", - "integrity": "sha512-NqcrMybYMnTxVTjEhCAPiDmpkkRivjHcjMdjGB97s6JuM+jVkYDzhQaF1z0n6eS0gnKjvLI1l60t1617g44kow==", - "dev": true, + "version": "2.0.0-beta.4", + "resolved": "https://pkg.pr.new/khandrew1/typescript-sdk/@modelcontextprotocol/core@387b904", + "integrity": "sha512-GzU7PQ5I2+AjZeBe7SvDmnnydb/BHm5pLmWJ0X5qp+DZAQ28ld1SJSD+dBj9Io4U3fGB6m0BSsi/F2wUfkrjeg==", "license": "MIT", "dependencies": { "zod": "^4.2.0" @@ -2427,11 +2433,12 @@ } }, "node_modules/@modelcontextprotocol/server": { - "version": "2.0.0-beta.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0-beta.3.tgz", - "integrity": "sha512-EQxVIWf2XMAgjR38ZRZnX1iiOWH42tT/YJG8N4dVjAnrEGSEfPirR6FYfDC72yuNSvVYbPDTD1H3KHLLHPd18A==", + "version": "2.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0-beta.4.tgz", + "integrity": "sha512-pjMZcNEt1dOq0aJCcY3b7w1Ayh+qmQN2xlfTELcGV9yiAjEGIczBPBLWWW0k0zzo5T8kiv15jtKPsWeHGxLvLg==", "license": "MIT", "dependencies": { + "@modelcontextprotocol/core": "2.0.0-beta.4", "zod": "^4.2.0" }, "engines": { @@ -4003,13 +4010,13 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz", - "integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz", + "integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.7", - "@vue/shared": "3.5.39", + "@vue/shared": "3.5.40", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" @@ -4028,90 +4035,88 @@ } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz", - "integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz", + "integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.39", - "@vue/shared": "3.5.39" + "@vue/compiler-core": "3.5.40", + "@vue/shared": "3.5.40" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.39.tgz", - "integrity": "sha512-d0ki86iOyN8LoZPBmk5SJWNwHP19CnDDCfuo//+2WJa2g5Ke0Jay983PIBIcSSzldC68I8DrD5GrHV3OSDfodg==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz", + "integrity": "sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.7", - "@vue/compiler-core": "3.5.39", - "@vue/compiler-dom": "3.5.39", - "@vue/compiler-ssr": "3.5.39", - "@vue/shared": "3.5.39", + "@vue/compiler-core": "3.5.40", + "@vue/compiler-dom": "3.5.40", + "@vue/compiler-ssr": "3.5.40", + "@vue/shared": "3.5.40", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", - "postcss": "^8.5.15", + "postcss": "^8.5.19", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.39.tgz", - "integrity": "sha512-Ce7/wvwMHai74bdszfXExdazFigYnlF9zgCmEQUcM1j0fOymlouZ7XilTYNo8oUjhlnjYOZbGrcYKuqjz89Ucw==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz", + "integrity": "sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.39", - "@vue/shared": "3.5.39" + "@vue/compiler-dom": "3.5.40", + "@vue/shared": "3.5.40" } }, "node_modules/@vue/reactivity": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.39.tgz", - "integrity": "sha512-TpsuBJ9gGlZa5d23XcM2y8EXanz9dZeVDQBXRwzy46ItgvM+rWpzs+UVM0wcRLxGvcav0HE5jz2gNL53xlRAog==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz", + "integrity": "sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.39" + "@vue/shared": "3.5.40" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.39.tgz", - "integrity": "sha512-9GLtNyRvPAUMbX+7ono0RC2j0guo2LXVi8LvcmAooImACUKm0oFf0jjwbX8/H0AE/t1nxhAkn8RSl9PMCzzxZw==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.40.tgz", + "integrity": "sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.39", - "@vue/shared": "3.5.39" + "@vue/reactivity": "3.5.40", + "@vue/shared": "3.5.40" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.39.tgz", - "integrity": "sha512-7Y6aAGboKcXAZ3ECuUy7RrS5yy2r47dhTp2SKaJmYxjopImaVFaNa5Ne66NwGovsrxVAl5S5rwc7m22UG7Lmww==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz", + "integrity": "sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.39", - "@vue/runtime-core": "3.5.39", - "@vue/shared": "3.5.39", + "@vue/reactivity": "3.5.40", + "@vue/runtime-core": "3.5.40", + "@vue/shared": "3.5.40", "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.39.tgz", - "integrity": "sha512-yZSakiAGw85rZfG7UM8akMnIF+FmeiNk47uvHf2nVBBSe+dIKUhZuZq9+XgJhbV3nS5Z4ALH23/MpXofW+mbcw==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.40.tgz", + "integrity": "sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.39", - "@vue/shared": "3.5.39" - }, - "peerDependencies": { - "vue": "3.5.39" + "@vue/compiler-ssr": "3.5.40", + "@vue/runtime-dom": "3.5.40", + "@vue/shared": "3.5.40" } }, "node_modules/@vue/shared": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz", - "integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz", + "integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==", "license": "MIT" }, "node_modules/@webgpu/types": { @@ -4535,9 +4540,9 @@ } }, "node_modules/browserslist/node_modules/caniuse-lite": { - "version": "1.0.30001805", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz", - "integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "dev": true, "funding": [ { @@ -4556,9 +4561,9 @@ "license": "CC-BY-4.0" }, "node_modules/browserslist/node_modules/electron-to-chromium": { - "version": "1.5.389", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz", - "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==", + "version": "1.5.392", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.392.tgz", + "integrity": "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g==", "dev": true, "license": "ISC" }, @@ -5779,12 +5784,13 @@ } }, "node_modules/express-rate-limit": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", - "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.6.0.tgz", + "integrity": "sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA==", "license": "MIT", "peer": true, "dependencies": { + "debug": "^4.4.3", "ip-address": "^10.2.0" }, "engines": { @@ -7318,9 +7324,9 @@ } }, "node_modules/postcss": { - "version": "8.5.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.18.tgz", - "integrity": "sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==", + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", "funding": [ { "type": "opencollective", @@ -8116,9 +8122,9 @@ } }, "node_modules/svelte": { - "version": "5.56.4", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.4.tgz", - "integrity": "sha512-/d0QHehmRuJW8gVz395MTkPcPozxzdjBMBE8oEYGz8O3b9KTMzzQ9ZHJQLuFKOHOPQbU6kx/X4iid/EBBzH7iw==", + "version": "5.56.6", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.6.tgz", + "integrity": "sha512-p4HDLDogGHKRKCrgckQHNs5PEfXkju6JI5jTywueaKJI5hAdjPohEhRtQ0M1SWC/+TA73SPln+r7srr+7e4nZA==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", @@ -8143,9 +8149,9 @@ } }, "node_modules/systeminformation": { - "version": "5.31.16", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.16.tgz", - "integrity": "sha512-37NsFaeaqwYxanLgdJAGWj8OXIRgvSBsDXGhlC0uUoHyl9nf4HrNsZjqtQ9Gc99bj9FQpffzYccPVuQ6gpjfqg==", + "version": "5.31.17", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.17.tgz", + "integrity": "sha512-TvFA9iwDWlMjqZVlKIJ0Cy+Zgm9ttlMx0SMRwJDMNKyhlEKWBMb3+WRwDi/3dvHdWbexpos4Osp4U49p5WjB5g==", "license": "MIT", "os": [ "darwin", @@ -8566,9 +8572,9 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.0.tgz", - "integrity": "sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.1.tgz", + "integrity": "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9434,16 +9440,16 @@ } }, "node_modules/vue": { - "version": "3.5.39", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.39.tgz", - "integrity": "sha512-xmZCYabFGcirU8r0fTuvl/LICc1OU620rnqepaJDL/a141ZigkG7AyaxQLdqJ02ZRYzWe6YPaDHeQx7MfknQfA==", + "version": "3.5.40", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz", + "integrity": "sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.39", - "@vue/compiler-sfc": "3.5.39", - "@vue/runtime-dom": "3.5.39", - "@vue/server-renderer": "3.5.39", - "@vue/shared": "3.5.39" + "@vue/compiler-dom": "3.5.40", + "@vue/compiler-sfc": "3.5.40", + "@vue/runtime-dom": "3.5.40", + "@vue/server-renderer": "3.5.40", + "@vue/shared": "3.5.40" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index ffa0925e1..31e95696d 100644 --- a/package.json +++ b/package.json @@ -77,9 +77,9 @@ "author": "Olivier Chafik", "devDependencies": { "@boneskull/typedoc-plugin-mermaid": "^0.2.0", - "@modelcontextprotocol/client": "2.0.0-beta.3", - "@modelcontextprotocol/core": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", + "@modelcontextprotocol/core": "https://pkg.pr.new/khandrew1/typescript-sdk/@modelcontextprotocol/core@387b904", + "@modelcontextprotocol/server": "2.0.0-beta.4", "@playwright/test": "1.57.0", "@types/bun": "^1.3.2", "@types/node": "20.19.27", @@ -110,14 +110,20 @@ "zod": "^4.1.13" }, "peerDependencies": { - "@modelcontextprotocol/client": "2.0.0-beta.3", - "@modelcontextprotocol/core": "2.0.0-beta.3", - "@modelcontextprotocol/server": "2.0.0-beta.3", + "@modelcontextprotocol/client": "2.0.0-beta.4", + "@modelcontextprotocol/core": "https://pkg.pr.new/khandrew1/typescript-sdk/@modelcontextprotocol/core@387b904", + "@modelcontextprotocol/server": "2.0.0-beta.4", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "zod": "^3.25.0 || ^4.0.0" }, "peerDependenciesMeta": { + "@modelcontextprotocol/client": { + "optional": true + }, + "@modelcontextprotocol/server": { + "optional": true + }, "react": { "optional": true }, @@ -129,7 +135,8 @@ "seroval": "1.4.1", "seroval-plugins": "1.4.2", "solid-js": "1.9.10", - "@types/node": "20.19.27" + "@types/node": "20.19.27", + "@modelcontextprotocol/core": "https://pkg.pr.new/khandrew1/typescript-sdk/@modelcontextprotocol/core@387b904" }, "dependencies": { "@standard-schema/spec": "^1.1.0" diff --git a/scripts/generate-schemas.ts b/scripts/generate-schemas.ts index b56e20545..bac556233 100644 --- a/scripts/generate-schemas.ts +++ b/scripts/generate-schemas.ts @@ -104,7 +104,7 @@ const EXTERNAL_TYPE_SCHEMAS = [ const MCP_SCHEMA_PACKAGE = "@modelcontextprotocol/core"; /** v2 TypeScript types package — matches imports in spec.types.ts. */ -const MCP_TYPES_PACKAGE = "@modelcontextprotocol/client"; +const MCP_TYPES_PACKAGE = "../mcp-types"; async function main() { console.log("🔧 Generating Zod schemas from spec.types.ts...\n"); @@ -213,15 +213,17 @@ function postProcess(content: string): string { // schema instances throws at parse time. See header comment for details. // // Import schemas from @modelcontextprotocol/core, then re-bind as - // z.ZodType with T from @modelcontextprotocol/client so .d.ts emit does - // not try to name core-internal aliases (JSONObject → TS4023). + // z.ZodType with role-neutral types from the public Protocol entry so + // .d.ts emit does not try to name core-internal aliases (JSONObject → TS4023). + // The intermediate `unknown` prevents TypeScript from recursively comparing + // the SDK's full Zod schema graph during this intentional re-binding. const typeImports = EXTERNAL_TYPE_SCHEMAS.map((e) => e.type).join(",\n "); const schemaImports = EXTERNAL_TYPE_SCHEMAS.map( (e) => `${e.schema} as ${e.schema}FromCore`, ).join(",\n "); const schemaBindings = EXTERNAL_TYPE_SCHEMAS.map( (e) => - `const ${e.schema}: z.ZodType<${e.type}> = ${e.schema}FromCore as z.ZodType<${e.type}>;`, + `const ${e.schema}: z.ZodType<${e.type}> = ${e.schema}FromCore as unknown as z.ZodType<${e.type}>;`, ).join("\n"); content = content.replace( diff --git a/src/app-bridge.ts b/src/app-bridge.ts index a8050f3a7..71ecaaf90 100644 --- a/src/app-bridge.ts +++ b/src/app-bridge.ts @@ -1,10 +1,9 @@ import { - Client, - type Implementation, + type BaseContext, + type ProtocolOptions, type RequestOptions, type Transport, -} from "@modelcontextprotocol/client"; -import { Server, type ServerOptions } from "@modelcontextprotocol/server"; +} from "@modelcontextprotocol/core/protocol"; import type { CallToolRequest, CallToolResult, @@ -21,12 +20,14 @@ import type { ListToolsRequest, ListToolsResult, LoggingMessageNotification, + Implementation, PingRequest, PromptListChangedNotification, ReadResourceRequest, ReadResourceResult, ResourceListChangedNotification, ToolListChangedNotification, + ServerCapabilities, } from "./types"; import { CallToolResultSchema, @@ -39,10 +40,9 @@ import { ReadResourceResultSchema, } from "@modelcontextprotocol/core"; import { - MethodClaimRegistry, - NotificationEventEmitter, - methodOf, + ProtocolWithEvents, paramsSchemaOf, + type ProtocolEventSchemas, toRequestHandlerExtra, warnIfRequestHandlerReplaced, type RequestHandlerExtra, @@ -206,13 +206,61 @@ export function buildAllowAttribute( * * @property hostContext - Optional initial host context to provide to the view * - * @see `ServerOptions` from @modelcontextprotocol/server for available options + * @see `ProtocolOptions` from @modelcontextprotocol/core/protocol for available options * @see {@link McpUiHostContext `McpUiHostContext`} for the hostContext structure */ -export type HostOptions = ServerOptions & { +export type HostOptions = Omit & { hostContext?: McpUiHostContext; }; +/** + * Structural client surface used for automatic MCP forwarding. + * + * Keeping this role-neutral prevents AppBridge's public declarations from + * requiring the concrete `@modelcontextprotocol/client` package. + */ +export interface AppBridgeClient { + getServerCapabilities(): ServerCapabilities | undefined; + request( + request: CallToolRequest, + options?: RequestOptions, + ): Promise; + request( + request: ListResourcesRequest, + options?: RequestOptions, + ): Promise; + request( + request: ListResourceTemplatesRequest, + options?: RequestOptions, + ): Promise; + request( + request: ReadResourceRequest, + options?: RequestOptions, + ): Promise; + request( + request: ListPromptsRequest, + options?: RequestOptions, + ): Promise; + setNotificationHandler( + method: "notifications/tools/list_changed", + handler: ( + notification: ToolListChangedNotification, + ) => void | Promise, + ): void; + setNotificationHandler( + method: "notifications/resources/list_changed", + handler: ( + notification: ResourceListChangedNotification, + ) => void | Promise, + ): void; + setNotificationHandler( + method: "notifications/prompts/list_changed", + handler: ( + notification: PromptListChangedNotification, + ) => void | Promise, + ): void; +} + /** * Protocol versions supported by this AppBridge implementation. * @@ -302,13 +350,37 @@ export type AppBridgeEventMap = { * await bridge.connect(transport); * ``` */ -export class AppBridge extends Server { +export class AppBridge extends ProtocolWithEvents< + BaseContext, + AppBridgeEventMap +> { private _appCapabilities?: McpUiAppCapabilities; private _hostContext: McpUiHostContext = {}; private _appInfo?: Implementation; private _initializedReceived = false; - private readonly _claims = new MethodClaimRegistry(); - private readonly _events!: NotificationEventEmitter; + + protected readonly eventSchemas: ProtocolEventSchemas = { + sizechange: { + method: "ui/notifications/size-changed", + params: paramsSchemaOf(McpUiSizeChangedNotificationSchema), + }, + sandboxready: { + method: "ui/notifications/sandbox-proxy-ready", + params: paramsSchemaOf(McpUiSandboxProxyReadyNotificationSchema), + }, + initialized: { + method: "ui/notifications/initialized", + params: paramsSchemaOf(McpUiInitializedNotificationSchema), + }, + requestteardown: { + method: "ui/notifications/request-teardown", + params: paramsSchemaOf(McpUiRequestTeardownNotificationSchema), + }, + loggingmessage: { + method: "notifications/message", + params: paramsSchemaOf(LoggingMessageNotificationSchema), + }, + }; /** * Create a new AppBridge instance. @@ -347,82 +419,15 @@ export class AppBridge extends Server { private _hostCapabilities: McpUiHostCapabilities; constructor( - private _client: Client | null, + private _client: AppBridgeClient | null, private _hostInfo: Implementation, hostCapabilities: McpUiHostCapabilities, options?: HostOptions, ) { - const { hostContext, ...serverOptions } = options ?? {}; - // AppBridge proxies tools/resources/prompts/logging between view and MCP - // server. Declare the corresponding Server capabilities so v2's - // assertRequestHandlerCapability / assertNotificationCapability allow - // handler registration and list_changed notifications. (v1 AppBridge - // stubbed these checks as no-ops.) - // NOTE: must not use a constructor param named `_capabilities` — that - // would overwrite Server's MCP capability store. - super(_hostInfo, { - ...serverOptions, - capabilities: { - tools: { listChanged: true }, - resources: { listChanged: true, subscribe: true }, - prompts: { listChanged: true }, - logging: {}, - ...serverOptions.capabilities, - }, - }); + const { hostContext, ...protocolOptions } = options ?? {}; + super(protocolOptions); this._hostCapabilities = hostCapabilities; - // Server declares `oninitialized` as a class field (own data property). - // Delete it so AppBridge's prototype getter/setter for - // `ui/notifications/initialized` is not shadowed. - delete (this as { oninitialized?: unknown }).oninitialized; - Object.defineProperty(this, "oninitialized", { - get: () => this.getEventHandler("initialized"), - set: ( - callback: - | ((params: McpUiInitializedNotification["params"]) => void) - | undefined, - ) => { - this.setEventHandler("initialized", callback); - }, - enumerable: true, - configurable: true, - }); - - this._events = new NotificationEventEmitter( - { - sizechange: { - method: methodOf(McpUiSizeChangedNotificationSchema), - params: paramsSchemaOf(McpUiSizeChangedNotificationSchema), - }, - sandboxready: { - method: methodOf(McpUiSandboxProxyReadyNotificationSchema), - params: paramsSchemaOf(McpUiSandboxProxyReadyNotificationSchema), - }, - initialized: { - method: methodOf(McpUiInitializedNotificationSchema), - params: paramsSchemaOf(McpUiInitializedNotificationSchema), - }, - requestteardown: { - method: methodOf(McpUiRequestTeardownNotificationSchema), - params: paramsSchemaOf(McpUiRequestTeardownNotificationSchema), - }, - loggingmessage: { - method: methodOf(LoggingMessageNotificationSchema), - params: paramsSchemaOf(LoggingMessageNotificationSchema), - }, - }, - (method, paramsSchema, dispatch) => { - this._claims.claim(method); - Server.prototype.setNotificationHandler.call( - this, - method, - { params: paramsSchema }, - (params: unknown) => dispatch(params), - ); - }, - ); - this.addEventListener("initialized", () => { this._initializedReceived = true; }); @@ -452,7 +457,7 @@ export class AppBridge extends Server { // Default handler for requestDisplayMode - returns current mode from host context. // Hosts can override this by setting bridge.onrequestdisplaymode = ... - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/request-display-mode", { params: paramsSchemaOf(McpUiRequestDisplayModeRequestSchema), @@ -465,27 +470,6 @@ export class AppBridge extends Server { ); } - /** - * Shadowed with double-set protection. Arrow field so Protocol/Server - * constructors (ping, initialize, …) still hit the base implementation. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - override setRequestHandler = (...args: any[]): void => { - const method = args[0] as string; - this._claims.assertAndClaim(method, "setRequestHandler"); - (Server.prototype.setRequestHandler as Function).apply(this, args); - }; - - /** - * Shadowed with double-set protection. Arrow field — see setRequestHandler. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - override setNotificationHandler = (...args: any[]): void => { - const method = args[0] as string; - this._claims.assertAndClaim(method, "setNotificationHandler"); - (Server.prototype.setNotificationHandler as Function).apply(this, args); - }; - /** * Replace a request handler (on* replace semantics), wrapping with the * initialized-received warning. `ui/initialize` and `ping` use @@ -493,10 +477,11 @@ export class AppBridge extends Server { * * @see {@link https://github.com/anthropics/claude-ai-mcp/issues/149 claude-ai-mcp#149} */ + private readonly _baseReplaceRequestHandler = this.replaceRequestHandler; + // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _replaceRequestHandler = (...args: any[]): void => { + protected override replaceRequestHandler = (...args: any[]): void => { const method = args[0] as string; - this._claims.claim(method); const warn = () => { if (!this._initializedReceived) { console.warn( @@ -509,8 +494,7 @@ export class AppBridge extends Server { }; if (typeof args[1] === "function") { const handler = args[1]; - (Server.prototype.setRequestHandler as Function).call( - this, + this._baseReplaceRequestHandler( method, (request: unknown, ctx: unknown) => { warn(); @@ -520,8 +504,7 @@ export class AppBridge extends Server { } else { const schemas = args[1]; const handler = args[2]; - (Server.prototype.setRequestHandler as Function).call( - this, + this._baseReplaceRequestHandler( method, schemas, (params: unknown, ctx: unknown) => { @@ -532,31 +515,21 @@ export class AppBridge extends Server { } }; - private setEventHandler( - event: K, - handler: ((params: AppBridgeEventMap[K]) => void) | undefined, - ): void { - this._events.setEventHandler(event, handler); + /** @internal */ + protected buildContext(ctx: BaseContext): BaseContext { + return ctx; } - private getEventHandler( - event: K, - ): ((params: AppBridgeEventMap[K]) => void) | undefined { - return this._events.getEventHandler(event); + protected assertCapabilityForMethod(_method: string): void { + // Host-to-view requests are negotiated by ui/initialize. } - addEventListener( - event: K, - handler: (params: AppBridgeEventMap[K]) => void, - ): void { - this._events.addEventListener(event, handler); + protected assertRequestHandlerCapability(_method: string): void { + // AppBridge accepts the proxy handlers registered by the host. } - removeEventListener( - event: K, - handler: (params: AppBridgeEventMap[K]) => void, - ): void { - this._events.removeEventListener(event, handler); + protected assertNotificationCapability(_method: string): void { + // AppBridge notifications are negotiated by ui/initialize. } /** @@ -655,14 +628,12 @@ export class AppBridge extends Server { * @deprecated Use {@link addEventListener `addEventListener("sizechange", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. */ get onsizechange(): - | ((params: McpUiSizeChangedNotification["params"]) => void) - | undefined { + ((params: McpUiSizeChangedNotification["params"]) => void) | undefined { return this.getEventHandler("sizechange"); } set onsizechange( callback: - | ((params: McpUiSizeChangedNotification["params"]) => void) - | undefined, + ((params: McpUiSizeChangedNotification["params"]) => void) | undefined, ) { this.setEventHandler("sizechange", callback); } @@ -729,17 +700,16 @@ export class AppBridge extends Server { * @see {@link sendToolInput `sendToolInput`} for sending tool arguments to the View * @deprecated Use {@link addEventListener `addEventListener("initialized", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. */ - /** - * Called when the view completes initialization. - * - * Implemented via `Object.defineProperty` in the constructor so it does not - * conflict with Server's `oninitialized` class field (MCP - * `notifications/initialized`). Public Apps API unchanged. - * - * @see {@link McpUiInitializedNotification `McpUiInitializedNotification`} for the notification type - * @deprecated Use {@link addEventListener `addEventListener("initialized", handler)`} instead. - */ - declare oninitialized: (() => void) | undefined; + get oninitialized(): + ((params: McpUiInitializedNotification["params"]) => void) | undefined { + return this.getEventHandler("initialized"); + } + set oninitialized( + callback: + ((params: McpUiInitializedNotification["params"]) => void) | undefined, + ) { + this.setEventHandler("initialized", callback); + } /** * Register a handler for message requests from the view. @@ -792,7 +762,7 @@ export class AppBridge extends Server { ) { warnIfRequestHandlerReplaced("onmessage", this._onmessage, callback); this._onmessage = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/message", { params: paramsSchemaOf(McpUiMessageRequestSchema), @@ -868,7 +838,7 @@ export class AppBridge extends Server { ) { warnIfRequestHandlerReplaced("onopenlink", this._onopenlink, callback); this._onopenlink = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/open-link", { params: paramsSchemaOf(McpUiOpenLinkRequestSchema), @@ -947,7 +917,7 @@ export class AppBridge extends Server { callback, ); this._ondownloadfile = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/download-file", { params: paramsSchemaOf(McpUiDownloadFileRequestSchema), @@ -989,8 +959,7 @@ export class AppBridge extends Server { * @deprecated Use {@link addEventListener `addEventListener("requestteardown", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. */ get onrequestteardown(): - | ((params: McpUiRequestTeardownNotification["params"]) => void) - | undefined { + ((params: McpUiRequestTeardownNotification["params"]) => void) | undefined { return this.getEventHandler("requestteardown"); } set onrequestteardown( @@ -1054,7 +1023,7 @@ export class AppBridge extends Server { callback, ); this._onrequestdisplaymode = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/request-display-mode", { params: paramsSchemaOf(McpUiRequestDisplayModeRequestSchema), @@ -1099,14 +1068,12 @@ export class AppBridge extends Server { * @deprecated Use {@link addEventListener `addEventListener("loggingmessage", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. */ get onloggingmessage(): - | ((params: LoggingMessageNotification["params"]) => void) - | undefined { + ((params: LoggingMessageNotification["params"]) => void) | undefined { return this.getEventHandler("loggingmessage"); } set onloggingmessage( callback: - | ((params: LoggingMessageNotification["params"]) => void) - | undefined, + ((params: LoggingMessageNotification["params"]) => void) | undefined, ) { this.setEventHandler("loggingmessage", callback); } @@ -1158,7 +1125,7 @@ export class AppBridge extends Server { callback, ); this._onupdatemodelcontext = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/update-model-context", { params: paramsSchemaOf(McpUiUpdateModelContextRequestSchema), @@ -1217,7 +1184,7 @@ export class AppBridge extends Server { ) { warnIfRequestHandlerReplaced("oncalltool", this._oncalltool, callback); this._oncalltool = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "tools/call", ( request: any, @@ -1347,7 +1314,7 @@ export class AppBridge extends Server { callback, ); this._onlistresources = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "resources/list", ( request: any, @@ -1410,7 +1377,7 @@ export class AppBridge extends Server { callback, ); this._onlistresourcetemplates = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "resources/templates/list", ( request: any, @@ -1472,7 +1439,7 @@ export class AppBridge extends Server { callback, ); this._onreadresource = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "resources/read", ( request: any, @@ -1559,7 +1526,7 @@ export class AppBridge extends Server { callback, ); this._onlistprompts = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "prompts/list", ( request: any, diff --git a/src/app.ts b/src/app.ts index 494c3dc92..b95bb8bf5 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,10 +1,9 @@ import { - Client, - type ClientOptions, - type Implementation, + type BaseContext, + type ProtocolOptions, type RequestOptions, type Transport, -} from "@modelcontextprotocol/client"; +} from "@modelcontextprotocol/core/protocol"; import { CreateMessageResultSchema, CreateMessageResultWithToolsSchema, @@ -16,11 +15,13 @@ import type { CreateMessageRequest, CreateMessageResult, CreateMessageResultWithTools, + EmptyResult, ListResourcesRequest, ListResourcesResult, ListToolsRequest, ListToolsResult, LoggingMessageNotification, + Implementation, ReadResourceRequest, ReadResourceResult, Tool, @@ -28,15 +29,15 @@ import type { ToolListChangedNotification, } from "./types"; import { - MethodClaimRegistry, - NotificationEventEmitter, + ProtocolWithEvents, mergeCapabilities, - methodOf, paramsSchemaOf, + type ProtocolEventSchemas, toRequestHandlerExtra, warnIfRequestHandlerReplaced, type RequestHandlerExtra, } from "./events"; +export { ProtocolWithEvents } from "./events"; import { PostMessageTransport } from "./message-transport"; import { LATEST_PROTOCOL_VERSION, @@ -164,11 +165,11 @@ export const RESOURCE_MIME_TYPE = "text/html;profile=mcp-app"; /** * Options for configuring {@link App `App`} behavior. * - * Extends `ClientOptions` from the MCP TypeScript SDK v2 with `App`-specific configuration. + * Extends `ProtocolOptions` from the MCP TypeScript SDK v2 with `App`-specific configuration. * - * @see `ClientOptions` from @modelcontextprotocol/client for inherited options + * @see `ProtocolOptions` from @modelcontextprotocol/core/protocol for inherited options */ -export type AppOptions = ClientOptions & { +export type AppOptions = Omit & { /** * Automatically report size changes to the host using `ResizeObserver`. * @@ -215,12 +216,11 @@ export type AppOptions = ClientOptions & { export type AppToolResult< Out extends StandardSchemaV1 | undefined = undefined, > = Out extends StandardSchemaV1 - ? - | (CallToolResult & { - structuredContent: StandardSchemaV1.InferOutput; - isError?: false; - }) - | (CallToolResult & { isError: true }) + ? | (CallToolResult & { + structuredContent: StandardSchemaV1.InferOutput; + isError?: false; + }) + | (CallToolResult & { isError: true }) : CallToolResult; /** @@ -342,14 +342,35 @@ export type AppEventMap = { * await app.connect(); * ``` */ -export class App extends Client { +export class App extends ProtocolWithEvents { private _hostCapabilities?: McpUiHostCapabilities; private _hostInfo?: Implementation; private _hostContext?: McpUiHostContext; private _registeredTools: { [name: string]: RegisteredAppTool } = {}; private _initializedSent = false; - private readonly _claims = new MethodClaimRegistry(); - private readonly _events!: NotificationEventEmitter; + + protected readonly eventSchemas: ProtocolEventSchemas = { + toolinput: { + method: "ui/notifications/tool-input", + params: paramsSchemaOf(McpUiToolInputNotificationSchema), + }, + toolinputpartial: { + method: "ui/notifications/tool-input-partial", + params: paramsSchemaOf(McpUiToolInputPartialNotificationSchema), + }, + toolresult: { + method: "ui/notifications/tool-result", + params: paramsSchemaOf(McpUiToolResultNotificationSchema), + }, + toolcancelled: { + method: "ui/notifications/tool-cancelled", + params: paramsSchemaOf(McpUiToolCancelledNotificationSchema), + }, + hostcontextchanged: { + method: "ui/notifications/host-context-changed", + params: paramsSchemaOf(McpUiHostContextChangedNotificationSchema), + }, + }; /** * Warn if a host-bound method is called before {@link connect `connect`} has @@ -416,33 +437,29 @@ export class App extends Client { console.warn(msg); } - private setEventHandler( + protected override setEventHandler( event: K, handler: ((params: AppEventMap[K]) => void) | undefined, ): void { if (handler) this._assertHandlerTiming(event); - this._events.setEventHandler(event, handler); + super.setEventHandler(event, handler); } - private getEventHandler( - event: K, - ): ((params: AppEventMap[K]) => void) | undefined { - return this._events.getEventHandler(event); - } - - addEventListener( + override addEventListener( event: K, handler: (params: AppEventMap[K]) => void, ): void { this._assertHandlerTiming(event); - this._events.addEventListener(event, handler); + super.addEventListener(event, handler); } - removeEventListener( + protected override onEventDispatch( event: K, - handler: (params: AppEventMap[K]) => void, + params: AppEventMap[K], ): void { - this._events.removeEventListener(event, handler); + if (event === "hostcontextchanged") { + this._hostContext = { ...this._hostContext, ...params }; + } } /** @@ -475,50 +492,9 @@ export class App extends Client { allowUnsafeEval: _allowUnsafeEval, ...clientOptions } = options; - // NOTE: must not use a constructor param named `_capabilities` — that - // would overwrite Client's MCP capability store. - super(_appInfo, clientOptions); + super(clientOptions); this._appCapabilities = appCapabilities; - this._events = new NotificationEventEmitter( - { - toolinput: { - method: methodOf(McpUiToolInputNotificationSchema), - params: paramsSchemaOf(McpUiToolInputNotificationSchema), - }, - toolinputpartial: { - method: methodOf(McpUiToolInputPartialNotificationSchema), - params: paramsSchemaOf(McpUiToolInputPartialNotificationSchema), - }, - toolresult: { - method: methodOf(McpUiToolResultNotificationSchema), - params: paramsSchemaOf(McpUiToolResultNotificationSchema), - }, - toolcancelled: { - method: methodOf(McpUiToolCancelledNotificationSchema), - params: paramsSchemaOf(McpUiToolCancelledNotificationSchema), - }, - hostcontextchanged: { - method: methodOf(McpUiHostContextChangedNotificationSchema), - params: paramsSchemaOf(McpUiHostContextChangedNotificationSchema), - }, - }, - (method, paramsSchema, dispatch) => { - this._claims.claim(method); - Client.prototype.setNotificationHandler.call( - this, - method, - { params: paramsSchema }, - (params: unknown) => dispatch(params), - ); - }, - (event, params) => { - if (event === "hostcontextchanged") { - this._hostContext = { ...this._hostContext, ...params }; - } - }, - ); - if (!options.allowUnsafeEval) { z.config({ jitless: true }); } @@ -534,36 +510,39 @@ export class App extends Client { this.setEventHandler("hostcontextchanged", undefined); } - /** - * Shadowed with double-set protection. Arrow field so Protocol's constructor - * (which registers ping/cancelled/progress) still hits the base implementation. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - override setRequestHandler = (...args: any[]): void => { - const method = args[0] as string; - this._claims.assertAndClaim(method, "setRequestHandler"); - (Client.prototype.setRequestHandler as Function).apply(this, args); - }; + /** @internal */ + protected buildContext(ctx: BaseContext): BaseContext { + return ctx; + } - /** - * Shadowed with double-set protection. Arrow field — see setRequestHandler. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - override setNotificationHandler = (...args: any[]): void => { - const method = args[0] as string; - this._claims.assertAndClaim(method, "setNotificationHandler"); - (Client.prototype.setNotificationHandler as Function).apply(this, args); - }; + protected override assertCapabilityForMethod(method: string): void { + if ( + method === "sampling/createMessage" && + !this._hostCapabilities?.sampling + ) { + throw new Error( + `Host does not support sampling (required for ${method})`, + ); + } + } - /** - * Replace a request handler, bypassing double-set protection (on* replace semantics). - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _replaceRequestHandler = (...args: any[]): void => { - const method = args[0] as string; - this._claims.claim(method); - (Client.prototype.setRequestHandler as Function).apply(this, args); - }; + protected override assertRequestHandlerCapability(method: string): void { + switch (method) { + case "tools/call": + case "tools/list": + this._assertToolsCapability(method); + return; + case "ping": + case "ui/resource-teardown": + return; + default: + throw new Error(`No handler for method ${method} registered`); + } + } + + protected override assertNotificationCapability(_method: string): void { + // Apps notification capabilities are negotiated by ui/initialize. + } /** Tools capability check formerly in assertRequestHandlerCapability. */ private _assertToolsCapability(method: string): void { @@ -772,6 +751,11 @@ export class App extends Client { return this._hostCapabilities; } + /** Send a standard MCP ping request to the host bridge. */ + ping(options?: RequestOptions): Promise { + return this.request({ method: "ping" }, options); + } + /** * Get the host's implementation info discovered during initialization. * @@ -853,14 +837,12 @@ export class App extends Client { * @see {@link McpUiToolInputNotification `McpUiToolInputNotification`} for the notification structure */ get ontoolinput(): - | ((params: McpUiToolInputNotification["params"]) => void) - | undefined { + ((params: McpUiToolInputNotification["params"]) => void) | undefined { return this.getEventHandler("toolinput"); } set ontoolinput( callback: - | ((params: McpUiToolInputNotification["params"]) => void) - | undefined, + ((params: McpUiToolInputNotification["params"]) => void) | undefined, ) { this.setEventHandler("toolinput", callback); } @@ -947,14 +929,12 @@ export class App extends Client { * @see {@link ontoolinput `ontoolinput`} for the initial tool input handler */ get ontoolresult(): - | ((params: McpUiToolResultNotification["params"]) => void) - | undefined { + ((params: McpUiToolResultNotification["params"]) => void) | undefined { return this.getEventHandler("toolresult"); } set ontoolresult( callback: - | ((params: McpUiToolResultNotification["params"]) => void) - | undefined, + ((params: McpUiToolResultNotification["params"]) => void) | undefined, ) { this.setEventHandler("toolresult", callback); } @@ -986,14 +966,12 @@ export class App extends Client { * @see {@link ontoolresult `ontoolresult`} for successful tool completion */ get ontoolcancelled(): - | ((params: McpUiToolCancelledNotification["params"]) => void) - | undefined { + ((params: McpUiToolCancelledNotification["params"]) => void) | undefined { return this.getEventHandler("toolcancelled"); } set ontoolcancelled( callback: - | ((params: McpUiToolCancelledNotification["params"]) => void) - | undefined, + ((params: McpUiToolCancelledNotification["params"]) => void) | undefined, ) { this.setEventHandler("toolcancelled", callback); } @@ -1091,7 +1069,7 @@ export class App extends Client { ) { warnIfRequestHandlerReplaced("onteardown", this._onteardown, callback); this._onteardown = callback; - this._replaceRequestHandler( + this.replaceRequestHandler( "ui/resource-teardown", { params: paramsSchemaOf(McpUiResourceTeardownRequestSchema), @@ -1153,7 +1131,7 @@ export class App extends Client { warnIfRequestHandlerReplaced("oncalltool", this._oncalltool, callback); this._oncalltool = callback; this._assertToolsCapability("tools/call"); - this._replaceRequestHandler( + this.replaceRequestHandler( "tools/call", ( request: CallToolRequest, @@ -1227,7 +1205,7 @@ export class App extends Client { warnIfRequestHandlerReplaced("onlisttools", this._onlisttools, callback); this._onlisttools = callback; this._assertToolsCapability("tools/list"); - this._replaceRequestHandler( + this.replaceRequestHandler( "tools/list", ( request: ListToolsRequest, @@ -1999,12 +1977,12 @@ export class App extends Client { ); } this._initializedSent = false; - // Public reconnect guard: skip MCP initialize so negotiated protocol - // version stays undefined and Client._shouldDropInbound never arms. - transport.sessionId = transport.sessionId ?? "ext-apps-view-no-mcp-init"; - await super.connect(transport); try { + // Protocol.connect only wires the transport. ui/initialize below is the + // first and only handshake on the iframe channel. + await super.connect(transport); + const result = await this.request( { method: "ui/initialize", diff --git a/src/events.ts b/src/events.ts index 4218d0cad..9f6356aa9 100644 --- a/src/events.ts +++ b/src/events.ts @@ -1,178 +1,77 @@ -/** - * DOM-style notification event fan-out and double-set protection for - * {@link App} / {@link AppBridge}, composed onto v2 Client/Server rather than - * subclassing Protocol. - * - * ### Singular `on*` handler (like `el.onclick`) - * - * Assigning replaces the previous handler; assigning `undefined` clears it. - * `addEventListener` listeners are unaffected. - * - * ### Multi-listener (`addEventListener` / `removeEventListener`) - * - * Append to a per-event listener array. Listeners fire in insertion order - * after the singular `on*` handler. - * - * ### Dispatch order - * - * 1. Optional `onDispatch` side-effects (e.g. merge host context) - * 2. The singular `on*` handler (if set) - * 3. All `addEventListener` listeners in insertion order - * - * ### Double-set protection - * - * {@link MethodClaimRegistry} tracks methods claimed by event registration or - * internal handlers. App/AppBridge shadow `setRequestHandler` / - * `setNotificationHandler` to throw when the same method is claimed twice. - */ - -import type { StandardSchemaV1 } from "@modelcontextprotocol/client"; - -/** - * Request-handler context passed to App/AppBridge `on*` request callbacks. - * - * Preserves the v1-era `extra.signal` surface used by hosts and examples. - * Mapped internally from the v2 handler context (`ctx`). - */ -export type RequestHandlerExtra = { - signal: AbortSignal; - sessionId?: string; -}; - -/** - * Adapt v2 handler context to the public `extra` shape. - */ -export function toRequestHandlerExtra(ctx: { - sessionId?: string; - mcpReq: { signal: AbortSignal }; -}): RequestHandlerExtra { - return { - signal: ctx.mcpReq.signal, - sessionId: ctx.sessionId, +import { Protocol } from "@modelcontextprotocol/core/protocol"; +import type { + BaseContext, + StandardSchemaV1, +} from "@modelcontextprotocol/core/protocol"; + +export type ProtocolEventSchemas> = { + [K in keyof EventMap]: { + method: string; + params: StandardSchemaV1; }; -} - -/** - * Deep-merge capability objects (replaces v1 `mergeCapabilities`). - */ -export function mergeCapabilities(base: T, additional: T): T { - const result = { ...(base as Record) }; - for (const [key, value] of Object.entries(additional)) { - const existing = result[key]; - if ( - existing && - typeof existing === "object" && - !Array.isArray(existing) && - value && - typeof value === "object" && - !Array.isArray(value) - ) { - result[key] = mergeCapabilities( - existing as Record, - value as Record, - ); - } else { - result[key] = value; - } - } - return result as T; -} - -/** - * Tracks JSON-RPC methods claimed by event registration or internal handlers - * so accidental double-registration via `setRequestHandler` / - * `setNotificationHandler` throws instead of silently replacing. - */ -export class MethodClaimRegistry { - private readonly _methods = new Set(); - - /** Record a claim without throwing (replace / first-register paths). */ - claim(method: string): void { - this._methods.add(method); - } - - /** Throw if already claimed, then claim. */ - assertAndClaim(method: string, via: string): void { - if (this._methods.has(method)) { - throw new Error( - `Handler for "${method}" already registered (via ${via}). ` + - `Use addEventListener() to attach multiple listeners, ` + - `or the on* setter for replace semantics.`, - ); - } - this._methods.add(method); - } - - has(method: string): boolean { - return this._methods.has(method); - } -} +}; interface EventSlot { onHandler?: ((params: T) => void) | undefined; listeners: ((params: T) => void)[]; } -export type EventMethodSchema = { - method: string; - params: StandardSchemaV1; -}; - /** - * Registers one v2 notification handler per event method and fans out to - * `on*` + `addEventListener` listeners. + * Intermediate base class that adds DOM-style event support on top of the + * role-neutral MCP SDK `Protocol` engine. + * + * Subclasses provide a map from event names to generated v2 notification + * schemas. The first listener for an event installs one Protocol notification + * handler, which fans out to the singular `on*` handler and all listeners. + * Direct handler registration remains double-set protected. */ -export class NotificationEventEmitter< +export abstract class ProtocolWithEvents< + ContextT extends BaseContext, EventMap extends Record, -> { +> extends Protocol { + private readonly _registeredMethods = new Set(); private readonly _eventSlots = new Map(); - constructor( - private readonly _eventSchemas: { - [K in keyof EventMap]: EventMethodSchema; - }, - /** - * Called once per event on first use. Must register a v2 - * `setNotificationHandler(method, { params }, handler)` and claim the - * method in the caller's {@link MethodClaimRegistry}. - */ - private readonly _registerDispatcher: ( - method: string, - paramsSchema: StandardSchemaV1, - dispatch: (params: unknown) => void, - ) => void, - private readonly _onDispatch?: ( - event: K, - params: EventMap[K], - ) => void, - ) {} + protected abstract readonly eventSchemas: ProtocolEventSchemas; + + protected onEventDispatch( + _event: K, + _params: EventMap[K], + ): void {} private _ensureEventSlot( event: K, ): EventSlot { let slot = this._eventSlots.get(event) as - | EventSlot - | undefined; + EventSlot | undefined; if (!slot) { - const schema = this._eventSchemas[event]; + const schema = this.eventSchemas[event]; if (!schema) { throw new Error(`Unknown event: ${String(event)}`); } + slot = { listeners: [] }; this._eventSlots.set(event, slot as EventSlot); - const s = slot; - this._registerDispatcher(schema.method, schema.params, (params) => { - const p = params as EventMap[K]; - this._onDispatch?.(event, p); - s.onHandler?.(p); - for (const l of [...s.listeners]) l(p); - }); + this._registeredMethods.add(schema.method); + const stableSlot = slot; + super.setNotificationHandler( + schema.method, + { params: schema.params }, + (params) => { + const eventParams = params as EventMap[K]; + this.onEventDispatch(event, eventParams); + stableSlot.onHandler?.(eventParams); + for (const listener of [...stableSlot.listeners]) { + listener(eventParams); + } + }, + ); } return slot; } - setEventHandler( + protected setEventHandler( event: K, handler: ((params: EventMap[K]) => void) | undefined, ): void { @@ -186,7 +85,7 @@ export class NotificationEventEmitter< slot.onHandler = handler; } - getEventHandler( + protected getEventHandler( event: K, ): ((params: EventMap[K]) => void) | undefined { return (this._eventSlots.get(event) as EventSlot | undefined) @@ -205,18 +104,97 @@ export class NotificationEventEmitter< handler: (params: EventMap[K]) => void, ): void { const slot = this._eventSlots.get(event) as - | EventSlot - | undefined; + EventSlot | undefined; if (!slot) return; - const idx = slot.listeners.indexOf(handler); - if (idx !== -1) slot.listeners.splice(idx, 1); + const index = slot.listeners.indexOf(handler); + if (index !== -1) slot.listeners.splice(index, 1); + } + + // Arrow fields intentionally initialize after Protocol's constructor. Its + // built-in ping/cancelled/progress registrations therefore reach the base + // methods before our duplicate-registration state exists. + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + override setRequestHandler = (...args: any[]): void => { + const method = args[0] as string; + this._assertMethodNotRegistered(method, "setRequestHandler"); + (Protocol.prototype.setRequestHandler as Function).apply(this, args); + }; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + override setNotificationHandler = (...args: any[]): void => { + const method = args[0] as string; + this._assertMethodNotRegistered(method, "setNotificationHandler"); + (Protocol.prototype.setNotificationHandler as Function).apply(this, args); + }; + + /** + * Replace a request handler while retaining `on*` replace semantics. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + protected replaceRequestHandler = (...args: any[]): void => { + this._registeredMethods.add(args[0] as string); + (Protocol.prototype.setRequestHandler as Function).apply(this, args); + }; + + protected warnIfRequestHandlerReplaced( + name: string, + previous: unknown, + next: unknown, + ): void { + warnIfRequestHandlerReplaced(name, previous, next); + } + + private _assertMethodNotRegistered(method: string, via: string): void { + if (this._registeredMethods.has(method)) { + throw new Error( + `Handler for "${method}" already registered (via ${via}). ` + + `Use addEventListener() to attach multiple listeners, ` + + `or the on* setter for replace semantics.`, + ); + } + this._registeredMethods.add(method); } } -/** - * Warn if a request-handler `on*` setter is replacing a previously-set - * handler. Call from each request setter before updating the backing field. - */ +export type RequestHandlerExtra = { + signal: AbortSignal; + sessionId?: string; +}; + +export function toRequestHandlerExtra(ctx: { + sessionId?: string; + mcpReq: { signal: AbortSignal }; +}): RequestHandlerExtra { + return { + signal: ctx.mcpReq.signal, + sessionId: ctx.sessionId, + }; +} + +export function mergeCapabilities(base: T, additional: T): T { + const result = { ...(base as Record) }; + for (const [key, value] of Object.entries(additional)) { + const existing = result[key]; + if ( + existing && + typeof existing === "object" && + !Array.isArray(existing) && + value && + typeof value === "object" && + !Array.isArray(value) + ) { + result[key] = mergeCapabilities( + existing as Record, + value as Record, + ); + } else { + result[key] = value; + } + } + return result as T; +} + export function warnIfRequestHandlerReplaced( name: string, previous: unknown, @@ -230,25 +208,6 @@ export function warnIfRequestHandlerReplaced( } } -/** - * Extract the `params` Zod schema from a generated `{ method, params }` schema. - */ -export function paramsSchemaOf< - S extends { shape: { params: StandardSchemaV1 } }, ->(schema: S): S["shape"]["params"] { - return schema.shape.params; -} - -/** - * Extract the literal method string from a generated `{ method, params }` schema. - */ -export function methodOf< - S extends { shape: { method: { value?: string; values?: Set } } }, ->(schema: S): string { - const method = schema.shape.method; - if (typeof method.value === "string") return method.value; - if (method.values && method.values.size > 0) { - return method.values.values().next().value as string; - } - throw new Error("Could not extract method literal from schema"); +export function paramsSchemaOf(schema: unknown): StandardSchemaV1 { + return (schema as { shape: { params: StandardSchemaV1 } }).shape.params; } diff --git a/src/generated/schema.ts b/src/generated/schema.ts index 7dd746d4b..339e84cfb 100644 --- a/src/generated/schema.ts +++ b/src/generated/schema.ts @@ -10,7 +10,7 @@ import type { RequestId, ResourceLink, Tool, -} from "@modelcontextprotocol/client"; +} from "../mcp-types"; import { ContentBlockSchema as ContentBlockSchemaFromCore, CallToolResultSchema as CallToolResultSchemaFromCore, @@ -22,18 +22,19 @@ import { } from "@modelcontextprotocol/core"; const ContentBlockSchema: z.ZodType = - ContentBlockSchemaFromCore as z.ZodType; + ContentBlockSchemaFromCore as unknown as z.ZodType; const CallToolResultSchema: z.ZodType = - CallToolResultSchemaFromCore as z.ZodType; + CallToolResultSchemaFromCore as unknown as z.ZodType; const EmbeddedResourceSchema: z.ZodType = - EmbeddedResourceSchemaFromCore as z.ZodType; + EmbeddedResourceSchemaFromCore as unknown as z.ZodType; const ImplementationSchema: z.ZodType = - ImplementationSchemaFromCore as z.ZodType; + ImplementationSchemaFromCore as unknown as z.ZodType; const RequestIdSchema: z.ZodType = - RequestIdSchemaFromCore as z.ZodType; + RequestIdSchemaFromCore as unknown as z.ZodType; const ResourceLinkSchema: z.ZodType = - ResourceLinkSchemaFromCore as z.ZodType; -const ToolSchema: z.ZodType = ToolSchemaFromCore as z.ZodType; + ResourceLinkSchemaFromCore as unknown as z.ZodType; +const ToolSchema: z.ZodType = + ToolSchemaFromCore as unknown as z.ZodType; /** * @description Color theme preference for the host environment. diff --git a/src/mcp-types.ts b/src/mcp-types.ts new file mode 100644 index 000000000..414b0eb57 --- /dev/null +++ b/src/mcp-types.ts @@ -0,0 +1,32 @@ +export type { + CallToolRequest, + CallToolResult, + ContentBlock, + CreateMessageRequest, + CreateMessageResult, + CreateMessageResultWithTools, + EmbeddedResource, + EmptyResult, + Implementation, + JSONRPCMessage, + ListPromptsRequest, + ListPromptsResult, + ListResourcesRequest, + ListResourcesResult, + ListResourceTemplatesRequest, + ListResourceTemplatesResult, + ListToolsRequest, + ListToolsResult, + LoggingMessageNotification, + PingRequest, + PromptListChangedNotification, + ReadResourceRequest, + ReadResourceResult, + RequestId, + ResourceLink, + ResourceListChangedNotification, + ServerCapabilities, + Tool, + ToolAnnotations, + ToolListChangedNotification, +} from "@modelcontextprotocol/core/protocol"; diff --git a/src/message-transport.ts b/src/message-transport.ts index 160a31360..244d2de85 100644 --- a/src/message-transport.ts +++ b/src/message-transport.ts @@ -1,10 +1,10 @@ import { - type JSONRPCMessage, type MessageExtraInfo, type Transport, type TransportSendOptions, -} from "@modelcontextprotocol/client"; +} from "@modelcontextprotocol/core/protocol"; import { JSONRPCMessageSchema } from "@modelcontextprotocol/core"; +import type { JSONRPCMessage } from "./mcp-types"; import { TOOL_INPUT_PARTIAL_METHOD } from "./spec.types"; /** @@ -13,7 +13,7 @@ import { TOOL_INPUT_PARTIAL_METHOD } from "./spec.types"; * This transport enables bidirectional communication between MCP Apps running in * iframes and their host applications using the browser's `postMessage` API. It * implements the MCP TypeScript SDK `Transport` interface from - * `@modelcontextprotocol/client` (also used by `@modelcontextprotocol/server`). + * `@modelcontextprotocol/core` (also used by the role packages). * Optional v2 members ({@link hasPerRequestStream}, * {@link setSupportedProtocolVersions}) and extended * {@link TransportSendOptions} fields are accepted but unused — postMessage is diff --git a/src/react/useApp.tsx b/src/react/useApp.tsx index 0e64a74d6..8d585c6fd 100644 --- a/src/react/useApp.tsx +++ b/src/react/useApp.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import type { Implementation } from "@modelcontextprotocol/client"; +import type { Implementation } from "../mcp-types"; import { App, AppOptions, diff --git a/src/spec.types.ts b/src/spec.types.ts index 5a6470184..134cbebce 100644 --- a/src/spec.types.ts +++ b/src/spec.types.ts @@ -18,7 +18,7 @@ import type { RequestId, ResourceLink, Tool, -} from "@modelcontextprotocol/client"; +} from "./mcp-types"; /** * Current protocol version supported by this SDK. diff --git a/src/types.ts b/src/types.ts index 578721004..33df879af 100644 --- a/src/types.ts +++ b/src/types.ts @@ -144,6 +144,7 @@ import type { CreateMessageResult, CreateMessageResultWithTools, EmptyResult, + Implementation, ListPromptsRequest, ListPromptsResult, ListResourcesRequest, @@ -158,10 +159,11 @@ import type { ReadResourceRequest, ReadResourceResult, ResourceListChangedNotification, + ServerCapabilities, Tool, ToolAnnotations, ToolListChangedNotification, -} from "@modelcontextprotocol/client"; +} from "./mcp-types"; export type { CallToolRequest, @@ -170,6 +172,7 @@ export type { CreateMessageResult, CreateMessageResultWithTools, EmptyResult, + Implementation, ListPromptsRequest, ListPromptsResult, ListResourcesRequest, @@ -184,6 +187,7 @@ export type { ReadResourceRequest, ReadResourceResult, ResourceListChangedNotification, + ServerCapabilities, Tool, ToolAnnotations, ToolListChangedNotification, diff --git a/src/v2-invariants.test.ts b/src/v2-invariants.test.ts index 1e0fb0a7f..b845a85e6 100644 --- a/src/v2-invariants.test.ts +++ b/src/v2-invariants.test.ts @@ -2,10 +2,9 @@ * Phase 3 regression guards for the v2 SDK migration. * * Load-bearing invariant: the view↔host iframe link must NEVER negotiate an - * MCP protocol version. App.connect() sets a synthetic transport.sessionId - * before super.connect() so v2 Client.connect() takes the session-resumption - * path and skips MCP initialize. If a modern (2026-07-28) era were negotiated, - * Client._shouldDropInbound would silently drop ALL inbound requests on App. + * MCP protocol version. App and AppBridge extend the role-neutral Protocol, + * whose connect() only wires the transport; ui/initialize remains the sole + * handshake on this channel. * * Coverage note (vs src/app-bridge.test.ts): * - Teardown round-trips, bridge→app ping, registerTool/listTools/callTool, @@ -105,11 +104,11 @@ describe("v2 invariants — no MCP negotiation on App↔AppBridge", () => { delete (globalThis as { window?: unknown }).window; }); - it("keeps negotiated protocol version undefined after ui/initialize", () => { - expect(app.getNegotiatedProtocolVersion()).toBeUndefined(); - expect(app.getServerCapabilities()).toBeUndefined(); - expect(bridge.getNegotiatedProtocolVersion()).toBeUndefined(); - expect(bridge.getClientCapabilities()).toBeUndefined(); + it("negotiates only UI capabilities after ui/initialize", () => { + expect(app.getHostCapabilities()).toEqual(testHostCapabilities); + expect(bridge.getAppCapabilities()).toEqual({ + tools: { listChanged: true }, + }); }); it("never sends MCP initialize or notifications/initialized on the wire", () => { diff --git a/typedoc.config.mjs b/typedoc.config.mjs index 5f6d9e2ba..2f674fb29 100644 --- a/typedoc.config.mjs +++ b/typedoc.config.mjs @@ -32,6 +32,7 @@ const config = { excludePrivate: true, excludeInternal: false, intentionallyNotExported: [ + "src/events.ts:ProtocolEventSchemas", "src/server/index.ts:ZodRawShape", "src/server/index.ts:AppToolCallback", ], @@ -52,6 +53,14 @@ const config = { TransportSendOptions: V2_SDK_DOCS, "__type.enforceStrictCapabilities": V2_SDK_DOCS, }, + "@modelcontextprotocol/core": { + "MessageExtraInfo.classification": V2_SDK_DOCS, + "Protocol.close": V2_SDK_DOCS, + "Protocol.notification": V2_SDK_DOCS, + "SdkErrorCode.UnsupportedResultType": V2_SDK_DOCS, + Transport: V2_SDK_DOCS, + TransportSendOptions: V2_SDK_DOCS, + }, "@modelcontextprotocol/server": { LoggingMessageNotification: V2_SDK_DOCS, "MessageExtraInfo.classification": V2_SDK_DOCS, From ebfe660fb197aa2467c940964317d2a34215e0d6 Mon Sep 17 00:00:00 2001 From: Andrew Khadder Date: Thu, 16 Jul 2026 18:52:59 -0700 Subject: [PATCH 2/2] fix: generate lockfile with CI npm --- package-lock.json | 503 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 401 insertions(+), 102 deletions(-) diff --git a/package-lock.json b/package-lock.json index 84e514780..35ee09587 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,6 +99,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/basic-host/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-host/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/basic-server-preact": { "name": "@modelcontextprotocol/server-basic-preact", "version": "1.7.4", @@ -129,6 +146,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/basic-server-preact/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-server-preact/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/basic-server-react": { "name": "@modelcontextprotocol/server-basic-react", "version": "1.7.4", @@ -161,6 +195,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/basic-server-react/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-server-react/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/basic-server-solid": { "name": "@modelcontextprotocol/server-basic-solid", "version": "1.7.4", @@ -191,6 +242,23 @@ "vite-plugin-solid": "^2.11.12" } }, + "examples/basic-server-solid/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-server-solid/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/basic-server-svelte": { "name": "@modelcontextprotocol/server-basic-svelte", "version": "1.7.4", @@ -221,6 +289,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/basic-server-svelte/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-server-svelte/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/basic-server-vanillajs": { "name": "@modelcontextprotocol/server-basic-vanillajs", "version": "1.7.4", @@ -249,6 +334,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/basic-server-vanillajs/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-server-vanillajs/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/basic-server-vue": { "name": "@modelcontextprotocol/server-basic-vue", "version": "1.7.4", @@ -279,6 +381,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/basic-server-vue/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/basic-server-vue/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/budget-allocator-server": { "name": "@modelcontextprotocol/server-budget-allocator", "version": "1.7.4", @@ -307,6 +426,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/budget-allocator-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/budget-allocator-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/cohort-heatmap-server": { "name": "@modelcontextprotocol/server-cohort-heatmap", "version": "1.7.4", @@ -339,6 +475,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/cohort-heatmap-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/cohort-heatmap-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/customer-segmentation-server": { "name": "@modelcontextprotocol/server-customer-segmentation", "version": "1.7.4", @@ -367,6 +520,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/customer-segmentation-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/customer-segmentation-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/debug-server": { "name": "@modelcontextprotocol/server-debug", "version": "1.7.4", @@ -394,6 +564,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/debug-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/debug-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/integration-server": { "version": "1.7.4", "dependencies": { @@ -424,6 +611,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/integration-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/integration-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/lazy-auth-server": { "name": "@modelcontextprotocol/server-lazy-auth", "version": "1.7.4", @@ -450,6 +654,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/lazy-auth-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/lazy-auth-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/map-server": { "name": "@modelcontextprotocol/server-map", "version": "1.7.4", @@ -478,6 +699,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/map-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/map-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/pdf-server": { "name": "@modelcontextprotocol/server-pdf", "version": "1.7.4", @@ -508,6 +746,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/pdf-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/pdf-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/qr-server": { "name": "@modelcontextprotocol/server-qr", "version": "1.7.4", @@ -539,6 +794,16 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/quickstart/node_modules/@types/node": { + "version": "22.19.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.5.tgz", + "integrity": "sha512-HfF8+mYcHPcPypui3w3mvzuIErlNOh2OAG+BCeBZCEwyiD5ls2SiCwEyT47OELtf7M3nHxBdu0FsmzdKxkN52Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, "examples/say-server": { "name": "@modelcontextprotocol/server-say", "version": "1.7.4", @@ -580,6 +845,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/scenario-modeler-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/scenario-modeler-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/shadertoy-server": { "name": "@modelcontextprotocol/server-shadertoy", "version": "1.7.4", @@ -607,6 +889,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/shadertoy-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/shadertoy-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/sheet-music-server": { "name": "@modelcontextprotocol/server-sheet-music", "version": "1.7.4", @@ -635,6 +934,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/sheet-music-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/sheet-music-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/system-monitor-server": { "name": "@modelcontextprotocol/server-system-monitor", "version": "1.7.4", @@ -664,6 +980,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/system-monitor-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/system-monitor-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/threejs-server": { "name": "@modelcontextprotocol/server-threejs", "version": "1.7.4", @@ -699,6 +1032,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/threejs-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/threejs-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/transcript-server": { "name": "@modelcontextprotocol/server-transcript", "version": "1.7.4", @@ -727,6 +1077,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/transcript-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/transcript-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/video-resource-server": { "name": "@modelcontextprotocol/server-video-resource", "version": "1.7.4", @@ -755,6 +1122,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/video-resource-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/video-resource-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "examples/wiki-explorer-server": { "name": "@modelcontextprotocol/server-wiki-explorer", "version": "1.7.4", @@ -785,6 +1169,23 @@ "vite-plugin-singlefile": "^2.3.0" } }, + "examples/wiki-explorer-server/node_modules/@types/node": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "examples/wiki-explorer-server/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -1796,9 +2197,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1816,9 +2214,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1836,9 +2231,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1856,9 +2248,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1876,9 +2265,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1896,9 +2282,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1916,9 +2299,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1936,9 +2316,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1956,9 +2333,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1982,9 +2356,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2008,9 +2379,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2034,9 +2402,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2060,9 +2425,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2086,9 +2448,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2112,9 +2471,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2138,9 +2494,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2654,9 +3007,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2677,9 +3027,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2700,9 +3047,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2723,9 +3067,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2746,9 +3087,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3304,9 +3642,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3321,9 +3656,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3338,9 +3670,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3355,9 +3684,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3372,9 +3698,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3389,9 +3712,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3406,9 +3726,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3423,9 +3740,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3440,9 +3754,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3457,9 +3768,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3474,9 +3782,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3491,9 +3796,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3508,9 +3810,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [