claude-code - 💡(How to fix) Fix tools/list_changed cannot recover stale Python subprocess code

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Related to but distinct from #59500. This issue is about the recovery primitive specifically.

I've been building khimaira-chat, a multi-agent orchestration MCP server. We declare tools.listChanged=True in ServerCapabilities as forward-compat groundwork — see packages/khimaira-chat/src/khimaira_chat/server.py:889.

Root Cause

notifications/tools/list_changed is documented as the mechanism for an MCP server to signal that its tool list has changed at runtime. We initially thought this would recover the "subprocess is running stale code after package upgrade" case. It doesn't, and the reason is non-obvious:

RAW_BUFFERClick to expand / collapse

Context

Related to but distinct from #59500. This issue is about the recovery primitive specifically.

I've been building khimaira-chat, a multi-agent orchestration MCP server. We declare tools.listChanged=True in ServerCapabilities as forward-compat groundwork — see packages/khimaira-chat/src/khimaira_chat/server.py:889.

Symptom

notifications/tools/list_changed is documented as the mechanism for an MCP server to signal that its tool list has changed at runtime. We initially thought this would recover the "subprocess is running stale code after package upgrade" case. It doesn't, and the reason is non-obvious:

When the OLD subprocess (still running old Python code) emits tools/list_changed, it can only re-announce its tool list — which is the OLD list. Claude Code re-fetches; gets the same OLD answer. No recovery.

This is a Python-subprocess-stale-module-cache problem, not a runtime-tool-registry-mutation problem. tools/list_changed is the right primitive for the latter, not the former.

Why this is worth documenting

The distinction is not surfaced anywhere in the MCP spec or Claude Code docs I could find. We spent meaningful debugging time assuming tools/list_changed would help our specific case before realizing the architectural mismatch.

Extended comment we left in our codebase capturing the lesson:

Note: that's a SUBPROCESS-STALE-CODE problem, not a runtime-tool-list-change problem. tools/list_changed from the OLD subprocess wouldn't help — it would re-announce its OLD list. The actual fix for that case is subprocess restart (close+reopen Claude Code window).

(From server.py:852-858)

What would help

Documentation clarifying:

  • tools/list_changed is for dynamic tool registry mutations within a single subprocess lifetime (e.g., a server that registers/unregisters tools based on runtime state)
  • It is not a recovery primitive for stale-subprocess-code scenarios
  • Backing-package upgrades require subprocess restart, period

Even a one-paragraph note in the MCP server docs would have saved us the debugging cycle.

Happy to provide

  • The full chain of debugging that led us to the realization
  • Specific commit/comment references in our codebase documenting the trap

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix tools/list_changed cannot recover stale Python subprocess code