Skip to content

perf(cli): stop eager MCP discovery from blocking agent-capable startup#35397

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-616ea81c
May 30, 2026
Merged

perf(cli): stop eager MCP discovery from blocking agent-capable startup#35397
teknium1 merged 1 commit into
mainfrom
hermes/hermes-616ea81c

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Stops eager MCP discovery from freezing classic CLI startup (hermes chat, hermes -z) when a configured MCP server is slow or dead.

Companion to #35273, which fixed the same hang on the TUI path. This closes the non-TUI half: the classic CLI launcher (hermes_cli/main.py::_prepare_agent_startup) still ran discover_mcp_tools() synchronously, so a dead server blocked the prompt before it appeared.

Salvage of #35360 by @Sylw3ster, cherry-picked onto current main (authorship preserved).

Changes

  • hermes_cli/mcp_startup.py (new): one shared background discovery thread + wait_for_mcp_discovery(timeout=0.75) bounded join; cheap config probe skips the whole MCP stack for non-MCP users.
  • hermes_cli/main.py: chat/oneshot/rl background discovery; TUI/gateway/ACP/cron keep their own dedicated startup (no double-run).
  • cli.py: bounded wait before the first tool snapshot so fast servers still land.
  • tests/hermes_cli/test_mcp_startup.py (new): backgrounding, TUI skip, bounded-join, init-agent wait.

Validation

Infographic

pop-laboratory

@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-616ea81c vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9518 on HEAD, 9513 on base (🆕 +5)

🆕 New issues (5):

Rule Count
invalid-assignment 4
unresolved-import 1
First entries
tests/hermes_cli/test_mcp_startup.py:150: [invalid-assignment] invalid-assignment: Object of type `() -> None` is not assignable to attribute `_install_tool_callbacks` of type `def _install_tool_callbacks(self) -> None`
tests/hermes_cli/test_mcp_startup.py:151: [invalid-assignment] invalid-assignment: Object of type `() -> None` is not assignable to attribute `_ensure_tirith_security` of type `def _ensure_tirith_security(self) -> None`
tests/hermes_cli/test_mcp_startup.py:152: [invalid-assignment] invalid-assignment: Object of type `() -> Literal[True]` is not assignable to attribute `_ensure_runtime_credentials` of type `def _ensure_runtime_credentials(self) -> bool`
tests/hermes_cli/test_mcp_startup.py:11: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/hermes_cli/test_mcp_startup.py:147: [invalid-assignment] invalid-assignment: Object of type `object` is not assignable to attribute `_session_db` of type `None | SessionDB`

✅ Fixed issues: none

Unchanged: 4934 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@teknium1 teknium1 merged commit 0c6e133 into main May 30, 2026
23 checks passed
@teknium1 teknium1 deleted the hermes/hermes-616ea81c branch May 30, 2026 14:45
@alt-glitch alt-glitch added type/perf Performance improvement or optimization P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard tool/mcp MCP client and OAuth labels May 30, 2026
buptwz added a commit to buptwz/hermes-agent that referenced this pull request Jun 4, 2026
…vered

PR NousResearch#35397 introduced start_background_mcp_discovery() for hermes -z and
hermes chat paths so that slow MCP servers don't block the CLI prompt.
However it relied on a 0.75 s bounded wait_for_mcp_discovery() call in
cli.py's _init_agent(), which is only reached by the interactive chat
path — oneshot bypassed it entirely.

The previous ensure_mcp_discovered() would call discover_mcp_tools()
directly even when a background thread was already running it, risking
a concurrent double-connection attempt against the same servers.

Fix: detect the background thread via hermes_cli.mcp_startup and join()
it without a timeout (appropriate for non-interactive paths where there
is no prompt to display quickly).  Fall through to a direct synchronous
call only when no background thread exists (batch_runner, delegate_tool,
background_review, curator, etc.).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists tool/mcp MCP client and OAuth type/perf Performance improvement or optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants