fix: drop unresolved union members in zod schemas

This change enables the strictUnions option in zod-to-json-schema so
that any union members that cannot be resolved are excluded from the
resulting JSON Schema anyOf array.

Previously, a schema like this:

**Before**

```ts
import { zodToJsonSchema } from "zod-to-json-schema";
import { z } from "zod";

console.dir(
  zodToJsonSchema(
    z.union([
      z
        .string()
        .base64()
        .transform((v) => Uint8Array.from(atob(v), (v) => v.charCodeAt(0))),
      z.instanceof(ReadableStream<Uint8Array>),
      z.instanceof(Blob),
      z.instanceof(ArrayBuffer),
      z.instanceof(Uint8Array),
    ])
  ),
  { depth: null }
);
```

Prints:

```js
{
  anyOf: [
    { type: "string", contentEncoding: "base64" }, {}, {}, {}, {}
  ],
  $schema: "http://json-schema.org/draft-07/schema#",
}
```

**After**

```ts
import { zodToJsonSchema } from "zod-to-json-schema";
import { z } from "zod";

console.dir(
  zodToJsonSchema(
    z.union([
      z
        .string()
        .base64()
        .transform((v) => Uint8Array.from(atob(v), (v) => v.charCodeAt(0))),
      z.instanceof(ReadableStream<Uint8Array>),
      z.instanceof(Blob),
      z.instanceof(ArrayBuffer),
      z.instanceof(Uint8Array),
    ]),
    { strictUnions: true }, // 👈
  ),
  { depth: null }
);
```

Prints:

```js
{
  anyOf: [
    { type: "string", contentEncoding: "base64" }
  ],
  $schema: "http://json-schema.org/draft-07/schema#",
}
```

---

I picked this example in particular because I have modelled file uploads
using a permissive schema that accepts streams, byte arrays / blobs and
base64-encoded strings. In the context of MCP, base64 would be most
applicable so I wanted to drop the other union members that couldn't be
represented in JSON Schema.
This commit is contained in:
Georges Haidar 2025-02-16 19:23:29 +00:00
commit 7c7e4ad0ae
No known key found for this signature in database

View file

@ -108,7 +108,9 @@ export class McpServer {
name,
description: tool.description,
inputSchema: tool.inputSchema
? (zodToJsonSchema(tool.inputSchema) as Tool["inputSchema"])
? (zodToJsonSchema(tool.inputSchema, {
strictUnions: true,
}) as Tool["inputSchema"])
: EMPTY_OBJECT_JSON_SCHEMA,
};
},