Skip to content

McpServer overwrites server tool capabilities when a tool is registered #1488

@stevenpal

Description

@stevenpal

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:

  1. Create an McpServer with capabilities where tools.listChanged is set to false:
  const myMcpServer = new McpServer(
    {
      name: 'my-mcp-server',
    },
    {
       capabilities: {
         tools: {
           listChanged: false,
         },
       },
    }
  );
  1. Call the registerTool method:
  myMcpServer.registerTool(
    'ping',
    {
      title: 'Ping',
    },
    async () => {
      return {
        content: [
          {
            type: 'text',
            text: 'pong',
          },
        ],
      };
    }
  );
  1. Connect the server to a transport method.

  2. Observe that the initialize returns capabilities.tools.listChanged as true.

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,
    },
  });

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions