Skip to content

MCP tools load in CLI sessions but not in desktop/TUI sessions (slash_worker subprocess) #61891

Description

@pearonjames

Summary

MCP servers configured in config.yaml with enabled: true are fully functional in hermes chat CLI sessions (65 tools registered, callable) but are completely absent from the toolset in desktop app / TUI sessions served by hermes serve. The agent has no MCP tools available and cannot call them.

Impact: This effectively makes MCP servers unusable from the desktop app, which is the primary interface for non-CLI users. The server is configured, healthy, and reports as enabled — but the agent simply has no access to its tools.

Environment

  • Hermes Agent: 0.18.2 (build 2026.7.7.2, upstream f8361d2)
  • Platform: WSL2 (Ubuntu), desktop Electron app connecting to hermes serve backend
  • MCP server: zotero-mcp-server 0.6.1 (stdio transport, FastMCP 3.4.4)
  • Session type where it works: hermes chat (CLI, one-shot)
  • Session type where it fails: Desktop app → hermes servetui_gateway.slash_worker

Reproduction

  1. Configure an MCP server in config.yaml (any stdio server — Zotero in my case)
  2. Verify it works: hermes chat "use zotero_search_items to find X" — MCP tools load, call succeeds
  3. Open the desktop app (or any TUI session via hermes serve)
  4. Ask the agent to use the same MCP tool — it doesn't appear in the toolset; the agent has no way to call it

hermes mcp list reports ✓ enabled in both cases — the discrepancy is between config state and runtime tool loading.

Evidence from agent.log

CLI sessions — MCP discovery runs before every turn, 65 tools register:

00:04:56 INFO tools.mcp_tool: MCP server 'zotero' (stdio): registered 65 tool(s)
00:04:56 INFO tools.mcp_tool: MCP: registered 65 tool(s) from 1 server(s)
00:04:58 INFO agent.turn_context: conversation turn: session=... platform=cli history=0

TUI sessions — no MCP registration at all, turn proceeds with zero MCP tools:

00:19:53 INFO agent.turn_context: conversation turn: session=... platform=tui history=328

Every platform=cli turn in the log is preceded by an MCP registration line. No platform=tui turn has one.

Proposed root cause (analysis, not confirmed)

This appears to be a process-boundary gap in how hermes serve delegates to tui_gateway.slash_worker.

The parent hermes serve process runs MCP discovery at startup via tui_gateway/entry.py (lines 325–347), which spawns a tui-mcp-discovery background thread calling discover_mcp_tools(). This populates the parent's in-memory tool registry.

Each conversation session, however, runs in a child subprocess (python3 -m tui_gateway.slash_worker --session-key ... --model ...). The slash_worker creates its own HermesCLI instance, which eventually calls get_tool_definitions(). That wrapper (cli.py ~line 844) calls wait_for_mcp_discovery() — but in the subprocess, _mcp_discovery_thread is None (nobody called start_background_mcp_discovery() in this process), so the wait returns immediately. model_tools.get_tool_definitions() then builds the tool list from a registry that has no MCP tools, because discover_mcp_tools() was never called in the slash_worker's process.

Standalone CLI sessions work because each hermes chat invocation runs start_background_mcp_discovery() on its own startup path, within its own process.

The relevant code path in slash_worker.py (lines 133–134):

with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
    cli = HermesCLI(model=args.model or None, compact=True, resume=args.session_key, verbose=False)

No MCP discovery is triggered here or anywhere else in the slash_worker lifecycle.

Process layout (observed)

PID Command Parent Role
3051 hermes serve --host 0.0.0.0 --port 9119 TUI gateway (has MCP tools in its registry)
19116 tui_gateway.slash_worker --session-key ... 3051 Session subprocess (no MCP tools)

Notes

  • The MCP server itself is healthy — mcp-stderr.log shows clean startup/shutdown cycles with no errors on recent entries.
  • Credentials are intact in config.yaml (not redacted by the secret sanitizer).
  • hermes mcp list reads config, not the runtime tool registry, so it reports ✓ enabled regardless.
  • This likely affects all MCP servers, not just Zotero — any stdio/SSE/HTTP MCP server configured in config.yaml would be absent from TUI sessions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/agentCore agent runtime: loop, agent_init, prompt builder, context-compression, responses endpointcomp/desktopElectron desktop app (apps/desktop/*)comp/tuiTerminal UI (ui-tui/ + tui_gateway/)tool/mcpMCP client and OAuthtype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions