From 82156515523402bd230d54ef6682762922711e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Barthelet?= Date: Mon, 7 Apr 2025 18:24:50 +0200 Subject: [PATCH 1/2] Add helper functions to distinguish between jsonRPC message types --- src/shared/protocol.ts | 13 +++++++++---- src/types.ts | 11 +++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/shared/protocol.ts b/src/shared/protocol.ts index b072e578..19ff97d3 100644 --- a/src/shared/protocol.ts +++ b/src/shared/protocol.ts @@ -3,6 +3,9 @@ import { CancelledNotificationSchema, ClientCapabilities, ErrorCode, + isJSONRPCRequest, + isJSONRPCResponse, + isJSONRPCNotification, JSONRPCError, JSONRPCNotification, JSONRPCRequest, @@ -271,12 +274,14 @@ export abstract class Protocol< }; this._transport.onmessage = (message) => { - if (!("method" in message)) { + if (isJSONRPCResponse(message)) { this._onresponse(message); - } else if ("id" in message) { + } else if (isJSONRPCRequest(message)) { this._onrequest(message); - } else { + } else if (isJSONRPCNotification(message)) { this._onnotification(message); + } else { + this._onerror(new Error(`Unknown message type: ${JSON.stringify(message)}`)); } }; @@ -437,7 +442,7 @@ export abstract class Protocol< this._progressHandlers.delete(messageId); this._cleanupTimeout(messageId); - if ("result" in response) { + if (isJSONRPCResponse(response)) { handler(response); } else { const error = new McpError( diff --git a/src/types.ts b/src/types.ts index da4afd2a..a68c3ff1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -78,6 +78,9 @@ export const JSONRPCRequestSchema = z .merge(RequestSchema) .strict(); +export const isJSONRPCRequest = (value: unknown): value is JSONRPCRequest => + JSONRPCRequestSchema.safeParse(value).success; + /** * A notification which does not expect a response. */ @@ -88,6 +91,11 @@ export const JSONRPCNotificationSchema = z .merge(NotificationSchema) .strict(); +export const isJSONRPCNotification = ( + value: unknown +): value is JSONRPCNotification => + JSONRPCNotificationSchema.safeParse(value).success; + /** * A successful (non-error) response to a request. */ @@ -99,6 +107,9 @@ export const JSONRPCResponseSchema = z }) .strict(); +export const isJSONRPCResponse = (value: unknown): value is JSONRPCResponse => + JSONRPCResponseSchema.safeParse(value).success; + /** * Error codes defined by the JSON-RPC specification. */ From 4e749dba4de93020f860c713492eb8b6872da746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Barthelet?= Date: Thu, 10 Apr 2025 00:06:07 +0200 Subject: [PATCH 2/2] Add isJSONRPCError method --- src/shared/protocol.ts | 3 ++- src/types.ts | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/shared/protocol.ts b/src/shared/protocol.ts index 19ff97d3..07bfc02c 100644 --- a/src/shared/protocol.ts +++ b/src/shared/protocol.ts @@ -3,6 +3,7 @@ import { CancelledNotificationSchema, ClientCapabilities, ErrorCode, + isJSONRPCError, isJSONRPCRequest, isJSONRPCResponse, isJSONRPCNotification, @@ -274,7 +275,7 @@ export abstract class Protocol< }; this._transport.onmessage = (message) => { - if (isJSONRPCResponse(message)) { + if (isJSONRPCResponse(message) || isJSONRPCError(message)) { this._onresponse(message); } else if (isJSONRPCRequest(message)) { this._onrequest(message); diff --git a/src/types.ts b/src/types.ts index a68c3ff1..db6bf125 100644 --- a/src/types.ts +++ b/src/types.ts @@ -150,6 +150,9 @@ export const JSONRPCErrorSchema = z }) .strict(); +export const isJSONRPCError = (value: unknown): value is JSONRPCError => + JSONRPCErrorSchema.safeParse(value).success; + export const JSONRPCMessageSchema = z.union([ JSONRPCRequestSchema, JSONRPCNotificationSchema,