You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DO NOT MERGE — proof-of-concept port to SDK v2. CI is expected to fail (package.json depends on local file:/tmp/*.tgz SDK builds that combine unpublished typescript-sdk changes).
Review guide — file map, reading order, what to skip (105 files but ~90 are mechanical)
105 files changed, but ~90 of them are mechanical. This guide maps what to read vs skim.
If you have 10 minutes
BREAKING.md — the public-surface delta. This is the contract.
src/app.ts — class App declaration (search for class App extends EventDispatcher). The whole composition pattern is visible in the first ~50 lines of the class body: readonly client: Client, readonly ui: ExtensionHandle<...>, then ui.setRequestHandler(...) calls in the constructor. Note: no zod import — embedded spec types validated via specTypeSchema() from the SDK.
src/app-bridge.ts — same, search for class AppBridge extends EventDispatcher. Note readonly server: Server and the server.setRequestHandler('tools/call', ...) proxy wiring alongside ui.* for ui/* methods.
Skim the test diff: src/app-bridge.test.ts — most of the file is unchanged. That's the point.
File map
Read carefully (~6 files, the actual design)
File
What changed
Why it matters
BREAKING.md
new, 94 lines
The contract. What consumers must change.
src/app.ts
rewrite, ~−1,600 lines net
App composes Client + ExtensionHandle. No assert*Capability overrides. No zod import — specTypeSchema('CallToolResult') etc. passed directly.
src/app-bridge.ts
rewrite, ~−2,000 lines net
AppBridge composes Server + ExtensionHandle. Standard tools/call etc. via setRequestHandler.
src/events.ts
−178 lines
ProtocolWithEvents (subclass of SDK Protocol) → standalone EventDispatcher<EventMap>. No SDK coupling.
src/message-transport.ts
−59 lines
PostMessageTransport on the v2 Transport interface.
src/server/index.ts
−431 lines
registerAppTool/registerAppResource on v2 McpServer.
Skim (mechanical, verify pattern then move on)
Area
Files
What changed
src/spec.types.ts, src/types.ts
2
Import paths v1→v2; interface McpUi*Capabilities → type (for JSONObject constraint).
Per-example: package.json deps, main.ts import path (/stdio subpath), server.ts v2 McpServer shape. Read one (examples/basic-server-react/) to see the pattern.
docs/, scripts/generate-schemas.ts
3
Import paths; generator emits isSpecType() for SDK types.
7. Validator integration (read):c8bc2649 eliminates sdk-compat.ts via isSpecType(); 60e9d690 passes specTypeSchema() directly to ExtensionHandle after #1846's StandardSchemaV1 widen.
Questions to evaluate
Does composition cover what subclassing did? Compare BREAKING.md's "Removed inherited member" table against what consumers actually use.
Is the ui/* ↔ standard-method split clean? In app-bridge.ts, find where ui.setRequestHandler(...) and server.setRequestHandler('tools/call', ...) coexist.
Is specTypeSchema() the right validator API?app.ts passes it directly to ExtensionHandle — no Zod at the consumer. generated/schema.ts uses z.custom(isSpecType()) because that file is Zod-composed.
Wire compat: v2 AppBridge keeps a ui/initialize handler for v1-iframe back-compat. Right choice vs. clean break?
Known gaps (intentional, documented)
npm run test:full includes examples/pdf-server/server.test.ts (~33 fails) — heavy example, deeper port out of scope.
tsconfig.json excludes src/**/*.examples.ts(x) and docs/ — companion JSDoc snippets use removed surface.
18 non-basic example workspaces had import paths sed-fixed but builds untested.
CI is red until SDK deps publish — package.json points at file:/tmp/*.tgz.
App/AppBridge move from subclassing Protocol to composing Client/Server + ExtensionHandle per the SEP-1865 role assignment. See BREAKING.md for the full surface delta. 73/88 of the v1 app-bridge.test.ts tests pass unmodified against the rewrite (final: 85 pass / 1 skip / 0 fail).
How Has This Been Tested?
Locally against an SDK build with the dependencies above: npm run build, npm test (197 pass / 1 skip / 0 fail), and basic-server-react/basic-server-vanillajs/quickstart/basic-host example builds all green. npm run test:full retains the unported examples/pdf-server suite.
Breaking Changes
Yes — see BREAKING.md. Peer dep moves from @modelcontextprotocol/sdk@^1 to @modelcontextprotocol/{client,server}@^2.
Types of changes
Bug fix (non-breaking change which fixes an issue)
New feature (non-breaking change which adds functionality)
Breaking change (fix or feature that would cause existing functionality to change)
This PR is the artifact for reviewing the v2 shape. Once the SDK dependencies publish to @alpha, the file: deps will be swapped to npm versions and CI will go green.
…ssignment)
Preserves all public methods and on* handlers. Removed: 5 assert*Capability
no-op overrides, inherited Protocol surface. Wire renames: notifications/message
-> ui/log; oncalltool/onlisttools now on ui/{call-view-tool,list-view-tools}.
Standard MCP proxying via server.setRequestHandler. ui/initialize handler kept
for v1-iframe wire compat. callTool/listTools wire renamed to ui/{call-view-tool,
list-view-tools}.
…pt-sdk#1846 StandardSchemaV1 widening)
generated/schema.ts keeps z.custom(isSpecType()) since it composes into Zod
chains; specTypeSchema() is used at the ExtensionHandle boundary where the
SDK now accepts StandardSchemaV1. app-bridge event-map params type widened
ZodType -> StandardSchemaV1. app.ts no longer imports zod.
…mappings
- Remove tsconfig excludes for *.examples.ts(x) and docs/ — all now typecheck
- Port companion files to v2 API (app.ui.sendRequest, client.callTool, z.object wraps)
- typedoc externalSymbolLinkMappings for @modelcontextprotocol/{client,server}
- Fix raw-shape inputSchema and Schema.shape→Schema across 9 example servers
- 25/25 examples now build; typedoc warnings 11→0
….registerTool)
All 33 fails fixed: v2 registerTool requires StandardSchema (raw shapes lack
~standard.validate). Also extra.signal→extra.mcpReq.signal, drop stale v1
import. test:full now 277/2/0 (was 197/1/33). e2e API tests pass; browser
tests need playwright install (env, not v2 break).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DO NOT MERGE — proof-of-concept port to SDK v2. CI is expected to fail (
package.jsondepends on localfile:/tmp/*.tgzSDK builds that combine unpublished typescript-sdk changes).Review guide — file map, reading order, what to skip (105 files but ~90 are mechanical)
105 files changed, but ~90 of them are mechanical. This guide maps what to read vs skim.
If you have 10 minutes
BREAKING.md— the public-surface delta. This is the contract.src/app.ts—class Appdeclaration (search forclass App extends EventDispatcher). The whole composition pattern is visible in the first ~50 lines of the class body:readonly client: Client,readonly ui: ExtensionHandle<...>, thenui.setRequestHandler(...)calls in the constructor. Note: nozodimport — embedded spec types validated viaspecTypeSchema()from the SDK.src/app-bridge.ts— same, search forclass AppBridge extends EventDispatcher. Notereadonly server: Serverand theserver.setRequestHandler('tools/call', ...)proxy wiring alongsideui.*forui/*methods.src/app-bridge.test.ts— most of the file is unchanged. That's the point.File map
Read carefully (~6 files, the actual design)
BREAKING.mdsrc/app.tsAppcomposesClient+ExtensionHandle. Noassert*Capabilityoverrides. No zod import —specTypeSchema('CallToolResult')etc. passed directly.src/app-bridge.tsAppBridgecomposesServer+ExtensionHandle. Standardtools/calletc. viasetRequestHandler.src/events.tsProtocolWithEvents(subclass of SDKProtocol) → standaloneEventDispatcher<EventMap>. No SDK coupling.src/message-transport.tsPostMessageTransporton the v2Transportinterface.src/server/index.tsregisterAppTool/registerAppResourceon v2McpServer.Skim (mechanical, verify pattern then move on)
src/spec.types.ts,src/types.tsinterface McpUi*Capabilities→type(forJSONObjectconstraint).src/generated/{schema.ts,schema.json,schema.test.ts}z.custom<T>(isSpecType('T', v))for embedded SDK types. Don't review line-by-line.src/app-bridge.test.tssrc/react/useApp.tsx,src/server/index.test.ts,src/*.examples.tsexamples/**package.jsondeps,main.tsimport path (/stdiosubpath),server.tsv2McpServershape. Read one (examples/basic-server-react/) to see the pattern.docs/,scripts/generate-schemas.tsisSpecType()for SDK types.package.json,build.bun.ts,tsconfig.json, lockfiletsconfigexclusions for unported*.examples.ts.Recommended reading order (by commit)
25 commits, intentionally staged. Read bottom-up in groups:
1. Setup (skim):
231251a6deps swap,b50315b1types/schemas,a9713e3dEventDispatcher + transport.2. The core rewrite (read):
25da6658App,a1f1f016AppBridge,a5378733react/server.3. Compile fixes (skim):
ea3f4af5..a97206ca.4. v1 parity fixes (read commit messages):
87fee346,f7490c6b,47f4cdf3,be67283e— each is a behavior the test suite caught.5. Tests + examples (skim):
7e8ae100,cce8436b,570781e0,9998758b,4298d34a,b845fd7c.6. Upstream-fix follow-through (skim):
953a5d81/4e26407d(#1871),76b3ba7a/stdioimport.7. Validator integration (read):
c8bc2649eliminatessdk-compat.tsviaisSpecType();60e9d690passesspecTypeSchema()directly toExtensionHandleafter #1846's StandardSchemaV1 widen.Questions to evaluate
BREAKING.md's "Removed inherited member" table against what consumers actually use.ui/*↔ standard-method split clean? Inapp-bridge.ts, find whereui.setRequestHandler(...)andserver.setRequestHandler('tools/call', ...)coexist.specTypeSchema()the right validator API?app.tspasses it directly toExtensionHandle— no Zod at the consumer.generated/schema.tsusesz.custom(isSpecType())because that file is Zod-composed.AppBridgekeeps aui/initializehandler for v1-iframe back-compat. Right choice vs. clean break?Known gaps (intentional, documented)
npm run test:fullincludesexamples/pdf-server/server.test.ts(~33 fails) — heavy example, deeper port out of scope.tsconfig.jsonexcludessrc/**/*.examples.ts(x)anddocs/— companion JSDoc snippets use removed surface.package.jsonpoints atfile:/tmp/*.tgz.Depends on:
specTypeSchema()for runtime validation of any spec type)Motivation and Context
App/AppBridgemove from subclassingProtocolto composingClient/Server+ExtensionHandleper the SEP-1865 role assignment. SeeBREAKING.mdfor the full surface delta. 73/88 of the v1app-bridge.test.tstests pass unmodified against the rewrite (final: 85 pass / 1 skip / 0 fail).How Has This Been Tested?
Locally against an SDK build with the dependencies above:
npm run build,npm test(197 pass / 1 skip / 0 fail), andbasic-server-react/basic-server-vanillajs/quickstart/basic-hostexample builds all green.npm run test:fullretains the unportedexamples/pdf-serversuite.Breaking Changes
Yes — see
BREAKING.md. Peer dep moves from@modelcontextprotocol/sdk@^1to@modelcontextprotocol/{client,server}@^2.Types of changes
Checklist
Additional context
This PR is the artifact for reviewing the v2 shape. Once the SDK dependencies publish to
@alpha, thefile:deps will be swapped to npm versions and CI will go green.