jackwener/maka-agent

mcp: tool discovery livelocks against a server that notifies list_changed after every tools/list

オープン

#2,981 opened on 2026/08/13

 (0 件のコメント) (0 件のリアクション) (0 人の担当者)TypeScript (0 件のフォーク)github user discovery
bughelp wanted

Repository metrics

Stars
 (1 個のスター)
PR merge metrics
 (PR metrics pending)

説明

Context

A server that emits tools/list_changed after every tools/list response livelocks tool discovery. Each notification schedules another discovery pass, whose response triggers the next notification, with no bound on the loop.

Measured with a probe server that notifies on every list: ~2000 tools/list round trips in 4 seconds, sync() never settling, and the manager unable to remove that server from the configuration — the removal sync queues behind a discovery that never finishes.

This is pre-existing, not a regression. I found it while reviewing #2663 and initially took it for a regression from installing the change handler before initial discovery; it is not. The same probe against origin/main produces the same ~2000-iteration loop. Noted in that review as out of scope there.

Severity

P2. Unlike most items in this class, something on main genuinely misbehaves rather than merely lacking protection: discovery hangs and configuration reconciliation stalls behind it. Held at P2 because triggering requires a server that notifies on every list — real servers notify on actual change — and it self-recovers the moment the server stops notifying. It has been in place a long time with no report.

Fix

Bound the rediscovery loop. Options, roughly in order of preference:

  1. Debounce list_changed — collapse notifications that arrive while a discovery for the same server is in flight or within a short window after it completes.
  2. Cap consecutive rediscoveries per connection generation, then stop honouring further notifications and surface the server as degraded.
  3. At minimum, let a pending configuration sync preempt an in-flight discovery, so a misbehaving server can always be removed.

(3) is worth having regardless of (1) and (2): the manager should never be unable to drop a server.

Verification

A probe server whose tools/list handler schedules sendToolListChanged() on every call. Assert that list round trips stay bounded, that sync() settles, and that a follow-up sync() removing the server completes.

コントリビューターガイド