Skip to content

Commit 1fb33e8

Browse files
Merge pull request #126 from modelcontextprotocol/justin/fix-multiple-registrations
Fix registering multiple tools/resources/prompts
2 parents 13ddf5f + 38c361a commit 1fb33e8

File tree

4 files changed

+100
-3
lines changed

4 files changed

+100
-3
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modelcontextprotocol/sdk",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"description": "Model Context Protocol implementation for TypeScript",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",

src/server/mcp.test.ts

+73
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,19 @@ describe("tool()", () => {
310310
}).toThrow(/already registered/);
311311
});
312312

313+
test("should allow registering multiple tools", () => {
314+
const mcpServer = new McpServer({
315+
name: "test server",
316+
version: "1.0",
317+
});
318+
319+
// This should succeed
320+
mcpServer.tool("tool1", () => ({ content: [] }));
321+
322+
// This should also succeed and not throw about request handlers
323+
mcpServer.tool("tool2", () => ({ content: [] }));
324+
});
325+
313326
test("should allow client to call server tools", async () => {
314327
const mcpServer = new McpServer({
315328
name: "test server",
@@ -734,6 +747,33 @@ describe("resource()", () => {
734747
}).toThrow(/already registered/);
735748
});
736749

750+
test("should allow registering multiple resources", () => {
751+
const mcpServer = new McpServer({
752+
name: "test server",
753+
version: "1.0",
754+
});
755+
756+
// This should succeed
757+
mcpServer.resource("resource1", "test://resource1", async () => ({
758+
contents: [
759+
{
760+
uri: "test://resource1",
761+
text: "Test content 1",
762+
},
763+
],
764+
}));
765+
766+
// This should also succeed and not throw about request handlers
767+
mcpServer.resource("resource2", "test://resource2", async () => ({
768+
contents: [
769+
{
770+
uri: "test://resource2",
771+
text: "Test content 2",
772+
},
773+
],
774+
}));
775+
});
776+
737777
test("should prevent duplicate resource template registration", () => {
738778
const mcpServer = new McpServer({
739779
name: "test server",
@@ -1210,6 +1250,39 @@ describe("prompt()", () => {
12101250
}).toThrow(/already registered/);
12111251
});
12121252

1253+
test("should allow registering multiple prompts", () => {
1254+
const mcpServer = new McpServer({
1255+
name: "test server",
1256+
version: "1.0",
1257+
});
1258+
1259+
// This should succeed
1260+
mcpServer.prompt("prompt1", async () => ({
1261+
messages: [
1262+
{
1263+
role: "assistant",
1264+
content: {
1265+
type: "text",
1266+
text: "Test response 1",
1267+
},
1268+
},
1269+
],
1270+
}));
1271+
1272+
// This should also succeed and not throw about request handlers
1273+
mcpServer.prompt("prompt2", async () => ({
1274+
messages: [
1275+
{
1276+
role: "assistant",
1277+
content: {
1278+
type: "text",
1279+
text: "Test response 2",
1280+
},
1281+
},
1282+
],
1283+
}));
1284+
});
1285+
12131286
test("should throw McpError for invalid prompt name", async () => {
12141287
const mcpServer = new McpServer({
12151288
name: "test server",

src/server/mcp.ts

+24
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,13 @@ export class McpServer {
8181
await this.server.close();
8282
}
8383

84+
private _toolHandlersInitialized = false;
85+
8486
private setToolRequestHandlers() {
87+
if (this._toolHandlersInitialized) {
88+
return;
89+
}
90+
8591
this.server.assertCanSetRequestHandler(
8692
ListToolsRequestSchema.shape.method.value,
8793
);
@@ -165,6 +171,8 @@ export class McpServer {
165171
}
166172
},
167173
);
174+
175+
this._toolHandlersInitialized = true;
168176
}
169177

170178
private setCompletionRequestHandler() {
@@ -249,7 +257,13 @@ export class McpServer {
249257
return createCompletionResult(suggestions);
250258
}
251259

260+
private _resourceHandlersInitialized = false;
261+
252262
private setResourceRequestHandlers() {
263+
if (this._resourceHandlersInitialized) {
264+
return;
265+
}
266+
253267
this.server.assertCanSetRequestHandler(
254268
ListResourcesRequestSchema.shape.method.value,
255269
);
@@ -342,9 +356,17 @@ export class McpServer {
342356
);
343357

344358
this.setCompletionRequestHandler();
359+
360+
this._resourceHandlersInitialized = true;
345361
}
346362

363+
private _promptHandlersInitialized = false;
364+
347365
private setPromptRequestHandlers() {
366+
if (this._promptHandlersInitialized) {
367+
return;
368+
}
369+
348370
this.server.assertCanSetRequestHandler(
349371
ListPromptsRequestSchema.shape.method.value,
350372
);
@@ -406,6 +428,8 @@ export class McpServer {
406428
);
407429

408430
this.setCompletionRequestHandler();
431+
432+
this._promptHandlersInitialized = true;
409433
}
410434

411435
/**

0 commit comments

Comments
 (0)