From 0537a8140d6c9d871c9b7183fee900f3acb66906 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Tue, 17 Mar 2026 11:47:24 -0400 Subject: [PATCH 1/3] fix: ensure object schemas always include required field for OpenAI compatibility When using z.object({}).strict() as inputSchema, the generated JSON schema omits the required field. OpenAI strict JSON schema mode requires required to always be present (even as an empty array), causing tool registration to fail with: "Schema must have the following keys: required" Fixed in two places: - schemaToJson() now adds required: [] to object schemas missing it - EMPTY_OBJECT_JSON_SCHEMA constant now includes required: [] Fixes #1659 --- packages/core/src/util/schema.ts | 8 +++++++- packages/server/src/server/mcp.ts | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/core/src/util/schema.ts b/packages/core/src/util/schema.ts index adecee361..34fb82c24 100644 --- a/packages/core/src/util/schema.ts +++ b/packages/core/src/util/schema.ts @@ -26,7 +26,13 @@ export type SchemaOutput = z.output; * Converts a Zod schema to JSON Schema. */ export function schemaToJson(schema: AnySchema, options?: { io?: 'input' | 'output' }): Record { - return z.toJSONSchema(schema, options) as Record; + const jsonSchema = z.toJSONSchema(schema, options) as Record; + // Ensure object schemas always include 'required' (even if empty) + // for compatibility with OpenAI strict JSON schema mode + if (jsonSchema.type === 'object' && !('required' in jsonSchema)) { + jsonSchema.required = []; + } + return jsonSchema; } /** diff --git a/packages/server/src/server/mcp.ts b/packages/server/src/server/mcp.ts index 05136f5b6..4bfa9e24f 100644 --- a/packages/server/src/server/mcp.ts +++ b/packages/server/src/server/mcp.ts @@ -1146,7 +1146,8 @@ function createToolExecutor(inputSchema: AnySchema | undefined, handler: AnyTool const EMPTY_OBJECT_JSON_SCHEMA = { type: 'object' as const, - properties: {} + properties: {}, + required: [] as string[] }; /** From 9cb23d859a9e274700a9a333f67cd3c33a3d84e5 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Tue, 17 Mar 2026 11:54:48 -0400 Subject: [PATCH 2/3] fix: update test to expect required: [] in empty object schema --- test/integration/test/server/mcp.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/test/server/mcp.test.ts b/test/integration/test/server/mcp.test.ts index 416f05102..0d2e1a9a7 100644 --- a/test/integration/test/server/mcp.test.ts +++ b/test/integration/test/server/mcp.test.ts @@ -432,7 +432,8 @@ describe('Zod v4', () => { expect(result.tools[0]!.name).toBe('test'); expect(result.tools[0]!.inputSchema).toEqual({ type: 'object', - properties: {} + properties: {}, + required: [] }); // Adding the tool before the connection was established means no notification was sent From b4f1b45d85a61a8b5bd980cfba157798b25f50a9 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Tue, 17 Mar 2026 19:58:04 -0400 Subject: [PATCH 3/3] add changeset --- .changeset/empty-zod-required.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/empty-zod-required.md diff --git a/.changeset/empty-zod-required.md b/.changeset/empty-zod-required.md new file mode 100644 index 000000000..0f6f497be --- /dev/null +++ b/.changeset/empty-zod-required.md @@ -0,0 +1,6 @@ +--- +"@modelcontextprotocol/core": patch +"@modelcontextprotocol/server": patch +--- + +Ensure object schemas always include required field for OpenAI strict JSON schema compatibility