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
- MCP server sends
notifications/tools/list_changed notification
- Claude Code re-fetches the tool list via
tools/list
- Claude Code sees the newly enabled/disabled tools
Actual Behavior
- MCP server sends
notifications/tools/list_changed notification
- Claude Code ignores the notification
- 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
- Start the MCP server (
bun start)
- Start Claude Code in the same directory (
claude)
- Ask Claude to call
get_status - shows secretToolEnabled: false
- Ask Claude to call
toggle_secret_tool with enable=true
- Server logs show:
Enabling secret_tool, isConnected: true
- 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.
Summary
Claude Code does not respond to
notifications/tools/list_changedMCP 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:
The capability is declared as:
{ "capabilities": { "tools": { "listChanged": true } } }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
notifications/tools/list_changednotificationtools/listActual Behavior
notifications/tools/list_changednotificationMinimal Reproduction
I've created a minimal reproduction case: https://github.com/eastlondoner/mcp-dynamic-tools-repro
Setup
The
.mcp.jsonis already configured:{ "mcpServers": { "dynamic-tools-repro": { "type": "http", "url": "http://localhost:3002/mcp" } } }Test Steps
bun start)claude)get_status- showssecretToolEnabled: falsetoggle_secret_toolwithenable=trueEnabling secret_tool,isConnected: truesecret_toolExpected: Claude calls
secret_toolsuccessfullyActual: Claude says it doesn't have access to
secret_toolServer Architecture
The test server has 3 tools:
get_statustoggle_secret_toolsecret_toolWhen
toggle_secret_tool(enable=true)is called, the MCP SDK'shandle.enable()method is used, which internally sendsnotifications/tools/list_changed.Environment
Related
notifications/tools/list_changedat the moment"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_containerwhen looking at a chest) based on game state. The server correctly sends notifications when tools become available, but Claude Code never sees them.