Skip to content

test(server): cover non-object output schemas#2533

Draft
pradeep-ramola wants to merge 2 commits into
modelcontextprotocol:mainfrom
pradeep-ramola:pradeep-ramola/zod-output-schema-validation
Draft

test(server): cover non-object output schemas#2533
pradeep-ramola wants to merge 2 commits into
modelcontextprotocol:mainfrom
pradeep-ramola:pradeep-ramola/zod-output-schema-validation

Conversation

@pradeep-ramola

@pradeep-ramola pradeep-ramola commented Jul 21, 2026

Copy link
Copy Markdown

Refs #1308
Refs #2530

Adds regression coverage for McpServer tool outputSchema validation when the registered Zod schema is not a bare z.object(...).

This is test-only. It does not change production behavior or claim to close either referenced issue.

Motivation and Context

The original coverage handled Zod wrappers such as .optional() and unions of object schemas. Review feedback asked for actual non-object roots too, especially strings and arrays.

The tests now verify:

  • z.object(...).optional() accepts matching structured output.
  • z.union([z.object(...), z.object(...)]) accepts matching structured output.
  • Invalid structured output is still rejected against wrapper/non-object schemas, so validation is not skipped.
  • On the default/in-memory legacy path, z.string() and z.array(z.string()) output schemas are projected into the legacy { result: ... } wrapper and the returned structuredContent is wrapped the same way.
  • On a real modern createMcpHandler HTTP connection negotiated through server/discover, z.string() and z.array(z.string()) keep their natural output schemas and return bare structuredContent values.

How Has This Been Tested?

corepack pnpm --filter @modelcontextprotocol/test-integration test -- test/server/mcp.test.ts
corepack pnpm --filter @modelcontextprotocol/test-integration test -- test/server/createMcpHandler.test.ts
corepack pnpm --filter @modelcontextprotocol/test-integration exec eslint test/server/mcp.test.ts test/server/createMcpHandler.test.ts
corepack pnpm exec prettier --config .prettierrc.json --check test/integration/test/server/mcp.test.ts test/integration/test/server/createMcpHandler.test.ts
git diff --check

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

No changeset is included because this is test-only.

The default/in-memory McpServer.server.connect() integration path negotiates a 2025-era connection, where non-object outputs are intentionally wrapped for compatibility. The added createMcpHandler coverage exercises the 2026-era path and shows that modern clients receive the natural string/array schema and structuredContent values.

@changeset-bot

changeset-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 4f0debd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2533

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2533

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2533

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2533

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2533

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2533

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2533

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2533

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2533

commit: 4f0debd

@tobiasBora

tobiasBora commented Jul 22, 2026

Copy link
Copy Markdown

Thanks, could you also add tests for actual non-objects like string and arrays? I have issues with strings in #2530

Also why do you say that it fixes #1308 as you just change tests? Or is it just a first draft before fixing the code as well?

@pradeep-ramola pradeep-ramola changed the title test(server): cover zod output schema wrappers test(server): cover non-object output schemas Jul 22, 2026
@pradeep-ramola

Copy link
Copy Markdown
Author

Thanks, could you also add tests for actual non-objects like string and arrays? I have issues with strings in #2530

Also why do you say that it fixes #1308 as you just change tests? Or is it just a first draft before fixing the code as well?

Thanks for the catch. I added tests for actual non-object roots now: z.string() and z.array(z.string()).

The added coverage checks both paths:

  • the default/in-memory 2025-era path, where non-object output schemas and structuredContent are intentionally wrapped as { result: ... }
  • the modern createMcpHandler HTTP path negotiated via server/discover, where string/array schemas and bare structuredContent values are preserved

I also updated the PR title/body from Fixes #1308 to Refs #1308 / Refs #2530 and clarified that this PR is test-only, not a production code fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants