Fix registering multiple tools/resources/prompts
Request handlers were being re-registered every time a new tool/resource/prompt was added, which would fail since the handlers were already registered. Now we track whether handlers have been initialized and only register them once. Added tests to verify that multiple registrations work correctly. Resolves #124.
This commit is contained in:
parent
438505b74c
commit
2590d40e74
2 changed files with 97 additions and 0 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue