model_tools.py ran discover_mcp_tools() as a module-level side effect.
discover_mcp_tools() uses a blocking 120s wait internally (via
_run_on_mcp_loop -> future.result(timeout=120)).
The gateway lazy-imports run_agent -> model_tools on the first user
message, which happens inside the asyncio event loop thread. A slow or
unreachable MCP server therefore froze Discord shard heartbeats and
Telegram polling for up to 120s on the first message after gateway
start.
Fix: remove the module-level call. Every entry point now runs
discovery explicitly at its own startup, using the context-appropriate
blocking/non-blocking pattern:
- gateway/run.py: loop.run_in_executor(None, discover_mcp_tools)
before platforms start accepting traffic
- hermes_cli/main.py: inline (no event loop at CLI startup)
- tui_gateway/entry.py: inline (sync stdin loop, no event loop)
- acp_adapter/entry.py: inline before asyncio.run()
Closes #16856.
This commit is contained in:
@ -138,12 +138,18 @@ def _run_async(coro):
|
||||
|
||||
discover_builtin_tools()
|
||||
|
||||
# MCP tool discovery (external MCP servers from config)
|
||||
try:
|
||||
from tools.mcp_tool import discover_mcp_tools
|
||||
discover_mcp_tools()
|
||||
except Exception as e:
|
||||
logger.debug("MCP tool discovery failed: %s", e)
|
||||
# MCP tool discovery (external MCP servers from config) used to run here as
|
||||
# a module-level side effect. It was removed because discover_mcp_tools()
|
||||
# internally uses a blocking future.result(timeout=120) wait, and the
|
||||
# gateway lazy-imports this module from inside the asyncio event loop on
|
||||
# the first user message — freezing Discord/Telegram heartbeats for up to
|
||||
# 120s whenever any configured MCP server was slow or unreachable (#16856).
|
||||
#
|
||||
# Each entry point now runs discovery explicitly at its own startup:
|
||||
# - gateway/run.py -> start_gateway() uses run_in_executor
|
||||
# - cli.py, hermes_cli/* -> inline on startup (no event loop)
|
||||
# - tui_gateway/server.py -> inline on startup (no event loop)
|
||||
# - acp_adapter/server.py -> asyncio.to_thread on session init
|
||||
|
||||
# Plugin tool discovery (user/project/pip plugins)
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user