-
Notifications
You must be signed in to change notification settings - Fork 815
Description
Description
The Aspire MCP server enters an infinite tools/list request loop when the db-mcp container's tools become available. This causes VS Code to spin indefinitely on "list tools" and the Copilot CLI to intermittently fail to surface the db-mcp tools.
Environment
- Aspire CLI/SDK: 13.2.0-preview.1.26106.2
- VS Code: Insiders 1.110.0-insider
- OS: Windows
- MCP client: VS Code Copilot Chat + GitHub Copilot CLI
Reproduction Steps
- Create an Aspire app with a PostgreSQL resource that has a db-mcp sidecar container
- Start the AppHost (
aspire run --detach) - Connect the Aspire MCP server to VS Code or Copilot CLI
- Wait for the db-mcp container to register its tools
Observed Behavior
When the db-mcp container connects and registers its tools, the Aspire MCP server fires a notifications/tools/list_changed notification. The MCP client responds with a tools/list request, which the server handles. However, the server immediately fires another tools/list_changed notification, causing the client to request tools/list again — creating an infinite loop.
From the logs:
- 1,742
tools/listrequest handler calls in ~2 minutes 44 seconds - 1,740
Tool list changednotifications in the same period - The tool count oscillates between 14 (base) and 23 (base + 9 db-mcp tools), suggesting a race condition where the db-mcp tools are alternately visible and invisible during enumeration
- The loop only terminates when VS Code kills the MCP server process
Log excerpt (showing the tight loop):
2026-02-06 13:55:44.018 [info] Tool list changed, refreshing tools...
2026-02-06 13:55:44.018 [info] Discovered 14 tools
2026-02-06 13:55:44.020 [info] tools/list request handler completed.
2026-02-06 13:55:44.020 [info] tools/list request handler called.
2026-02-06 13:55:44.053 [info] Tool list changed, refreshing tools...
2026-02-06 13:55:44.053 [info] Discovered 23 tools
2026-02-06 13:55:44.054 [info] tools/list request handler completed.
2026-02-06 13:55:44.054 [info] tools/list request handler called.
2026-02-06 13:55:44.069 [info] Tool list changed, refreshing tools...
2026-02-06 13:55:44.069 [info] Discovered 14 tools
... (repeats 1740+ times over ~2m44s)
Termination stack trace:
System.OperationCanceledException: The operation was canceled.
at System.Threading.CancellationToken.ThrowOperationCanceledException()
at ModelContextProtocol.McpSessionHandler.SendMessageAsync()
at ModelContextProtocol.McpSessionHandler.HandleRequest()
at ModelContextProtocol.McpSessionHandler.HandleMessageAsync()
Additional Observations from Copilot CLI
In the Copilot CLI, the behavior manifests differently:
refresh_toolssometimes returns 14 tools, sometimes 23- When it returns 23, the db-mcp tool IDs are reported but calling them returns
No MCP client found for tool IDorAn error occurred invoking - The
tools_changed_noticeis either never delivered to the CLI client, or arrives with stale tool IDs
Expected Behavior
- The
notifications/tools/list_changednotification should fire once when the db-mcp tools stabilize, not on everytools/listresponse - The tool list should be consistent — if 23 tools are reported, all 23 should be callable
- No infinite loop between
tools/list_changed→tools/list→tools/list_changed
Possible Root Cause
It appears the server is firing tools/list_changed as a side effect of handling the tools/list request itself (perhaps re-enumerating proxied tools from the db-mcp container triggers a change detection). This creates a feedback loop: list → changed → list → changed → ...
A debounce or dirty-flag mechanism on the tools/list_changed notification would likely resolve this.
Attached Logs
Full VS Code MCP log (10,547 lines) is available — happy to attach if needed.