Skip to content

fix: replace schema-based handlers with string method names - #1446

Merged
mattzcarey merged 7 commits into
mainfrom
feat/set-request-handler
Feb 2, 2026
Merged

fix: replace schema-based handlers with string method names#1446
mattzcarey merged 7 commits into
mainfrom
feat/set-request-handler

Conversation

@mattzcarey

@mattzcareymattzcarey commented Feb 2, 2026

Copy link
Copy Markdown
Contributor

Remove schema imports and update setRequestHandler/setNotificationHandler calls to use string method names directly instead of schema objects. Update type annotations for elicitation content to use explicit union types and add const assertions for action returns.

Motivation and Context

Standardize method names and simplify the API. This brings it inline with the Python SDK and removes complex Zod schema introspection code.

How Has This Been Tested?

All 485 tests pass. Lint and typecheck pass.

Breaking Changes

setRequestHandler and setNotificationHandler API Change

Before:

import{InitializeRequestSchema}from'@modelcontextprotocol/core';server.setRequestHandler(InitializeRequestSchema,(request)=>{// handle initialize});

After:

server.setRequestHandler('initialize',(request)=>{// handle initialize - request is still fully typed});

The method string is now passed directly instead of the Zod schema. Type safety is preserved through RequestTypeMap and NotificationTypeMap.

New Exports

ExportDescription
RequestMethodUnion type of all request method strings
NotificationMethodUnion type of all notification method strings
RequestTypeMapMaps method string → request type
NotificationTypeMapMaps method string → notification type
getRequestSchema()Runtime lookup: method → Zod schema
getNotificationSchema()Runtime lookup: method → Zod schema

Migration

Replace schema-based handler registration:

  • setRequestHandler(InitializeRequestSchema, ...)setRequestHandler('initialize', ...)
  • setRequestHandler(CallToolRequestSchema, ...)setRequestHandler('tools/call', ...)
  • setNotificationHandler(ProgressNotificationSchema, ...)setNotificationHandler('notifications/progress', ...)

The request/notification parameter in your handler remains fully typed.

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)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Remove schema imports and update setRequestHandler/setNotificationHandler calls to use string method names directly instead of schema objects. Update type annotations for elicitation content to use explicit union types and add const assertions for action returns.
@mattzcarey
mattzcarey requested a review from a team as a code ownerFebruary 2, 2026 16:53
@changeset-bot

changeset-botBot commented Feb 2, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: e7bcfc2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-newBot commented Feb 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1446

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1446

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1446

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1446

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1446

commit: 36ac2c2

mattzcareyand others added 4 commits February 2, 2026 17:21
Remove redundant `as unknown as SendResultT` and `as Promise<SendResultT>` type assertions from ping handler and setRequestHandler since TypeScript can infer these types correctly.
Comment threadpackages/client/test/client/sse.test.ts
Comment threadpackages/core/src/shared/protocol.ts
Comment on lines -1404 to +1402
setRequestHandler<T extends AnyObjectSchema>(
requestSchema: T,
setRequestHandler<M extends RequestMethod>(
method: M,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important caveat discussed separately with @mattzcarey - this tightens the possibilities from any request to only requests actually defined on the MCP protocol.

Worth confirming this inadvertent capability wasn't being heavily used elsewhere.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have fallbackRequestHandler for this

Comment threadpackages/core/src/util/zodJsonSchemaCompat.ts
Comment threadpackages/core/test/shared/protocol.test.ts
Comment threadtest/integration/test/client/client.test.ts
Comment threadpackages/server/test/server/stdio.test.ts
Comment threadpackages/core/src/shared/protocol.ts
@mattzcareymattzcarey changed the title fix(client): replace schema-based handlers with string method namesfix: replace schema-based handlers with string method namesFeb 2, 2026
@mattzcarey
mattzcarey enabled auto-merge (squash) February 2, 2026 19:32
return map;
}

const requestSchemas = buildSchemaMap([...ClientRequestSchema.options, ...ServerRequestSchema.options] as const) as Record<

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving a note so we don't forget (here or in a follow up PR):

  • Client and Server support different client request and server request schemas, we should differentiate by that, client.setRequestHandler / server.setRequestHandler) to only allow what is acceptable for them respectively

felixweinberger added a commit that referenced this pull request Feb 2, 2026
…ver, and Client
After the string-based setRequestHandler API (PR #1446), the generic type
parameters <RequestT, NotificationT, ResultT> on Server/Client and
<SendRequestT, SendNotificationT, SendResultT> on Protocol no longer
serve any purpose since custom methods cannot be registered.
This removes them entirely, simplifying:
- Protocol class declaration and all methods
- RequestHandlerExtra type (no longer generic)
- Server and Client class declarations
- ExperimentalServerTasks and ExperimentalClientTasks
- 4 @ts-expect-error comments that were needed to work around the generics
Net -103 lines of type complexity.
@mattzcarey
mattzcarey merged commit f6e8204 into mainFeb 2, 2026
10 of 24 checks passed
@mattzcarey
mattzcarey deleted the feat/set-request-handler branch February 2, 2026 23:57
felixweinberger added a commit that referenced this pull request Feb 3, 2026
…ver, and Client
After the string-based setRequestHandler API (PR #1446), the generic type
parameters <RequestT, NotificationT, ResultT> on Server/Client and
<SendRequestT, SendNotificationT, SendResultT> on Protocol no longer
serve any purpose since custom methods cannot be registered.
This removes them entirely, simplifying:
- Protocol class declaration and all methods
- RequestHandlerExtra type (no longer generic)
- Server and Client class declarations
- ExperimentalServerTasks and ExperimentalClientTasks
- 4 @ts-expect-error comments that were needed to work around the generics
Net -103 lines of type complexity.
felixweinberger added a commit that referenced this pull request Feb 3, 2026
Add RequestMethod, NotificationMethod, RequestTypeMap, NotificationTypeMap,
getRequestSchema, and getNotificationSchema to the curated public API.
These were introduced by the setRequestHandler string-based API change
and are needed by users writing typed handlers or doing custom validation.
felixweinberger added a commit that referenced this pull request Feb 3, 2026
The string-based setRequestHandler API (from #1446) requires methods
to be in the RequestTypeMap. Replace custom test method names
(test/longRunning, test/method, etc.) with 'tools/call' which is a
valid protocol method.
felixweinberger added a commit that referenced this pull request Feb 3, 2026
…ver, and Client
After the string-based setRequestHandler API (PR #1446), the generic type
parameters <RequestT, NotificationT, ResultT> on Server/Client and
<SendRequestT, SendNotificationT, SendResultT> on Protocol no longer
serve any purpose since custom methods cannot be registered.
This removes them entirely, simplifying:
- Protocol class declaration and all methods
- RequestHandlerExtra type (no longer generic)
- Server and Client class declarations
- ExperimentalServerTasks and ExperimentalClientTasks
- 4 @ts-expect-error comments that were needed to work around the generics
Net -103 lines of type complexity.
@KKonstantinovKKonstantinov linked an issue Mar 31, 2026 that may be closed by this pull request
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decouple from Zod, allow any validator (bring your own)

3 participants

@mattzcarey@KKonstantinov@felixweinberger