Migration guide fixes and editor-visible deprecation for the 1.x handler form

Guide: name @modelcontextprotocol/express in the server-author row, say
the two SDKs share no types rather than "do not interoperate" (they speak
the same wire protocol), note zod 4.0/4.1 lack ~standard.jsonSchema, list
the full 1.x-shaped extra, cover tool callbacks in the handler-context
bullet, document that the double-registration guard now covers the base
Protocol's notifications/progress and notifications/cancelled handlers,
mention ResourceNotFoundError, add the Express row to the import map, and
add a "What stays the same" section.

The @deprecated tag on the legacy setRequestHandler / setNotificationHandler
overload sat on the parameter inside an intersection type, which TypeScript
does not report. The overload now comes from LegacyRequestHandlerSetter /
LegacyNotificationHandlerSetter, named types with a documented call
signature, so editors flag the 1.x call and not the 2.x forms.

README links to the quickstart use the lowercase slug typedoc emits.
This commit is contained in:
Olivier Chafik 2026-09-08 18:01:18 +01:00
commit 853c9f749c
3 changed files with 87 additions and 49 deletions

View file

@ -37,9 +37,8 @@ import {
import { EventDispatcher, MethodRegistry } from "./events.js";
import {
toModernArgs,
type LegacyMethodSchema,
type LegacyNotificationHandler,
type LegacyRequestHandler,
type LegacyNotificationHandlerSetter,
type LegacyRequestHandlerSetter,
} from "./legacy-handlers.js";
import type { ZodLiteral, ZodObject, ZodType } from "zod/v4";
@ -330,12 +329,9 @@ export class AppBridge extends Protocol<BaseContext> {
*
* @throws {Error} if a handler for this method is already registered.
*/
override setRequestHandler: Protocol<BaseContext>["setRequestHandler"] &
(<S extends LegacyMethodSchema>(
/** @deprecated Pass the method name and `{ params }` instead. */
schema: S,
handler: LegacyRequestHandler<S>,
) => void) = (...args: unknown[]) => {
override setRequestHandler: LegacyRequestHandlerSetter<
Protocol<BaseContext>["setRequestHandler"]
> = (...args: unknown[]) => {
const [method, ...rest] = toModernArgs("request", args) ?? args;
this._methods.claim(method as string, "setRequestHandler");
(super.setRequestHandler as unknown as UntypedHandlerSetter).call(
@ -352,12 +348,9 @@ export class AppBridge extends Protocol<BaseContext> {
*
* @throws {Error} if a handler for this method is already registered.
*/
override setNotificationHandler: Protocol<BaseContext>["setNotificationHandler"] &
(<S extends LegacyMethodSchema>(
/** @deprecated Pass the method name and `{ params }` instead. */
schema: S,
handler: LegacyNotificationHandler<S>,
) => void) = (...args: unknown[]) => {
override setNotificationHandler: LegacyNotificationHandlerSetter<
Protocol<BaseContext>["setNotificationHandler"]
> = (...args: unknown[]) => {
const [method, ...rest] = toModernArgs("notification", args) ?? args;
this._methods.claim(method as string, "setNotificationHandler");
(super.setNotificationHandler as unknown as UntypedHandlerSetter).call(

View file

@ -26,15 +26,16 @@ export { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "./constants.js";
import { EventDispatcher, MethodRegistry } from "./events.js";
import {
toModernArgs,
type LegacyMethodSchema,
type LegacyNotificationHandler,
type LegacyRequestHandler,
type LegacyNotificationHandlerSetter,
type LegacyRequestHandlerSetter,
} from "./legacy-handlers.js";
export type {
LegacyMethodSchema,
LegacyNotificationHandler,
LegacyNotificationHandlerSetter,
LegacyRequestHandler,
LegacyRequestHandlerExtra,
LegacyRequestHandlerSetter,
} from "./legacy-handlers.js";
export { EventDispatcher } from "./events.js";
@ -328,12 +329,9 @@ export class App extends Protocol<BaseContext> {
*
* @throws {Error} if a handler for this method is already registered.
*/
override setRequestHandler: Protocol<BaseContext>["setRequestHandler"] &
(<S extends LegacyMethodSchema>(
/** @deprecated Pass the method name and `{ params }` instead. */
schema: S,
handler: LegacyRequestHandler<S>,
) => void) = (...args: unknown[]) => {
override setRequestHandler: LegacyRequestHandlerSetter<
Protocol<BaseContext>["setRequestHandler"]
> = (...args: unknown[]) => {
const [method, ...rest] = toModernArgs("request", args) ?? args;
this._methods.claim(method as string, "setRequestHandler");
(super.setRequestHandler as unknown as UntypedHandlerSetter).call(
@ -350,12 +348,9 @@ export class App extends Protocol<BaseContext> {
*
* @throws {Error} if a handler for this method is already registered.
*/
override setNotificationHandler: Protocol<BaseContext>["setNotificationHandler"] &
(<S extends LegacyMethodSchema>(
/** @deprecated Pass the method name and `{ params }` instead. */
schema: S,
handler: LegacyNotificationHandler<S>,
) => void) = (...args: unknown[]) => {
override setNotificationHandler: LegacyNotificationHandlerSetter<
Protocol<BaseContext>["setNotificationHandler"]
> = (...args: unknown[]) => {
const [method, ...rest] = toModernArgs("notification", args) ?? args;
this._methods.claim(method as string, "setNotificationHandler");
(super.setNotificationHandler as unknown as UntypedHandlerSetter).call(

View file

@ -36,6 +36,33 @@ export type LegacyNotificationHandler<S extends LegacyMethodSchema> = (
notification: S["_output"],
) => void | Promise<void>;
/**
* `setRequestHandler` with the 1.x `(Schema, handler)` form kept as a
* deprecated overload next to the 2.x forms in `Modern`.
*/
export type LegacyRequestHandlerSetter<Modern> = Modern & {
/**
* @deprecated 1.x form. Pass the method name and `{ params }` instead;
* removed in 3.0.
*/
<S extends LegacyMethodSchema>(
schema: S,
handler: LegacyRequestHandler<S>,
): void;
};
/** `setNotificationHandler` counterpart of {@link LegacyRequestHandlerSetter}. */
export type LegacyNotificationHandlerSetter<Modern> = Modern & {
/**
* @deprecated 1.x form. Pass the method name and `{ params }` instead;
* removed in 3.0.
*/
<S extends LegacyMethodSchema>(
schema: S,
handler: LegacyNotificationHandler<S>,
): void;
};
/**
* Arguments for the 2.x three-argument `setRequestHandler` /
* `setNotificationHandler` form.