MCP client does not re-fetch tools/list on notifications/tools/list_changed — new tools unreachable until full session restart
Environment
- Claude Code CLI on Windows 10 (10.0.19045)
- CLI version:
2.1.198 (Claude Code) - MCP server: local HTTP (StreamableHTTPServerTransport), Node ESM, registered at user scope
Summary
When an MCP server declares capabilities.tools.listChanged and emits notifications/tools/list_changed, a connected Claude Code session does not re-request tools/list. Tools added to the server mid-session (e.g. after a server restart that the client transparently reconnects to) remain undiscoverable and uncallable — ToolSearch can't find them either — until the user fully restarts the Claude session. Reconnecting the transport is not sufficient.
Expected
Per the MCP spec, after receiving notifications/tools/list_changed from a server that declared the listChanged capability, the client should re-request tools/list and surface the updated tool set to the model (including deferred-tool search indexes).
Actual
The notification is delivered (or at least emitted without transport error) but the session's tool registry keeps the stale list. New tools return schema/validation errors if called by name and are absent from ToolSearch results.
Reproduction
- Start Claude Code with a local MCP server connected (HTTP transport).
- Add a trivial new tool to the server (we used a
pingcanary), restart the server process; the client auto-reconnects to the same server URL. - Server emits
notifications/tools/list_changedon both client init (server.oninitialized) and the rebind-after-restart path. Server-side delivery is unit-tested against a compliant in-memory MCP client, which does receive and act on it. - In the still-open Claude session, attempt to call or ToolSearch the new tool.
Result: tool not found. Only a full session restart (not /mcp reconnect) picks it up.
Server-side evidence
- Server declares
capabilities.tools.listChangedand emits on init + rebind (our commitsf7122f8,1e00739). - Emission fires without error on the live transport.
- A compliant test client (MCP SDK in-memory pair) receives the notification and re-lists successfully — isolating the gap to the Claude Code client (or to mid-session tool-registry refresh, or the rebound SSE stream not carrying the deferred notification).
Impact
Any workflow where an MCP server evolves during a session — hot-reload during development, version upgrades, servers that register tools dynamically — requires killing the whole Claude session, losing conversation context. For long-running orchestration sessions this is the single most expensive restart in our stack.
Ask
Either honor tools/list_changed with a tools/list re-fetch (and refresh the deferred-tool index), or document that mid-session tool-list changes are unsupported so servers can design around it.