Skip to content

Commit d88ef47

Browse files
feat: port to MCP SDK v2 (minimum-diff via compat layer)
Ports ext-apps to @modelcontextprotocol/sdk ^2.0.0-alpha.2 using the v2 backwards-compat layer. Source delta is 4 files +44/-31; the compat layer keeps v1 deep-import paths and the ZodSchema overloads working. Unavoidable changes: - Protocol<X,Y,Z> -> Protocol<ContextT> generic-arity (events.ts) - assertCapability* override params widened to string (app.ts, app-bridge.ts) - registerAppTool callback unifies LegacyToolCallback | ToolCallback to cover both raw-shape and StandardSchema args (server/index.ts) CI will fail until @modelcontextprotocol/sdk@2.0.0-alpha.2 is published; see typescript-sdk milestone v2.0.0-bc. package-lock.json intentionally not updated in this commit.
1 parent 01d826a commit d88ef47

5 files changed

Lines changed: 46 additions & 33 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"author": "Olivier Chafik",
7777
"devDependencies": {
7878
"@boneskull/typedoc-plugin-mermaid": "^0.2.0",
79-
"@modelcontextprotocol/sdk": "^1.29.0",
79+
"@modelcontextprotocol/sdk": "^2.0.0-alpha.2",
8080
"@playwright/test": "1.57.0",
8181
"@types/bun": "^1.3.2",
8282
"@types/node": "20.19.27",
@@ -107,7 +107,7 @@
107107
"zod": "^4.1.13"
108108
},
109109
"peerDependencies": {
110-
"@modelcontextprotocol/sdk": "^1.29.0",
110+
"@modelcontextprotocol/sdk": "^2.0.0-alpha.2",
111111
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
112112
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
113113
"zod": "^3.25.0 || ^4.0.0"

src/app-bridge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,7 @@ export class AppBridge extends ProtocolWithEvents<
13251325
* Verify that the guest supports the capability required for the given request method.
13261326
* @internal
13271327
*/
1328-
assertCapabilityForMethod(method: AppRequest["method"]): void {
1328+
assertCapabilityForMethod(method: string): void {
13291329
// TODO
13301330
}
13311331

@@ -1341,7 +1341,7 @@ export class AppBridge extends ProtocolWithEvents<
13411341
* Verify that the host supports the capability required for the given notification method.
13421342
* @internal
13431343
*/
1344-
assertNotificationCapability(method: AppNotification["method"]): void {
1344+
assertNotificationCapability(method: string): void {
13451345
// TODO
13461346
}
13471347

src/app.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ export class App extends ProtocolWithEvents<
762762
* Verify that the host supports the capability required for the given request method.
763763
* @internal
764764
*/
765-
assertCapabilityForMethod(method: AppRequest["method"]): void {
765+
assertCapabilityForMethod(method: string): void {
766766
// TODO
767767
}
768768

@@ -792,7 +792,7 @@ export class App extends ProtocolWithEvents<
792792
* Verify that the app supports the capability required for the given notification method.
793793
* @internal
794794
*/
795-
assertNotificationCapability(method: AppNotification["method"]): void {
795+
assertNotificationCapability(method: string): void {
796796
// TODO
797797
}
798798

src/events.ts

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import {
33
Request,
44
Notification,
55
Result,
6+
type BaseContext,
7+
type LegacyContextFields,
68
} from "@modelcontextprotocol/sdk/types.js";
9+
10+
type AppContext = BaseContext & LegacyContextFields;
711
import { ZodLiteral, ZodObject } from "zod/v4";
812

913
type MethodSchema = ZodObject<{ method: ZodLiteral<string> }>;
@@ -61,7 +65,10 @@ export abstract class ProtocolWithEvents<
6165
SendNotificationT extends Notification,
6266
SendResultT extends Result,
6367
EventMap extends Record<string, unknown>,
64-
> extends Protocol<SendRequestT, SendNotificationT, SendResultT> {
68+
> extends Protocol<AppContext> {
69+
protected buildContext(ctx: AppContext): AppContext {
70+
return ctx;
71+
}
6572
private _registeredMethods = new Set<string>();
6673
private _eventSlots = new Map<keyof EventMap, EventSlot>();
6774

@@ -209,14 +216,11 @@ export abstract class ProtocolWithEvents<
209216
*
210217
* @throws {Error} if a handler for this method is already registered.
211218
*/
212-
override setRequestHandler: Protocol<
213-
SendRequestT,
214-
SendNotificationT,
215-
SendResultT
216-
>["setRequestHandler"] = (schema, handler) => {
217-
this._assertMethodNotRegistered(schema, "setRequestHandler");
218-
super.setRequestHandler(schema, handler);
219-
};
219+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
220+
override setRequestHandler = ((...args: any) => {
221+
this._assertMethodNotRegistered(args[0], "setRequestHandler");
222+
super.setRequestHandler(...(args as [MethodSchema, () => Result]));
223+
}) as Protocol<AppContext>["setRequestHandler"];
220224

221225
/**
222226
* Registers a notification handler. Throws if a handler for the same
@@ -225,14 +229,11 @@ export abstract class ProtocolWithEvents<
225229
*
226230
* @throws {Error} if a handler for this method is already registered.
227231
*/
228-
override setNotificationHandler: Protocol<
229-
SendRequestT,
230-
SendNotificationT,
231-
SendResultT
232-
>["setNotificationHandler"] = (schema, handler) => {
233-
this._assertMethodNotRegistered(schema, "setNotificationHandler");
234-
super.setNotificationHandler(schema, handler);
235-
};
232+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
233+
override setNotificationHandler = ((...args: any) => {
234+
this._assertMethodNotRegistered(args[0], "setNotificationHandler");
235+
super.setNotificationHandler(...(args as [MethodSchema, () => void]));
236+
}) as Protocol<AppContext>["setNotificationHandler"];
236237

237238
/**
238239
* Warn if a request handler `on*` setter is replacing a previously-set
@@ -255,15 +256,12 @@ export abstract class ProtocolWithEvents<
255256
* Replace a request handler, bypassing double-set protection. Used by
256257
* `on*` request-handler setters that need replace semantics.
257258
*/
258-
protected replaceRequestHandler: Protocol<
259-
SendRequestT,
260-
SendNotificationT,
261-
SendResultT
262-
>["setRequestHandler"] = (schema, handler) => {
263-
const method = (schema as MethodSchema).shape.method.value;
259+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
260+
protected replaceRequestHandler = ((...args: any) => {
261+
const method = (args[0] as MethodSchema).shape.method.value;
264262
this._registeredMethods.add(method);
265-
super.setRequestHandler(schema, handler);
266-
};
263+
super.setRequestHandler(...(args as [MethodSchema, () => Result]));
264+
}) as Protocol<AppContext>["setRequestHandler"];
267265

268266
private _assertMethodNotRegistered(schema: unknown, via: string): void {
269267
const method = (schema as MethodSchema).shape.method.value;

src/server/index.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,27 @@ import {
4141
} from "../app.js";
4242
import type {
4343
BaseToolCallback,
44+
LegacyToolCallback,
4445
McpServer,
4546
RegisteredTool,
4647
ResourceMetadata,
47-
ToolCallback,
48+
ToolCallback as SchemaToolCallback,
4849
ReadResourceCallback as _ReadResourceCallback,
4950
RegisteredResource,
5051
} from "@modelcontextprotocol/sdk/server/mcp.js";
5152
import type {
5253
AnySchema,
5354
ZodRawShapeCompat,
55+
StandardSchemaWithJSON,
5456
} from "@modelcontextprotocol/sdk/server/zod-compat.js";
57+
import type { ZodRawShape } from "@modelcontextprotocol/sdk";
58+
59+
type ToolCallback<Args extends ZodRawShapeCompat | AnySchema | undefined> =
60+
Args extends ZodRawShape
61+
? LegacyToolCallback<Args>
62+
: Args extends StandardSchemaWithJSON
63+
? SchemaToolCallback<Args>
64+
: SchemaToolCallback<undefined>;
5565
import type {
5666
ClientCapabilities,
5767
ReadResourceResult,
@@ -241,7 +251,12 @@ export function registerAppTool<
241251
normalizedMeta = { ...meta, ui: { ...uiMeta, resourceUri: legacyUri } };
242252
}
243253

244-
return server.registerTool(name, { ...config, _meta: normalizedMeta }, cb);
254+
return (server.registerTool as McpServer["registerTool"])(
255+
name,
256+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
257+
{ ...config, _meta: normalizedMeta } as any,
258+
cb as SchemaToolCallback<undefined>,
259+
);
245260
}
246261

247262
export type McpUiReadResourceResult = ReadResourceResult & {

0 commit comments

Comments
 (0)