fix(mcp): announce a disabled parked entry once, not per self-probe wake

The enabled:false gate on the parked self-probe logged an INFO line on
every wake, which on a 300 s timer is the same unbounded stream the gate
exists to end; the pause is announced once and repeats go to DEBUG. Tests
trimmed to two invariants driving the real park loop.
This commit is contained in:
teknium1
2026-09-19 22:05:28 -07:00
committed by Teknium
parent 67737c37f8
commit 6ea3fe06b0
2 changed files with 14 additions and 9 deletions

View File

@@ -19,10 +19,13 @@ import pytest
from tools.mcp_tool import MCPServerTask
def _fast_time(monkeypatch):
"""Zero out the retry sleeps and the parked self-probe interval."""
def _fast_time(monkeypatch, tmp_path):
"""Zero out the retry sleeps and the parked self-probe interval; keep ``blender``
enabled in the temp home's config.yaml so the self-probe gate lets it wake."""
from tools import mcp_tool
(tmp_path / "config.yaml").write_text(
"mcp_servers:\n blender:\n command: x\n", encoding="utf-8")
monkeypatch.setattr(mcp_tool, "_PARKED_RETRY_INTERVAL", 0)
real_sleep = asyncio.sleep
@@ -42,7 +45,7 @@ def test_reparked_server_logs_once_not_per_probe(monkeypatch, tmp_path, caplog):
from tools import mcp_tool
monkeypatch.setattr(mcp_tool, "_MAX_INITIAL_CONNECT_RETRIES", 1)
_fast_time(monkeypatch)
_fast_time(monkeypatch, tmp_path)
state = {"calls": 0}
@@ -92,7 +95,7 @@ def test_park_after_revival_warns_again(monkeypatch, tmp_path, caplog):
monkeypatch.setattr(mcp_tool, "_MAX_INITIAL_CONNECT_RETRIES", 1)
monkeypatch.setattr(mcp_tool, "_MAX_RECONNECT_RETRIES", 1)
_fast_time(monkeypatch)
_fast_time(monkeypatch, tmp_path)
state = {"calls": 0}

View File

@@ -202,6 +202,7 @@ class MCPServerRunMixin:
self._park_reason = revival_reason
self._deregister_tools()
self._reconnect_event.clear()
paused = False
while True:
outcome = await self._wait_for_reconnect_or_shutdown(
timeout=_core._PARKED_RETRY_INTERVAL)
@@ -213,12 +214,13 @@ class MCPServerRunMixin:
# the process (background loops that do not run the gateway reconcile tick
# never learn the entry changed). An explicit reconnect request — manual
# refresh or `hermes mcp login` — still revives immediately regardless of the
# config gate; only the unattended probe honours it.
# config gate; only the unattended probe honours it. Announce the pause once:
# a line per skipped wake would be the very flood this gate exists to stop.
if outcome == "self-probe" and not self._still_configured_enabled():
logger.info(
"MCP server '%s': skipping self-probe revival — entry is disabled or "
"gone from mcp_servers config",
self.name)
(logger.debug if paused else logger.info)(
"MCP server '%s': parked entry is disabled or gone from mcp_servers; pausing the "
"self-probe until it is re-enabled", self.name)
paused = True
continue
# Nobody asked for this revival: a self-probe must never open a browser OAuth flow. The
# OAuth provider runs inside THIS task (the SDK's auth flow sits in the transport), so a