MCP client does not re-fetch tools/list on notifications/tools/list_changed — new tools unreachable until full session restart

Open 💬 0 comments Opened Jul 13, 2026 by SMC1177

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

  1. Start Claude Code with a local MCP server connected (HTTP transport).
  2. Add a trivial new tool to the server (we used a ping canary), restart the server process; the client auto-reconnects to the same server URL.
  3. Server emits notifications/tools/list_changed on 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.
  4. 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.listChanged and emits on init + rebind (our commits f7122f8, 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.

View original on GitHub ↗