diff --git a/package-lock.json b/package-lock.json index 6f8490b3..a4e2e7ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@modelcontextprotocol/sdk", - "version": "1.3.0", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@modelcontextprotocol/sdk", - "version": "1.3.0", + "version": "1.3.1", "license": "MIT", "dependencies": { "content-type": "^1.0.5", diff --git a/package.json b/package.json index bc7fb42f..e051f1a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/sdk", - "version": "1.3.0", + "version": "1.3.1", "description": "Model Context Protocol implementation for TypeScript", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/src/server/mcp.test.ts b/src/server/mcp.test.ts index 33fdeb91..4154e7dd 100644 --- a/src/server/mcp.test.ts +++ b/src/server/mcp.test.ts @@ -310,6 +310,19 @@ describe("tool()", () => { }).toThrow(/already registered/); }); + test("should allow registering multiple tools", () => { + const mcpServer = new McpServer({ + name: "test server", + version: "1.0", + }); + + // This should succeed + mcpServer.tool("tool1", () => ({ content: [] })); + + // This should also succeed and not throw about request handlers + mcpServer.tool("tool2", () => ({ content: [] })); + }); + test("should allow client to call server tools", async () => { const mcpServer = new McpServer({ name: "test server", @@ -734,6 +747,33 @@ describe("resource()", () => { }).toThrow(/already registered/); }); + test("should allow registering multiple resources", () => { + const mcpServer = new McpServer({ + name: "test server", + version: "1.0", + }); + + // This should succeed + mcpServer.resource("resource1", "test://resource1", async () => ({ + contents: [ + { + uri: "test://resource1", + text: "Test content 1", + }, + ], + })); + + // This should also succeed and not throw about request handlers + mcpServer.resource("resource2", "test://resource2", async () => ({ + contents: [ + { + uri: "test://resource2", + text: "Test content 2", + }, + ], + })); + }); + test("should prevent duplicate resource template registration", () => { const mcpServer = new McpServer({ name: "test server", @@ -1210,6 +1250,39 @@ describe("prompt()", () => { }).toThrow(/already registered/); }); + test("should allow registering multiple prompts", () => { + const mcpServer = new McpServer({ + name: "test server", + version: "1.0", + }); + + // This should succeed + mcpServer.prompt("prompt1", async () => ({ + messages: [ + { + role: "assistant", + content: { + type: "text", + text: "Test response 1", + }, + }, + ], + })); + + // This should also succeed and not throw about request handlers + mcpServer.prompt("prompt2", async () => ({ + messages: [ + { + role: "assistant", + content: { + type: "text", + text: "Test response 2", + }, + }, + ], + })); + }); + test("should throw McpError for invalid prompt name", async () => { const mcpServer = new McpServer({ name: "test server", diff --git a/src/server/mcp.ts b/src/server/mcp.ts index 4b484465..36d9341d 100644 --- a/src/server/mcp.ts +++ b/src/server/mcp.ts @@ -81,7 +81,13 @@ export class McpServer { await this.server.close(); } + private _toolHandlersInitialized = false; + private setToolRequestHandlers() { + if (this._toolHandlersInitialized) { + return; + } + this.server.assertCanSetRequestHandler( ListToolsRequestSchema.shape.method.value, ); @@ -165,6 +171,8 @@ export class McpServer { } }, ); + + this._toolHandlersInitialized = true; } private setCompletionRequestHandler() { @@ -249,7 +257,13 @@ export class McpServer { return createCompletionResult(suggestions); } + private _resourceHandlersInitialized = false; + private setResourceRequestHandlers() { + if (this._resourceHandlersInitialized) { + return; + } + this.server.assertCanSetRequestHandler( ListResourcesRequestSchema.shape.method.value, ); @@ -342,9 +356,17 @@ export class McpServer { ); this.setCompletionRequestHandler(); + + this._resourceHandlersInitialized = true; } + private _promptHandlersInitialized = false; + private setPromptRequestHandlers() { + if (this._promptHandlersInitialized) { + return; + } + this.server.assertCanSetRequestHandler( ListPromptsRequestSchema.shape.method.value, ); @@ -406,6 +428,8 @@ export class McpServer { ); this.setCompletionRequestHandler(); + + this._promptHandlersInitialized = true; } /**