Skip to content

Fix: Respect explicit listChanged: false capability setting#1513

Merged
mattzcarey merged 2 commits intomainfrom
fix/list-changed-overwrite
Feb 10, 2026
Merged

Fix: Respect explicit listChanged: false capability setting#1513
mattzcarey merged 2 commits intomainfrom
fix/list-changed-overwrite

Conversation

@mattzcarey
Copy link
Copy Markdown
Contributor

@mattzcarey mattzcarey commented Feb 10, 2026

Problem

When instantiating McpServer with capabilities.tools.listChanged set to false, the setting was being overwritten to true when registering a tool via registerTool().

const server = new McpServer(
  { name: 'my-server', version: '1.0' },
  { capabilities: { tools: { listChanged: false } } }
);

server.registerTool('ping', {}, async () => ({ content: [{ type: 'text', text: 'pong' }] }));
// After connect, capabilities.tools.listChanged is incorrectly `true`

This prevents servers from opting out of list change notifications, which may be desirable for stateless server implementations.

Fixes #1488

Solution

Changed the registerCapabilities calls in setToolRequestHandlers(), setResourceRequestHandlers(), and setPromptRequestHandlers() to use nullish coalescing, only defaulting to true when not explicitly set:

// Before
this.server.registerCapabilities({
    tools: { listChanged: true }
});

// After
this.server.registerCapabilities({
    tools: { listChanged: this.server.getCapabilities().tools?.listChanged ?? true }
});

Design Decisions

  1. Made Server.getCapabilities() public - This was the minimal change needed to allow McpServer to check existing capability values. The method already existed as private; we simply changed visibility.

  2. Defaulting at registration time - We considered moving the default elsewhere (e.g., constructor), but listChanged: true only makes sense when tools/resources/prompts are actually registered. Keeping the default at registration time preserves this semantic.

  3. Nullish coalescing (?? true) - This ensures:

    • Explicit false → stays false
    • Explicit true → stays true
    • Not set (undefined) → defaults to true (backwards compatible)
  4. No breaking changes - Existing code that doesn't set listChanged continues to get listChanged: true as before.

Test Plan

Added 4 tests:

  • should default tools.listChanged to true when not explicitly set
  • should respect tools.listChanged: false when explicitly set
  • should respect resources.listChanged: false when explicitly set
  • should respect prompts.listChanged: false when explicitly set

Changed McpServer to check existing capabilities before setting listChanged to true, allowing users to explicitly set listChanged: false for tools, resources, and prompts. Made Server.getCapabilities() public to enable this check.
@mattzcarey mattzcarey requested a review from a team as a code owner February 10, 2026 09:22
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 10, 2026

⚠️ No Changeset found

Latest commit: 292c34a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Feb 10, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1513

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1513

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1513

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1513

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1513

commit: 292c34a

@claude
Copy link
Copy Markdown

claude bot commented Feb 10, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@mattzcarey mattzcarey merged commit 8654c7f into main Feb 10, 2026
16 checks passed
@mattzcarey mattzcarey deleted the fix/list-changed-overwrite branch February 10, 2026 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

McpServer overwrites server tool capabilities when a tool is registered

2 participants