Skip to content

v2: setRequestHandler/setNotificationHandler require a method-string literal — re-accept the schema object (or export typed method tokens) #2505

Description

@cliffhall

Summary

In v2, Protocol.setRequestHandler / setNotificationHandler require a method-string literal as the first argument and no longer accept the request/notification Zod schema object (the v1 API). Two consequences motivated this request while migrating a client:

  1. v1-peer libraries break at runtime with a confusing error. Any library still on the v1 peer that calls client.setNotificationHandler(SomeNotificationSchema, handler) now throws:

    '[object Object]' is not a spec notification method; pass schemas as the second argument to setNotificationHandler()
    

    The schema stringifies to [object Object], so the message is hard to act on, and it fails at connect time rather than at build time.

  2. Callers must hardcode magic string literals. setRequestHandler('tools/list', …) / setNotificationHandler('notifications/tools/list_changed', …) scatter bare method strings through app code instead of referencing a typed value.

Context

Found migrating the MCP Inspector to @modelcontextprotocol/client@2.0.0-beta.4. The Inspector renders MCP Apps via @modelcontextprotocol/ext-apps, which still peers on the v1 SDK and subscribes to tools/resources/prompts *_changed notifications with the schema-first API. Under v2 that throws the error above during the AppBridge connect handshake, so apps fail to load. We worked around it with a client-side proxy that reads the method literal off the schema's shape.method.value and forwards the method string — but that's exactly the translation the SDK is well-positioned to provide.

The *RequestSchema / *NotificationSchema objects still exist and still carry the method literal, so the method is derivable from the schema.

Proposals (either would help)

A. Re-accept the schema object as an overload, deriving the method from schema.shape.method:

setNotificationHandler(ToolListChangedNotificationSchema, handler) // v1-style, typed, no magic string
setNotificationHandler('notifications/tools/list_changed', handler) // still supported

This also restores backward-compat for v1-peer libraries, so nothing breaks at runtime.

B. Export typed method tokens/constants (e.g. a RequestMethods / NotificationMethods map) so callers reference a named value instead of a bare literal, keeping the method-string design but removing hardcoded strings.

At minimum, if the schema-first form stays unsupported, the thrown error could name the received schema's method (from shape.method.value) and suggest the string to pass — it would have turned a head-scratch into a one-line fix.

Versions

  • @modelcontextprotocol/client / core: 2.0.0-beta.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions