From 52dc7f116080a143ff65a559a4f10a3420ec4d57 Mon Sep 17 00:00:00 2001 From: yuna0x0 Date: Tue, 6 May 2025 01:49:33 +0800 Subject: [PATCH 1/2] Fix isZodRawShape return false on empty object and add test --- src/server/mcp.test.ts | 47 ++++++++++++++++++++++++++++++++++++++++++ src/server/mcp.ts | 7 +++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/server/mcp.test.ts b/src/server/mcp.test.ts index c9be5c76..5f50df68 100644 --- a/src/server/mcp.test.ts +++ b/src/server/mcp.test.ts @@ -622,6 +622,53 @@ describe("tool()", () => { }); }); + test("should register tool with description, empty params, and annotations", async () => { + const mcpServer = new McpServer({ + name: "test server", + version: "1.0", + }); + const client = new Client({ + name: "test client", + version: "1.0", + }); + + mcpServer.tool( + "test", + "A tool with everything but empty params", + {}, + { title: "Complete Test Tool with empty params", readOnlyHint: true, openWorldHint: false }, + async () => ({ + content: [{ type: "text", text: "Test response" }] + }) + ); + + const [clientTransport, serverTransport] = + InMemoryTransport.createLinkedPair(); + + await Promise.all([ + client.connect(clientTransport), + mcpServer.server.connect(serverTransport), + ]); + + const result = await client.request( + { method: "tools/list" }, + ListToolsResultSchema, + ); + + expect(result.tools).toHaveLength(1); + expect(result.tools[0].name).toBe("test"); + expect(result.tools[0].description).toBe("A tool with everything but empty params"); + expect(result.tools[0].inputSchema).toMatchObject({ + type: "object", + properties: {} + }); + expect(result.tools[0].annotations).toEqual({ + title: "Complete Test Tool with empty params", + readOnlyHint: true, + openWorldHint: false + }); + }); + test("should validate tool args", async () => { const mcpServer = new McpServer({ name: "test server", diff --git a/src/server/mcp.ts b/src/server/mcp.ts index 6204eb2a..dccfa04e 100644 --- a/src/server/mcp.ts +++ b/src/server/mcp.ts @@ -663,8 +663,11 @@ export class McpServer { // Helper to check if an object is a Zod schema (ZodRawShape) const isZodRawShape = (obj: unknown): obj is ZodRawShape => { if (typeof obj !== "object" || obj === null) return false; - // Check that at least one property is a ZodType instance - return Object.values(obj as object).some(v => v instanceof ZodType); + + const isEmptyObject = z.object({}).strict().safeParse(obj).success; + + // Check if object is empty or at least one property is a ZodType instance + return isEmptyObject || Object.values(obj as object).some(v => v instanceof ZodType); }; let description: string | undefined; From 51ce07fada7d1cdedaf4ca28820a3911ae1329ec Mon Sep 17 00:00:00 2001 From: ihrpr Date: Thu, 8 May 2025 18:05:27 +0100 Subject: [PATCH 2/2] bump version to 1.11.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c6a65847..fa6f9545 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/sdk", - "version": "1.11.0", + "version": "1.11.1", "description": "Model Context Protocol implementation for TypeScript", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)",