modelcontextprotocol / modelcontextprotocol/typescript-sdk

ListTools request handler fails to generate inputSchema (jsonSchema)

Open
#1,028 7 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

  • #869 by @dclark27 — closed without merging
bug P1 potentially close ready for work
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

Describe the bug

When a tool - either with or without an input schema - is registered onto the mcp server, it gets registered correctly with its input schema being a ZodObject ({type: 'object', shape: <accessor>}), the server starts and the MCP inspector is able to connect to it.
When a list tools request is sent from the mcp inspector, all toolDefinitions are generated, converting the existing tool inputSchema (Zod) into a jsonSchema. However, despite the shape and type of the zod input schema, the zodToJsonSchema function always returns {type: "string", $schema: "http://json-schema.org/draft-07/schema#"}. This turns into an error on the MCP inspector, being unable to list tools, thus unable to execute any of them.

To Reproduce
Steps to reproduce the behavior:

  1. Create an instance of McpServer:
server = new McpServer({...serverInfo}, {
      capabilities,
      instructions,
    });
  1. Register a tool with an inputSchema:
server.registerTool(
      name,
      {
        title: name,
        description: description,
        inputSchema: z.object({...schema}).shape,
      },
      handler,
    );
  1. Start MCP inspector
  2. Connect to MCP server from inspector
  3. Try to list tools
  4. Get the error:
Uncaught (in promise) ZodError: [
  {
    "received": "string",
    "code": "invalid_literal",
    "expected": "object",
    "path": [
      "tools",
      0,
      "inputSchema",
      "type"
    ],
    "message": "Invalid literal value, expected \"object\""
  }
]

Expected behavior
The input Schema of the tool should be converted into a valid, matching jsonSchema.

Additional Context
Debugging the application, I could see that the zodToJsonSchema function calls the parseDef function with the zod definition. When the jsonSchemaOrGetterconstant gets calculated through the selectParser function, it passes def, def.typeName and refs. The second argument is undefined. Then teh selectParser function switches typeName on all possible ZodFirstPartyTypeKind.<ZodType>. However, ZodFirstPartyTypeKind is {}, so the first one matches, which is the string matcher.

I have @modelcontextprotocol/sdk@1.20.0 dependency installed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the ListTools request with the registration example, then trace zodToJsonSchema through parseDef and selectParser, checking how ZodFirstPartyTypeKind is provided. Compare the generated schema with the MCP inspector error; done means registered tools produce matching object inputSchema values and can be listed by the inspector.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.