Skip to content

fix(mcp): avoid UNC cwd warnings for Windows stdio servers on WSL - #8305

Open
liu-collab wants to merge 1 commit into
NousResearch:mainfrom
liu-collab:fix/wsl-windows-mcp-stdio-cwd
Open

fix(mcp): avoid UNC cwd warnings for Windows stdio servers on WSL#8305
liu-collab wants to merge 1 commit into
NousResearch:mainfrom
liu-collab:fix/wsl-windows-mcp-stdio-cwd

Conversation

@liu-collab

Copy link
Copy Markdown
Contributor

Summary

  • avoid WSL UNC cwd warnings corrupting stdio MCP traffic when Hermes launches Windows executables like cmd.exe
  • auto-select a Windows-mounted fallback cwd for WSL stdio MCP servers when no explicit mcp_servers.<name>.cwd is configured
  • document the new cwd option and the WSL /root startup failure mode for Windows-backed MCP servers

Problem

When Hermes runs inside WSL and an MCP stdio server is configured with a Windows executable such as cmd.exe, launching Hermes from a Linux-only WSL path like /root can break the MCP connection before the server even starts.

In the reproduced setup:

  • Hermes ran inside WSL Ubuntu as root
  • browser automation used chrome-devtools-mcp via cmd.exe /c npx ...
  • Hermes was started from /root

That caused Windows interop to emit this warning on stdout:

'\\wsl.localhost\Ubuntu\root'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.

Because stdio MCP requires stdout to be protocol-only, those extra lines corrupted the transport and Hermes showed the MCP server as failed at startup.

Design

I fixed this in the stdio MCP launch layer rather than in a one-off browser integration because the failure is generic to any WSL -> Windows executable stdio server.

Implementation details:

  • keep honoring explicit mcp_servers.<name>.cwd if the user sets one
  • detect WSL with the existing shared hermes_constants.is_wsl() helper
  • detect Windows executables (.exe, .cmd, .bat, .com)
  • when Hermes is on WSL and the stdio command is a Windows executable, pick a safe Windows-mounted cwd automatically if none was configured
  • candidate fallbacks are:
    • /mnt/c/Users/$USERNAME
    • /mnt/c/Users/$WIN_USERNAME
    • /mnt/c/Users/Administrator
    • /mnt/c/Users
    • /mnt/c

This keeps normal Linux stdio servers unchanged and avoids touching command strings or wrapping processes in shell glue.

Verification

Targeted tests:

  • uv run python -m pytest tests/tools/test_mcp_tool_issue_948.py -q

Manual repro / regression checks:

  • from /root, hermes_cli/main.py mcp test chrome-devtools-win now connects successfully
  • from /root, hermes_cli/main.py chat ... mcp_chrome_devtools_win_list_pages now succeeds instead of failing at startup due to the UNC warning

Notes

This came from a real WSL + Windows Chrome bridge setup where Hermes in WSL was driving a live Windows Chrome session via chrome-devtools-mcp.

@liu-collab
liu-collab force-pushed the fix/wsl-windows-mcp-stdio-cwd branch from e51d1f2 to 2e98f60 Compare April 12, 2026 10:27
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists tool/mcp MCP client and OAuth labels Apr 28, 2026
@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing a real WSL-to-Windows MCP failure mode. Current main still creates StdioServerParameters without a cwd at tools/mcp_tool.py:2068, and its docs still require a /mnt/c launch path (website/docs/guides/use-mcp-with-hermes.md:183).

Problems

  • The added assertion at tests/tools/test_mcp_tool_issue_948.py:153 is incompatible with current main: _run_stdio() wraps POSIX commands with mcp_stdio_watchdog.py at tools/mcp_tool.py:2066, so StdioServerParameters.command is sys.executable, not cmd.exe.
  • The docs update misses the companion config reference (website/docs/reference/mcp-config-reference.md:48-50) and leaves conflicting WSL workaround guidance in website/docs/guides/use-mcp-with-hermes.md:183 and website/docs/user-guide/windows-wsl-quickstart.md:191,330.

Suggested changes

  • Update the regression test to assert the watchdog wrapper and its forwarded cmd.exe target while retaining the cwd assertion.
  • Update the config reference and existing WSL guidance alongside the feature guide.

Automated hermes-sweeper review.

await server.start({"command": "cmd.exe", "args": ["/c", "echo", "ok"]})

call_kwargs = mock_params.call_args.kwargs
assert call_kwargs["command"].endswith("cmd.exe")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current main wraps POSIX stdio commands through sys.executable tools/mcp_stdio_watchdog.py ... -- <real-command> at tools/mcp_tool.py:2066. On WSL this assertion should instead verify the wrapper command and assert that cmd.exe appears after --; keep the cwd assertion to cover this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows tool/mcp MCP client and OAuth type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants