-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Describe the bug
When creating an McpServer with ServerOptions.capabilities.tools.listChanged set to false, any call to registerTool overwrites that value to true.
To Reproduce
Steps to reproduce the behavior:
- Create an
McpServerwith capabilities wheretools.listChangedis set tofalse:
const myMcpServer = new McpServer(
{
name: 'my-mcp-server',
},
{
capabilities: {
tools: {
listChanged: false,
},
},
}
);
- Call the
registerToolmethod:
myMcpServer.registerTool(
'ping',
{
title: 'Ping',
},
async () => {
return {
content: [
{
type: 'text',
text: 'pong',
},
],
};
}
);
-
Connect the server to a transport method.
-
Observe that the initialize returns
capabilities.tools.listChangedastrue.
Expected behavior
Setting the capabilities shouldn't be a side-effect of registering a tool. If you've set the capability as false when setting up the server, subsequent calls shouldn't overwrite that value.
Proposed Fix
Remove the registerCapabilities call from setToolRequestHandler:
| this.server.registerCapabilities({ |
private setToolRequestHandlers() {
if (this._toolHandlersInitialized) {
return;
}
this.server.assertCanSetRequestHandler('tools/list');
this.server.assertCanSetRequestHandler('tools/call');
// REMOVE THIS CALL TO REGISTER CAPABILITIES
this.server.registerCapabilities({
tools: {
listChanged: true
}
});
Additional context
I'm working on a stateless MCP server using StreamableHTTP. I don't want clients to try to create open-ended GET requests waiting for updates because they'll just end-up timing out on my end. As a workaround, I'm using the registerCapabilities method to set the listChanged capability back to false after all my calls to registerTool.
const myMcpServer = new McpServer({ name: 'my-mcp-server' });
myMcpServer.registerTool(...);
// update capabilities after you're done registering all the tools
myMcpServer.server.registerCapabilities({
tools: {
listChanged: false,
},
});