Skip to content

Add backwards compatibility with 2024-10-07 #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 26 additions & 23 deletions src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
import { ProgressCallback, Protocol } from "../shared/protocol.js";
import { Transport } from "../shared/transport.js";
import {
CallToolRequest,
CallToolResultSchema,
ClientNotification,
ClientRequest,
ClientResult,
Implementation,
InitializeResultSchema,
Notification,
PROTOCOL_VERSION,
Request,
Result,
ServerCapabilities,
CompatibilityCallToolResultSchema,
CompleteRequest,
GetPromptRequest,
ListPromptsRequest,
ListResourcesRequest,
ReadResourceRequest,
SubscribeRequest,
UnsubscribeRequest,
CallToolRequest,
ListToolsRequest,
CompleteResultSchema,
EmptyResultSchema,
GetPromptRequest,
GetPromptResultSchema,
Implementation,
InitializeResultSchema,
LATEST_PROTOCOL_VERSION,
ListPromptsRequest,
ListPromptsResultSchema,
ListResourcesRequest,
ListResourcesResultSchema,
ReadResourceResultSchema,
CallToolResultSchema,
ListToolsResultSchema,
EmptyResultSchema,
LoggingLevel,
ListResourceTemplatesRequest,
ListResourceTemplatesResultSchema,
ListToolsRequest,
ListToolsResultSchema,
LoggingLevel,
Notification,
ReadResourceRequest,
ReadResourceResultSchema,
Request,
Result,
ServerCapabilities,
SubscribeRequest,
SUPPORTED_PROTOCOL_VERSIONS,
UnsubscribeRequest
} from "../types.js";

