Skip to content

Claude Code does not respond to MCP notifications/tools/list_changed #15667

Description

@eastlondoner

Summary

Claude Code does not respond to notifications/tools/list_changed MCP notifications. When an MCP server dynamically enables/disables tools and sends the notification, Claude Code does not update its tool list.

MCP Specification Reference

According to the MCP Tools Specification:

Servers that support tools MUST declare the tools capability. listChanged indicates whether the server will emit notifications when the list of available tools changes.

The capability is declared as:

{
  "capabilities": {
    "tools": {
      "listChanged": true
    }
  }
}

When the list of available tools changes, servers that declared the listChanged capability SHOULD send a notification.

The notification format is:

{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed"
}

Upon receiving this notification, clients are expected to re-fetch the tool list via tools/list.

Expected Behavior

  1. MCP server sends notifications/tools/list_changed notification
  2. Claude Code re-fetches the tool list via tools/list
  3. Claude Code sees the newly enabled/disabled tools

Actual Behavior

  1. MCP server sends notifications/tools/list_changed notification
  2. Claude Code ignores the notification
  3. Claude Code's tool list remains unchanged from initial connection

Minimal Reproduction

I've created a minimal reproduction case: https://github.com/eastlondoner/mcp-dynamic-tools-repro

Setup

git clone https://github.com/eastlondoner/mcp-dynamic-tools-repro
cd mcp-dynamic-tools-repro
bun install  # or npm install
bun start    # starts MCP server on http://localhost:3002/mcp

The .mcp.json is already configured:

{
  "mcpServers": {
    "dynamic-tools-repro": {
      "type": "http",
      "url": "http://localhost:3002/mcp"
    }
  }
}

Test Steps

  1. Start the MCP server (bun start)
  2. Start Claude Code in the same directory (claude)
  3. Ask Claude to call get_status - shows secretToolEnabled: false
  4. Ask Claude to call toggle_secret_tool with enable=true
  5. Server logs show: Enabling secret_tool, isConnected: true
  6. Ask Claude to call secret_tool

Expected: Claude calls secret_tool successfully

Actual: Claude says it doesn't have access to secret_tool

Server Architecture

The test server has 3 tools:

Tool Initially Available Description
get_status Yes Shows current state
toggle_secret_tool Yes Enables/disables secret_tool
secret_tool No (disabled) Only visible after enabling

When toggle_secret_tool(enable=true) is called, the MCP SDK's handle.enable() method is used, which internally sends notifications/tools/list_changed.

Environment

  • Claude Code version: 2.0.62
  • MCP SDK version: 1.25.1
  • Runtime: Bun 1.3.5
  • OS: macOS

Related

  • GitHub Discussion #76 mentions "Claude Desktop doesn't support notifications/tools/list_changed at the moment"
  • This appears to also apply to Claude Code

Use Case

This is blocking my development of a Minecraft client with an MCP co-pilot interface. I want to dynamically show/hide contextual tools (like open_container when looking at a chest) based on game state. The server correctly sends notifications when tools become available, but Claude Code never sees them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions