Skip to content

fix(schema): add method-aware deserialization for routing enums - #2741

Open
nikhillakra2007-tech wants to merge 2 commits into
agentclientprotocol:mainfrom
nikhillakra2007-tech:fix/method-aware-enum-deserialize
Open

nikhillakra2007-tech wants to merge 2 commits into
agentclientprotocol:mainfrom
nikhillakra2007-tech:fix/method-aware-enum-deserialize

Conversation

@nikhillakra2007-tech

@nikhillakra2007-tech nikhillakra2007-tech commented Oct 31, 2026 •

Copy link
Copy Markdown

The schema crate's aggregated routing enums derive untagged Deserialize, which selects variants by payload shape rather than the JSON-RPC method.

I reproduced a session/new request parsing successfully as LogoutRequest, silently dropping cwd and mcpServers. A session/new response can similarly parse as AuthenticateResponse and lose sessionId.

This adds method-aware parsing helpers for the v1 and v2 routing enums:

  • from_method_and_params for requests and notifications
  • from_method_and_result for responses, using the originating request's method
  • explicit errors for unknown methods and invalid payloads
  • preservation of extension payloads

The existing Deserialize implementations remain unchanged for compatibility, with warnings pointing callers to the new helpers. The official SDK already dispatches by method; this proposal is for consumers using the schema crate directly.

Validation:

  • Default and all-features test suites pass
  • 20 dispatch tests with all features enabled
  • Clippy, formatting and rustdoc checks pass

I'd appreciate feedback on whether these helpers belong in the schema crate and whether this API shape fits the project. Happy to narrow the scope if preferred.

Follow-up commit regenerates the four JSON schema files affected by the new doc comments. npm run generate was rerun after committing and left the working tree clean; npm run format:check passed. GitHub CI has not run yet.

The protocol's aggregated enums (ClientRequest, AgentRequest,
ClientResponse, AgentResponse, ClientNotification, AgentNotification,
ProtocolLevelNotification, and their v2 counterparts) derive Deserialize
as #[serde(untagged)] for JSON Schema generation. serde tries untagged
variants in declaration order, so a variant whose fields are all
optional (e.g. LogoutRequest, ListProvidersRequest) silently matches
every payload: parsing a session/new request through
JsonRpcMessage<Request<ClientRequest>> succeeded and returned
LogoutRequest with an empty payload, dropping cwd and mcpServers
without any error. The crate docs describe these enums as the routing
types used to dispatch incoming JSON-RPC messages, so the only obvious
parse API corrupted requests and responses silently.

Add ClientRequest::from_method_and_params and the matching helpers on
every routing enum (from_method_and_params for requests and
notifications, from_method_and_result for responses). They dispatch on
the JSON-RPC method name first and then deserialize the payload into
the matching variant, so unknown non-extension methods fail with
MethodDispatchError::UnknownMethod, mismatched payloads fail with
MethodDispatchError::InvalidPayload, and _-prefixed extension methods
route to the Ext variants with their raw payload preserved. The derived
implementations are kept for schema generation, with doc warnings on
each enum pointing at the safe entrypoints.
@nikhillakra2007-tech
nikhillakra2007-tech requested a review from a team as a code owner October 31, 2026 12:15

This branch has not been deployed

No deployments
Sign up for free to 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.

1 participant