fix(dashboard): start background MCP discovery for dashboard-hosted chat sessions - #43189
jacobcwright wants to merge 1 commit into
Conversation
f2efd71 to
beca730
Compare
…hat sessions Chat sessions hosted by `hermes dashboard` run on the web server's in-memory tui_gateway — the chat PTY attaches via HERMES_TUI_GATEWAY_URL instead of spawning its own gateway, so tui_gateway.entry's startup MCP discovery never runs in that process. The messaging gateway (gateway/run.py) and the standalone CLI TUI both call discover_mcp_tools() at startup; the dashboard path never did. Result: configured `mcp_servers` silently contribute zero tools to dashboard/desktop sessions. The enabled-toolset resolution correctly includes the MCP server names, but the tool registry has nothing to hand out, so they're dropped without a trace until a manual `/reload-mcp`. Fix: - web_server lifespan starts the shared background discovery helper (hermes_cli.mcp_startup) — config-gated and backgrounded, so dashboards with no MCP servers pay neither the MCP-SDK import nor a thread, and a slow/dead server can't block startup. - tui_gateway _make_agent additionally joins the shared mcp_startup thread (bounded), mirroring the existing entry.py wait, so the first agent build in a dashboard process picks up fast-connecting servers. Repro: register any stdio MCP server (`hermes mcp add ...`), open a chat from the dashboard/desktop app, ask the agent to list its tools — no mcp_* tools appear; `/reload-mcp` makes them appear. With this fix they are present from the first session.
beca730 to
61b9f17
Compare
|
I applied the change from this PR locally on a Hermes Desktop/Dashboard installation, and it appears to fix the issue in practice. What was applied locally:
Observed result after restarting the Desktop/Dashboard session:
Environment tested:
Local verification:
On behalf of Sancho, a Hermes Agent |
Duplicate of #42703 — same fix: start background MCP tool discovery for dashboard/Desktop-hosted chat sessions so they aren't built with an empty MCP tool list (the |
|
Superseded by PR #44512 — #44512 implements the same fix this PR proposes: Thanks for the fix — closing as redundant. Credit to you and the other contributors who independently caught this (#42703, #43189, #40407 all targeted the same gap). |
Problem
Chat sessions hosted by
hermes dashboard(the web UI / desktop-app remote backend) never see configured MCP servers' tools.The dashboard's chat PTY attaches to the web server process's in-memory tui_gateway via
HERMES_TUI_GATEWAY_URLinstead of spawning its own gateway, sotui_gateway/entry.py's startup MCP discovery never runs in that process. The other two entrypoints both run discovery at startup:gateway/run.py→discover_mcp_tools()tui_gateway/entry.py:main()→ backgroundeddiscover_mcp_tools()The dashboard path never did. The failure is silent and confusing:
_get_platform_tools(cfg, "cli", include_default_mcp_servers=True)correctly resolves the MCP server names into the enabled-toolset list, but the tool registry has no MCP tools to hand out, so the agent is built without them — no warning anywhere. A manual/reload-mcpfixes the live session (and is how we confirmed the cause), but it's needed again after every restart.Repro
hermes mcp add <any stdio server> ...hermes dashboard, open a chat (web or desktop app)mcp_*tools;/reload-mcpmakes them appearConfirmed on a Fly.io deployment running the gateway and dashboard side by side: the gateway process had all 7 configured MCP stdio servers as children; the dashboard process had none.
Fix
hermes_cli/web_server.py: the lifespan now starts the existing shared background-discovery helper (hermes_cli.mcp_startup.start_background_mcp_discovery). It's config-gated (no MCP servers configured → no MCP-SDK import, no thread) and backgrounded (a slow/dead server can't block dashboard startup), same as the CLI path.tui_gateway/server.py:_make_agent: in addition to the existingtui_gateway.entrywait, briefly join the sharedmcp_startupthread (bounded) so the first agent build in a dashboard process picks up fast-connecting servers. Each wait is a no-op when its thread was never started.Tests
Two regression tests in
tests/hermes_cli/test_mcp_startup.py: lifespan starts discovery when servers are configured; skips entirely when none are. Rantests/hermes_cli/test_mcp_startup.py(6 passed),tests/hermes_cli/test_web_server.py(211 passed),tests/tui_gateway/test_wait_for_mcp_discovery.py+test_make_agent_provider.py(11 passed).