Skip to content

[v2] Should raise error at build time if zod outputSchema is not consistent with the structuredContent type #2754

Open

Description

@tobiasBora

What happened?

I created a tool that outputs a structured content like:

  server.registerTool(
    'ping',
    {
      description: 'Returns a string pong with a timestamp',
      outputSchema: z.object({data: z.string()}) // <---- Wrong return type, should be simply z.string()!
    },
    async () => {
      const str = `Pong at ${new Date()}`
      return {
        content: [{ type: 'text', text: str }], // It seems to be added automatically by the library, but typescript complains if only structuredContent is present
        structuredContent: str
      };
    }
  );

Using only static analysis, we can directly see that this won't work, since outputSchema expects an object but structuredContent outputs a string… and indeed, at runtime this produces an error. Yet, I'd love this kind of error to be catched at build time, with a proper Typescript error.

What did you expect?

An error.

Code to reproduce

  server.registerTool(
    'ping',
    {
      description: 'Returns a string pong with a timestamp',
      outputSchema: z.object({data: z.string()}) // <---- Wrong return type, should be simply z.string()!
    },
    async () => {
      const str = `Pong at ${new Date()}`
      return {
        content: [{ type: 'text', text: str }], // It seems to be added automatically by the library, but typescript complains if only structuredContent is present
        structuredContent: str
      };
    }
  );

SDK version

2.0.0

Area

Server

Activity

  1. added
    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes
    on Sep 3, 2026
  2. hngpt52 commented on Sep 12, 2026

    @hngpt52

    I have a fix prepared for this: thread the output schema through registerTool callback typing so successful structuredContent must match its inferred output type. Error and input-required responses keep their current behavior, and runtime validation stays in place.

    The change covers Standard Schema providers and the deprecated raw Zod shape overload, with compiler regressions and checks against the built ESM/CJS declarations. I will open a PR with the implementation and validation details.

  3. errmakov commented on Sep 14, 2026

    @errmakov

    There are three open PRs for this, two of them from before this issue was filed:

    I type-checked the snippet above against each PR's preview build. With @modelcontextprotocol/server@2.0.0 it compiles cleanly. With each of the three PRs it fails with Type 'string' is not assignable to type '{ data: string; }', and a tool that returns structuredContent: { data: 'ok' } still compiles.

    AI disclosure: this comment was written with the help of Claude Code.

  4. added
    enhancementRequest for a new feature that's not currently supported
    and removed
    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes
    on Sep 28, 2026
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

    enhancementRequest for a new feature that's not currently supported

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions