From 53712478afb709eff729cb9686ed8aca09ae766e Mon Sep 17 00:00:00 2001 From: Ryan Suhartanto Date: Fri, 14 Nov 2025 18:57:44 +0700 Subject: [PATCH] feat: support latest Zod --- README.md | 12 ++++++------ package-lock.json | 16 ++++++++++++---- package.json | 2 +- src/client/index.test.ts | 2 +- src/client/index.ts | 2 +- .../server/jsonResponseStreamableHttp.ts | 2 +- src/examples/server/mcpServerOutputSchema.ts | 2 +- src/examples/server/simpleSseServer.ts | 2 +- .../server/simpleStatelessStreamableHttp.ts | 2 +- src/examples/server/simpleStreamableHttp.ts | 2 +- .../sseAndStreamableHttpCompatibleServer.ts | 2 +- src/examples/server/toolWithSampleServer.ts | 2 +- .../stateManagementStreamableHttp.test.ts | 2 +- src/integration-tests/taskResumability.test.ts | 2 +- src/server/auth/handlers/authorize.ts | 2 +- src/server/auth/handlers/token.ts | 2 +- src/server/auth/middleware/clientAuth.ts | 2 +- src/server/completable.test.ts | 2 +- src/server/completable.ts | 2 +- src/server/index.test.ts | 2 +- src/server/mcp.test.ts | 2 +- src/server/mcp.ts | 2 +- src/server/sse.test.ts | 2 +- src/server/streamableHttp.test.ts | 2 +- src/server/title.test.ts | 2 +- src/shared/auth.ts | 2 +- src/shared/protocol-transport-handling.test.ts | 2 +- src/shared/protocol.test.ts | 2 +- src/shared/protocol.ts | 2 +- src/types.ts | 2 +- 30 files changed, 46 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 92f56786f..235a93c3d 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Let's create a simple MCP server that exposes a calculator tool and some data. S import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import express from 'express'; -import { z } from 'zod'; +import { z } from 'zod/v3'; // Create an MCP server const server = new McpServer({ @@ -477,7 +477,7 @@ MCP servers can request LLM completions from connected clients that support samp import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import express from 'express'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const mcpServer = new McpServer({ name: 'tools-with-sample-server', @@ -561,7 +561,7 @@ For most use cases where session management isn't needed: import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import express from 'express'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const app = express(); app.use(express.json()); @@ -796,7 +796,7 @@ A simple server demonstrating resources, tools, and prompts: ```typescript import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const server = new McpServer({ name: 'echo-server', @@ -866,7 +866,7 @@ A more complex example showing database integration: import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import sqlite3 from 'sqlite3'; import { promisify } from 'util'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const server = new McpServer({ name: 'sqlite-explorer', @@ -961,7 +961,7 @@ If you want to offer an initial set of tools/prompts/resources, but later add ad import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import express from 'express'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const server = new McpServer({ name: 'Dynamic Example', diff --git a/package-lock.json b/package-lock.json index 8b245aa0c..e7735f78e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", - "zod": "^3.23.8", + "zod": "^3.25.76 || ^4.1.12", "zod-to-json-schema": "^3.24.1" }, "devDependencies": { @@ -103,6 +103,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -2040,6 +2041,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.11.0", "@typescript-eslint/types": "8.11.0", @@ -2367,6 +2369,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2703,6 +2706,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -3336,6 +3340,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", @@ -4527,6 +4532,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -6643,6 +6649,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6901,10 +6908,11 @@ } }, "node_modules/zod": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", - "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", + "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index d8eebaeb9..1f8edd825 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", - "zod": "^3.23.8", + "zod": "^3.25.76 || ^4.1.12", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { diff --git a/src/client/index.test.ts b/src/client/index.test.ts index 912abaac3..c8184416e 100644 --- a/src/client/index.test.ts +++ b/src/client/index.test.ts @@ -2,7 +2,7 @@ /* eslint-disable no-constant-binary-expression */ /* eslint-disable @typescript-eslint/no-unused-expressions */ import { Client } from './index.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { RequestSchema, NotificationSchema, diff --git a/src/client/index.ts b/src/client/index.ts index 5770f9d7f..8b4d7a4ed 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -42,7 +42,7 @@ import { } from '../types.js'; import { AjvJsonSchemaValidator } from '../validation/ajv-provider.js'; import type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator } from '../validation/types.js'; -import { ZodLiteral, ZodObject, z } from 'zod'; +import { ZodLiteral, ZodObject, z } from 'zod/v3'; import type { RequestHandlerExtra } from '../shared/protocol.js'; /** diff --git a/src/examples/server/jsonResponseStreamableHttp.ts b/src/examples/server/jsonResponseStreamableHttp.ts index 8b640777d..57ba3ca9f 100644 --- a/src/examples/server/jsonResponseStreamableHttp.ts +++ b/src/examples/server/jsonResponseStreamableHttp.ts @@ -2,7 +2,7 @@ import express, { Request, Response } from 'express'; import { randomUUID } from 'node:crypto'; import { McpServer } from '../../server/mcp.js'; import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { CallToolResult, isInitializeRequest } from '../../types.js'; import cors from 'cors'; diff --git a/src/examples/server/mcpServerOutputSchema.ts b/src/examples/server/mcpServerOutputSchema.ts index 5d1cab0bd..06b2b81c8 100644 --- a/src/examples/server/mcpServerOutputSchema.ts +++ b/src/examples/server/mcpServerOutputSchema.ts @@ -6,7 +6,7 @@ import { McpServer } from '../../server/mcp.js'; import { StdioServerTransport } from '../../server/stdio.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const server = new McpServer({ name: 'mcp-output-schema-high-level-example', diff --git a/src/examples/server/simpleSseServer.ts b/src/examples/server/simpleSseServer.ts index b99334369..bc72d3fda 100644 --- a/src/examples/server/simpleSseServer.ts +++ b/src/examples/server/simpleSseServer.ts @@ -1,7 +1,7 @@ import express, { Request, Response } from 'express'; import { McpServer } from '../../server/mcp.js'; import { SSEServerTransport } from '../../server/sse.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { CallToolResult } from '../../types.js'; /** diff --git a/src/examples/server/simpleStatelessStreamableHttp.ts b/src/examples/server/simpleStatelessStreamableHttp.ts index f71e5db6c..d5dfcfc52 100644 --- a/src/examples/server/simpleStatelessStreamableHttp.ts +++ b/src/examples/server/simpleStatelessStreamableHttp.ts @@ -1,7 +1,7 @@ import express, { Request, Response } from 'express'; import { McpServer } from '../../server/mcp.js'; import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { CallToolResult, GetPromptResult, ReadResourceResult } from '../../types.js'; import cors from 'cors'; diff --git a/src/examples/server/simpleStreamableHttp.ts b/src/examples/server/simpleStreamableHttp.ts index 6c970bdd1..399318036 100644 --- a/src/examples/server/simpleStreamableHttp.ts +++ b/src/examples/server/simpleStreamableHttp.ts @@ -1,6 +1,6 @@ import express, { Request, Response } from 'express'; import { randomUUID } from 'node:crypto'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { McpServer } from '../../server/mcp.js'; import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js'; import { getOAuthProtectedResourceMetadataUrl, mcpAuthMetadataRouter } from '../../server/auth/router.js'; diff --git a/src/examples/server/sseAndStreamableHttpCompatibleServer.ts b/src/examples/server/sseAndStreamableHttpCompatibleServer.ts index 50e2e5125..b23857cbd 100644 --- a/src/examples/server/sseAndStreamableHttpCompatibleServer.ts +++ b/src/examples/server/sseAndStreamableHttpCompatibleServer.ts @@ -3,7 +3,7 @@ import { randomUUID } from 'node:crypto'; import { McpServer } from '../../server/mcp.js'; import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js'; import { SSEServerTransport } from '../../server/sse.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { CallToolResult, isInitializeRequest } from '../../types.js'; import { InMemoryEventStore } from '../shared/inMemoryEventStore.js'; import cors from 'cors'; diff --git a/src/examples/server/toolWithSampleServer.ts b/src/examples/server/toolWithSampleServer.ts index ad5a01bdc..3d11ec0b1 100644 --- a/src/examples/server/toolWithSampleServer.ts +++ b/src/examples/server/toolWithSampleServer.ts @@ -2,7 +2,7 @@ import { McpServer } from '../../server/mcp.js'; import { StdioServerTransport } from '../../server/stdio.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; const mcpServer = new McpServer({ name: 'tools-with-sample-server', diff --git a/src/integration-tests/stateManagementStreamableHttp.test.ts b/src/integration-tests/stateManagementStreamableHttp.test.ts index 629b01519..1c1ee50fd 100644 --- a/src/integration-tests/stateManagementStreamableHttp.test.ts +++ b/src/integration-tests/stateManagementStreamableHttp.test.ts @@ -12,7 +12,7 @@ import { ListPromptsResultSchema, LATEST_PROTOCOL_VERSION } from '../types.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; describe('Streamable HTTP Transport Session Management', () => { // Function to set up the server with optional session management diff --git a/src/integration-tests/taskResumability.test.ts b/src/integration-tests/taskResumability.test.ts index 224d8e382..f3f6ebec9 100644 --- a/src/integration-tests/taskResumability.test.ts +++ b/src/integration-tests/taskResumability.test.ts @@ -6,7 +6,7 @@ import { StreamableHTTPClientTransport } from '../client/streamableHttp.js'; import { McpServer } from '../server/mcp.js'; import { StreamableHTTPServerTransport } from '../server/streamableHttp.js'; import { CallToolResultSchema, LoggingMessageNotificationSchema } from '../types.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { InMemoryEventStore } from '../examples/shared/inMemoryEventStore.js'; describe('Transport resumability', () => { diff --git a/src/server/auth/handlers/authorize.ts b/src/server/auth/handlers/authorize.ts index ef15770b9..7e52e2f62 100644 --- a/src/server/auth/handlers/authorize.ts +++ b/src/server/auth/handlers/authorize.ts @@ -1,5 +1,5 @@ import { RequestHandler } from 'express'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import express from 'express'; import { OAuthServerProvider } from '../provider.js'; import { rateLimit, Options as RateLimitOptions } from 'express-rate-limit'; diff --git a/src/server/auth/handlers/token.ts b/src/server/auth/handlers/token.ts index c387ff7bf..301051c5f 100644 --- a/src/server/auth/handlers/token.ts +++ b/src/server/auth/handlers/token.ts @@ -1,4 +1,4 @@ -import { z } from 'zod'; +import { z } from 'zod/v3'; import express, { RequestHandler } from 'express'; import { OAuthServerProvider } from '../provider.js'; import cors from 'cors'; diff --git a/src/server/auth/middleware/clientAuth.ts b/src/server/auth/middleware/clientAuth.ts index 9969b8724..f90181321 100644 --- a/src/server/auth/middleware/clientAuth.ts +++ b/src/server/auth/middleware/clientAuth.ts @@ -1,4 +1,4 @@ -import { z } from 'zod'; +import { z } from 'zod/v3'; import { RequestHandler } from 'express'; import { OAuthRegisteredClientsStore } from '../clients.js'; import { OAuthClientInformationFull } from '../../../shared/auth.js'; diff --git a/src/server/completable.test.ts b/src/server/completable.test.ts index b5effc272..4348c36f2 100644 --- a/src/server/completable.test.ts +++ b/src/server/completable.test.ts @@ -1,4 +1,4 @@ -import { z } from 'zod'; +import { z } from 'zod/v3'; import { completable } from './completable.js'; describe('completable', () => { diff --git a/src/server/completable.ts b/src/server/completable.ts index 67d91c383..b831ce6de 100644 --- a/src/server/completable.ts +++ b/src/server/completable.ts @@ -1,4 +1,4 @@ -import { ZodTypeAny, ZodTypeDef, ZodType, ParseInput, ParseReturnType, RawCreateParams, ZodErrorMap, ProcessedCreateParams } from 'zod'; +import { ZodTypeAny, ZodTypeDef, ZodType, ParseInput, ParseReturnType, RawCreateParams, ZodErrorMap, ProcessedCreateParams } from 'zod/v3'; export enum McpZodTypeKind { Completable = 'McpCompletable' diff --git a/src/server/index.test.ts b/src/server/index.test.ts index d2c453931..8e8ae4b9e 100644 --- a/src/server/index.test.ts +++ b/src/server/index.test.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { z } from 'zod'; +import { z } from 'zod/v3'; import { Client } from '../client/index.js'; import { InMemoryTransport } from '../inMemory.js'; import type { Transport } from '../shared/transport.js'; diff --git a/src/server/mcp.test.ts b/src/server/mcp.test.ts index 9bc40f316..5d2798553 100644 --- a/src/server/mcp.test.ts +++ b/src/server/mcp.test.ts @@ -1,4 +1,4 @@ -import { z } from 'zod'; +import { z } from 'zod/v3'; import { Client } from '../client/index.js'; import { InMemoryTransport } from '../inMemory.js'; import { getDisplayName } from '../shared/metadataUtils.js'; diff --git a/src/server/mcp.ts b/src/server/mcp.ts index bee3b76ec..bdf1f7c9e 100644 --- a/src/server/mcp.ts +++ b/src/server/mcp.ts @@ -1,6 +1,6 @@ import { Server, ServerOptions } from './index.js'; import { zodToJsonSchema } from 'zod-to-json-schema'; -import { z, ZodRawShape, ZodObject, ZodString, ZodTypeAny, ZodType, ZodTypeDef, ZodOptional } from 'zod'; +import { z, ZodRawShape, ZodObject, ZodString, ZodTypeAny, ZodType, ZodTypeDef, ZodOptional } from 'zod/v3'; import { Implementation, Tool, diff --git a/src/server/sse.test.ts b/src/server/sse.test.ts index 418094de2..7607610ca 100644 --- a/src/server/sse.test.ts +++ b/src/server/sse.test.ts @@ -4,7 +4,7 @@ import { SSEServerTransport } from './sse.js'; import { McpServer } from './mcp.js'; import { createServer, type Server } from 'node:http'; import { AddressInfo } from 'node:net'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { CallToolResult, JSONRPCMessage } from '../types.js'; const createMockResponse = () => { diff --git a/src/server/streamableHttp.test.ts b/src/server/streamableHttp.test.ts index 824d0f423..a43f5d355 100644 --- a/src/server/streamableHttp.test.ts +++ b/src/server/streamableHttp.test.ts @@ -4,7 +4,7 @@ import { randomUUID } from 'node:crypto'; import { EventStore, StreamableHTTPServerTransport, EventId, StreamId } from './streamableHttp.js'; import { McpServer } from './mcp.js'; import { CallToolResult, JSONRPCMessage } from '../types.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { AuthInfo } from './auth/types.js'; async function getFreePort() { diff --git a/src/server/title.test.ts b/src/server/title.test.ts index 7f0feedc8..de18e9be2 100644 --- a/src/server/title.test.ts +++ b/src/server/title.test.ts @@ -1,7 +1,7 @@ import { Server } from './index.js'; import { Client } from '../client/index.js'; import { InMemoryTransport } from '../inMemory.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; import { McpServer, ResourceTemplate } from './mcp.js'; describe('Title field backwards compatibility', () => { diff --git a/src/shared/auth.ts b/src/shared/auth.ts index 819b33086..0df48e0a5 100644 --- a/src/shared/auth.ts +++ b/src/shared/auth.ts @@ -1,4 +1,4 @@ -import { z } from 'zod'; +import { z } from 'zod/v3'; /** * Reusable URL validation that disallows javascript: scheme diff --git a/src/shared/protocol-transport-handling.test.ts b/src/shared/protocol-transport-handling.test.ts index 375a0ee78..c44553a99 100644 --- a/src/shared/protocol-transport-handling.test.ts +++ b/src/shared/protocol-transport-handling.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test, beforeEach } from '@jest/globals'; import { Protocol } from './protocol.js'; import { Transport } from './transport.js'; import { Request, Notification, Result, JSONRPCMessage } from '../types.js'; -import { z } from 'zod'; +import { z } from 'zod/v3'; // Mock Transport class class MockTransport implements Transport { diff --git a/src/shared/protocol.test.ts b/src/shared/protocol.test.ts index 802c1dd9d..671cc22d0 100644 --- a/src/shared/protocol.test.ts +++ b/src/shared/protocol.test.ts @@ -1,4 +1,4 @@ -import { ZodType, z } from 'zod'; +import { ZodType, z } from 'zod/v3'; import { ClientCapabilities, ErrorCode, McpError, Notification, Request, Result, ServerCapabilities } from '../types.js'; import { Protocol, mergeCapabilities } from './protocol.js'; import { Transport } from './transport.js'; diff --git a/src/shared/protocol.ts b/src/shared/protocol.ts index 48cad896f..b39e76021 100644 --- a/src/shared/protocol.ts +++ b/src/shared/protocol.ts @@ -1,4 +1,4 @@ -import { ZodLiteral, ZodObject, ZodType, z } from 'zod'; +import { ZodLiteral, ZodObject, ZodType, z } from 'zod/v3'; import { CancelledNotificationSchema, ClientCapabilities, diff --git a/src/types.ts b/src/types.ts index 66cc34941..7d52ae2ce 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { z, ZodTypeAny } from 'zod'; +import { z, ZodTypeAny } from 'zod/v3'; import { AuthInfo } from './server/auth/types.js'; export const LATEST_PROTOCOL_VERSION = '2025-06-18';