/**
Expand Down Expand Up @@ -84,7 +86,7 @@ export class Client<
{
method: "initialize",
params: {
protocolVersion: PROTOCOL_VERSION,
protocolVersion: LATEST_PROTOCOL_VERSION,
capabilities: {},
clientInfo: this._clientInfo,
},
Expand All @@ -96,7 +98,7 @@ export class Client<
throw new Error(`Server sent invalid initialize result: ${result}`);
}

if (result.protocolVersion !== PROTOCOL_VERSION) {
if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) {
throw new Error(
`Server's protocol version is not supported: ${result.protocolVersion}`,
);
Expand Down Expand Up @@ -217,11 +219,12 @@ export class Client<

async callTool(
params: CallToolRequest["params"],
resultSchema: typeof CallToolResultSchema | typeof CompatibilityCallToolResultSchema = CallToolResultSchema,
onprogress?: ProgressCallback,
) {
return this.request(
{ method: "tools/call", params },
CallToolResultSchema,
resultSchema,
onprogress,
);
}
Expand Down
33 changes: 15 additions & 18 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import { ProgressCallback, Protocol } from "../shared/protocol.js";
import {
ClientCapabilities,
CreateMessageRequest,
CreateMessageResultSchema,
EmptyResultSchema,
Implementation,
InitializedNotificationSchema,
InitializeRequest,
InitializeRequestSchema,
InitializeResult,
LATEST_PROTOCOL_VERSION,
ListPromptsRequestSchema,
ListResourcesRequestSchema,
ListRootsRequest,
ListRootsResultSchema,
ListToolsRequestSchema,
LoggingMessageNotification,
Notification,
PROTOCOL_VERSION,
Request,
ResourceUpdatedNotification,
Result,
ServerCapabilities,
ServerNotification,
ServerRequest,
ServerResult,
ServerCapabilities,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ListPromptsRequestSchema,
SetLevelRequestSchema,
CreateMessageRequest,
CreateMessageResultSchema,
EmptyResultSchema,
LoggingMessageNotification,
ResourceUpdatedNotification,
ListRootsRequest,
ListRootsResultSchema,
SUPPORTED_PROTOCOL_VERSIONS
} from "../types.js";

/**
Expand Down Expand Up @@ -86,17 +87,13 @@ export class Server<
private async _oninitialize(
request: InitializeRequest,
): Promise<InitializeResult> {
if (request.params.protocolVersion !== PROTOCOL_VERSION) {
throw new Error(
`Client's protocol version is not supported: ${request.params.protocolVersion}`,
);
}
const requestedVersion = request.params.protocolVersion;

this._clientCapabilities = request.params.capabilities;
this._clientVersion = request.params.clientInfo;

return {
protocolVersion: PROTOCOL_VERSION,
protocolVersion: SUPPORTED_PROTOCOL_VERSIONS.includes(requestedVersion) ? requestedVersion : LATEST_PROTOCOL_VERSION,
capabilities: this.getCapabilities(),
serverInfo: this._serverInfo,
};
Expand Down
4 changes: 2 additions & 2 deletions src/shared/protocol.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnyZodObject, ZodLiteral, ZodObject, z } from "zod";
import { ZodLiteral, ZodObject, ZodType, z } from "zod";
import {
ErrorCode,
JSONRPCError,
Expand Down Expand Up @@ -250,7 +250,7 @@ export class Protocol<
*
* Do not use this method to emit notifications! Use notification() instead.
*/
request<T extends AnyZodObject>(
request<T extends ZodType<object>>(
request: SendRequestT,
resultSchema: T,
onprogress?: ProgressCallback,
Expand Down
16 changes: 13 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from "zod";

export const PROTOCOL_VERSION = "2024-11-05";
export const LATEST_PROTOCOL_VERSION = "2024-11-05";
export const SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2024-10-07"];

/* JSON-RPC types */
export const JSONRPC_VERSION = "2.0";
Expand Down Expand Up @@ -196,7 +197,7 @@ export const InitializeRequestSchema = RequestSchema.extend({
/**
* The latest version of the Model Context Protocol that the client supports. The client MAY decide to support older versions as well.
*/
protocolVersion: z.string().or(z.number().int()),
protocolVersion: z.string(),
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know of any client or server sending numbers anymore, so bringing this into spec compliance.

capabilities: ClientCapabilitiesSchema,
clientInfo: ImplementationSchema,
}),
Expand Down Expand Up @@ -268,7 +269,7 @@ export const InitializeResultSchema = ResultSchema.extend({
/**
* The version of the Model Context Protocol that the server wants to use. This may not match the version that the client requested. If the client cannot support this version, it MUST disconnect.
*/
protocolVersion: z.string().or(z.number().int()),
protocolVersion: z.string(),
capabilities: ServerCapabilitiesSchema,
serverInfo: ImplementationSchema,
});
Expand Down Expand Up @@ -721,6 +722,13 @@ export const CallToolResultSchema = ResultSchema.extend({
isError: z.boolean(),
});

/**
* CallToolResultSchema extended with backwards compatibility to protocol version 2024-10-07.
*/
export const CompatibilityCallToolResultSchema = CallToolResultSchema.or(ResultSchema.extend({
toolResult: z.unknown(),
}));

/**
* Used by the client to invoke a tool provided by the server.
*/
Expand Down Expand Up @@ -1053,6 +1061,7 @@ export const ServerResultSchema = z.union([
ListResourceTemplatesResultSchema,
ReadResourceResultSchema,
CallToolResultSchema,
CompatibilityCallToolResultSchema,
ListToolsResultSchema,
]);

Expand Down Expand Up @@ -1147,6 +1156,7 @@ export type Tool = z.infer<typeof ToolSchema>;
export type ListToolsRequest = z.infer<typeof ListToolsRequestSchema>;
export type ListToolsResult = z.infer<typeof ListToolsResultSchema>;
export type CallToolResult = z.infer<typeof CallToolResultSchema>;
export type CompatibilityCallToolResult = z.infer<typeof CompatibilityCallToolResultSchema>;
export type CallToolRequest = z.infer<typeof CallToolRequestSchema>;
export type ToolListChangedNotification = z.infer<
typeof ToolListChangedNotificationSchema
Expand Down