fix(mcp): ensure MCP discovery completes before agent build in non-interactive sessions - #75933
Merged
kshitijk4poor merged 1 commit intoAug 1, 2026
Conversation
…teractive sessions Non-interactive sessions (hermes chat -q, hermes -z) snapshot the tool registry at AIAgent construction time. If background MCP discovery hasn't finished, MCP tools are invisible for the entire session — and unlike interactive mode, there is no between-turns late-binding refresh to recover. Root cause: wait_for_mcp_discovery() only joins an already-created discovery thread, so it no-ops if a direct/single-query path reaches agent construction before MCP startup created that thread. Oneshot._run_agent() didn't call it at all. Fix: - Add ensure_mcp_discovery_before_agent_build() helper to mcp_startup.py: idempotently starts discovery if needed + bounded wait. Fail-open on errors. - Add single_query parameter to _resolve_discovery_timeout/wait_for_mcp_discovery: uses mcp_single_query_discovery_timeout (default 15s) instead of the interactive mcp_discovery_timeout (1.5s) because one-shot sessions have no second turn to recover. - Wire into CLI _init_agent (single_query from _single_query_mode flag set in cli.py's single-query path) and oneshot._run_agent (single_query=True). - Interactive sessions unchanged: keep 1.5s bound (between-turns refresh covers). Closes NousResearch#38448, NousResearch#51316, NousResearch#37013, NousResearch#68137 Composite salvage of NousResearch#60017 (chrishart0), NousResearch#51322 (Bartok9), NousResearch#38620 (buptwz), NousResearch#43544 (halonke), NousResearch#36882 (vanhoof).
kshitijk4poor
enabled auto-merge (rebase)
August 1, 2026 06:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Non-interactive sessions (
hermes chat -q,hermes -z) now wait for MCP discovery to complete before building the agent, so configured MCP tools are visible in the one and only model turn instead of silently dropped.Root cause:
wait_for_mcp_discovery()only joins an already-created discovery thread — it no-ops if a direct/single-query path reaches agent construction before MCP startup created that thread.oneshot._run_agent()didn't call it at all. Interactive sessions recovered via between-turns late-binding refresh, but one-shot sessions have no second turn.Changes
hermes_cli/mcp_startup.py: Newensure_mcp_discovery_before_agent_build()helper — idempotently starts discovery if needed + bounded wait. Addedsingle_queryparam to_resolve_discovery_timeout()andwait_for_mcp_discovery()to use the largermcp_single_query_discovery_timeoutbound (default 15s) for one-shot sessions.hermes_cli/config_defaults.py: Newmcp_single_query_discovery_timeoutconfig key (default 15.0s). Interactivemcp_discovery_timeoutunchanged at 1.5s.hermes_cli/cli_agent_setup_mixin.py:_init_agentcallsensure_mcp_discovery_before_agent_build()instead of barewait_for_mcp_discovery(), forwardingsingle_queryfrom_single_query_mode.cli.py: Setscli._single_query_mode = Truein the single-query (-q/-z) path.hermes_cli/oneshot.py:_run_agentcallsensure_mcp_discovery_before_agent_build(single_query=True)before AIAgent construction.tests/hermes_cli/test_mcp_discovery_timing.py: 12 regression tests covering timeout resolution, helper behavior, ordering, bounded wait, and single_query flag forwarding.Why two timeout bounds
Interactive sessions keep 1.5s because the between-turns late-binding refresh (
agent/turn_context.py) picks up late-arriving MCP tools on the next turn. Single-query sessions have ONE turn — no refresh — so 15s gives slow cold-start servers (npx, uvx, remote HTTP) a chance to land.thread.join(timeout)returns the instant discovery completes, so fast servers pay ~0s regardless.Validation
hermes -z "use mcp__server__tool"hermes chat -q "prompt"_single_query_modehermes chat12 new tests pass. 10 existing MCP startup/refresh tests pass. E2E verified with real imports.
Credits
Composite salvage of 5 community PRs, each of which identified the same bug class from a different entry point:
ensure_mcp_discovery_before_agent_build()helper concept_single_query_modeflagmcp_startupentirelyCloses #38448
Closes #51316
Closes #37013
Closes #68137