Skip to content

Zod version compatibility issue with MCP SDK #906

Closed

Description

@developermau

While, I am builidng a custom MCP server about fetching data from Disney API. I have this error: keyValidator.parse is not a function.

Cursor found out a Zod version compatibility issue with MCP SDK:

There's a version conflict:

  • Your project has Zod 4.1.4 installed
  • But the MCP SDK is using Zod 3.25.76 internally
  • This version mismatch is causing the keyValidator._parse is not a function error

The solution is to downgrade your Zod version to be compatible with the MCP SDK. But the latest version of Zod is 4.1.5.

Please, if it is possible, you might give support to the latest of version of Zod. Or maybe, there is a best way to solve this kind of issues.

I would appreciate your help. Have a nice day!

Activity

  1. orlov-vo commented on Aug 30, 2025

    @orlov-vo

    Agreed! As temporary workaround you can use old version of zod in mcp declarations, just add it to package.json and install packages:

    "mcp-zod": "npm:zod@3.25.76"

    and use it in your declarations:

    // import { z } from "zod";
    import { z as mcpZod } from "mcp-zod";
    const z = mcpZod as unknown as typeof import("zod").z;
    
    mcpServer.registerTool(
      "roll_dice",
      {
        description: "Rolls an N-sided die",
        inputSchema: {
          sides: z.number().int().min(2).describe("The number of sides on the die"),
        },
      },
      async ({ sides }) => {
        const value = 1 + Math.floor(Math.random() * sides);
        return {
          content: [{ type: "text", text: `🎲 You rolled a ${value}!` }],
        };
      },
    );
  2. Karljoy973 commented on Aug 31, 2025

    @Karljoy973

    Im not sure they allow the use of zod 4 as it might create some breaking changes.

  3. tmkn commented on Sep 1, 2025

    @tmkn

    @developermau you can import Zod 3 via import { z } from "zod/v3"; from a Zod 4 version

  4. developermau commented on Sep 2, 2025

    @developermau
    Author

    @developermau you can import Zod 3 via import { z } from "zod/v3"; from a Zod 4 version

    Thanks @tmkn ! I tried it (import { z } from "zod/v3";). However, I have another error: Type instantiation is excessively deep and possibly infinite..

    "dependencies": {
        "@modelcontextprotocol/sdk": "^1.17.4",
        "zod": "^4.1.5"
      },

    Part of the code:

    import { z } from "zod/v3";
    // More code
    
    server.tool(
      "filter_character_by_name",
      "Filter a specific character using the character?params endpoint.",
      {
        name: z.string().describe("Character name"),
      },
      async (args) => {
        // 68 lines of code 👀
      }
    );
  5. developermau commented on Sep 2, 2025

    @developermau
    Author

    Agreed! As temporary workaround you can use old version of zod in mcp declarations, just add it to package.json and install packages:

    "mcp-zod": "npm:zod@3.25.76"
    and use it in your declarations:

    // import { z } from "zod";
    import { z as mcpZod } from "mcp-zod";
    const z = mcpZod as unknown as typeof import("zod").z;

    mcpServer.registerTool(
    "roll_dice",
    {
    description: "Rolls an N-sided die",
    inputSchema: {
    sides: z.number().int().min(2).describe("The number of sides on the die"),
    },
    },
    async ({ sides }) => {
    const value = 1 + Math.floor(Math.random() * sides);
    return {
    content: [{ type: "text", text: 🎲 You rolled a ${value}! }],
    };
    },
    );

    Thanks @orlov-vo ! It works!

    "dependencies": {
        "mcp-zod": "npm:zod@3.25.76",
        "@modelcontextprotocol/sdk": "^1.17.4",
        "zod": "^4.1.5"
      },

    Part of the code:

    import { z as mcpZod } from "mcp-zod";
    const z = mcpZod as unknown as typeof import("zod").z;
    
    // More code
    
    server.tool(
      "filter_character_by_name",
      "Filter a specific character using the character?params endpoint.",
      {
        name: z.string().describe("Character name"),
      },
      async (args) => {
        // More code
      }
    );
  6. justin-schroeder commented on Sep 4, 2025

    @justin-schroeder

    I just released this to help this exact problem: https://zodown.com/

    const v3schema = zodown(v4schema)
    
  7. colinhacks commented on Sep 11, 2025

    @colinhacks

    To the maintainers: if you haven't already, I recommend checking out the Library Authors guide for best practices around peer dependencies and accepting user-defined schemas: https://zod.dev/library-authors

  8. tmkn commented on Sep 12, 2025

    @tmkn

    @colinhacks can confirm, with the latest zod version, the Type instantiation is excessively deep and possibly infinite. error is gone

  9. gkurt commented on Sep 16, 2025

    @gkurt

    I noticed this library is importing from zod. Until v4 schemas are fully supported, can you at least import from zod/v3 so that people can install v3 or v4 in their own project if they want.

  10. Crustan commented on Oct 2, 2025

    @Crustan

    How did you guys get this to work? I'm still getting Type instantiation is excessively deep and possibly infinite.

    I'm using:

    "@modelcontextprotocol/sdk": "^1.18.2",
    "zod": "^4.1.11"
    

    I'm setting up my server like this:

    import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
    import * as z from 'zod/v3';
    
    const server = new McpServer(mcpServerOptions.serverInfo);
    server.tool(
      "tool_name",
      "tool_description",
      { text: z.string().describe('text_description') },
      async (args) => { /* executefunction */ }  
    );
    

    I have tried changing that 3rd parameter to:

    • z.object({ text: z.string().describe('text_description') }) -> No overload matches this call. ... Argument of type 'string' is not assignable to parameter of type 'ZodRawShape'.

    • zodown(z.object({ text: z.string().describe('text_description') })) (with zodown installed) -> same

    • z.object({ text: z.string().describe('text_description') }).shape -> Type instantiation is excessively deep and possibly infinite.

    • z.toJSONSchema(z.object({ text: z.string().describe('text_description') })) (with zod 4) -> gives no TS error but input schema becomes empty and request body isn't passed to the tool.

    I have tried changing zod import, and even tried to installing zod v3 separately with npm install mcp-zod@npm:zod@3.23.8:

    import * as z from 'zod';
    import * as z from 'zod/v3';
    import { z } from 'zod/v3';
    
    import import { z as mcpZod } from "mcp-zod";
    

    Nothing works. Do you have any suggestions except downgrading zod completely?

  11. luisvinicius09 commented on Oct 9, 2025

    @luisvinicius09

    I've also done everything mentioned by Crustan above and could not get it working.

    Any help would be great.

  12. codeXLinkX commented on Oct 22, 2025

    @codeXLinkX

    Hey MCP team! Is there an update regarding the zod v4 support?

  13. felixweinberger commented on Nov 21, 2025

    @felixweinberger
    Contributor

    Hi! we just shipped a beta release adding backwards compatible support for zod v4 - if you'd like to try it we're keen for feedback to make sure this works well!

  14. josealvarez97 commented on Dec 21, 2025

    @josealvarez97

    Does the latest version on NPM (1.25.1) support zod v4? @felixweinberger

    Hi! we just shipped a beta release adding backwards compatible support for zod v4 - if you'd like to try it we're keen for feedback to make sure this works well!

  15. remigermain commented on Jun 17, 2026

    @remigermain

    if someone have the probleme (from 1.29) , you can change type in mcpServer definition:

    import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp'
    
    type Schema = {
      [key: string]: any
    }
    
    export type TypeMcpServer = Omit<McpServer, 'registerTool'> & {
      registerTool: (
        name: string,
        config: Omit<
          Parameters<McpServer['registerTool']>[1],
          'inputSchema' | 'outputSchema'
        > & {
          inputSchema?: Schema
          outputSchema?: Schema
        },
        cb: Parameters<McpServer['registerTool']>[2]
      ) => ReturnType<McpServer['registerTool']>
    }
    ~``
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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