Skip to content

fix(tools): resolve uv/uvx MCP commands under GUI-style PATHs (fixes #37589) - #37665

Open
Morad37 wants to merge 1 commit into
NousResearch:mainfrom
Morad37:fix/37589-mcp-uvx-fallback
Open

fix(tools): resolve uv/uvx MCP commands under GUI-style PATHs (fixes #37589)#37665
Morad37 wants to merge 1 commit into
NousResearch:mainfrom
Morad37:fix/37589-mcp-uvx-fallback

Conversation

@Morad37

@Morad37 Morad37 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes bare command: uv / command: uvx MCP server configs from Hermes Desktop on macOS. The Hermes Desktop app inherits a minimal LaunchAgent PATH (/usr/bin:/bin:/usr/sbin:/sbin) that doesn't include ~/.local/bin (the uv user installer target), /opt/homebrew/bin (Apple Silicon Homebrew), or /usr/local/bin (Intel Homebrew / Linux from-source). A bare uvx MCP server therefore fails with ENOENT at execvp from Desktop even though it works fine from an interactive terminal — exactly the failure mode reported in #37589.

Changes

  • tools/mcp_tool.py (_resolve_stdio_command)
    • Added uv and uvx to the bare-command candidate allowlist (was only npx/npm/node before).
    • Added $HERMES_HOME/bin/<cmd> as a candidate for managed uv/uvx (from refactor(uv): single managed-uv path, delete fts5 installer escalation #37660). Managed uv is preferred over ~/.local/bin, Homebrew, etc. so MCP servers use the same uv as the CLI update path.
    • Added a new /opt/homebrew/bin/<cmd> candidate for the Apple Silicon Homebrew case (brew install uv). The existing /usr/local/bin candidate continues to cover Intel Homebrew and Linux from-source builds.
    • Candidate ordering: Hermes-bundled Node → managed uv ($HERMES_HOME/bin) → ~/.local/bin/opt/homebrew/bin/usr/local/bin.
  • tests/tools/test_mcp_tool_issue_948.py
    • New test: test_resolve_stdio_command_finds_uvx_in_user_local_bin — covers the dominant install location for uv on Apple Silicon / Ubuntu.
    • New test: test_resolve_stdio_command_uvx_unchanged_when_already_on_path — ensures shutil.which still takes precedence (no double-resolve of a working bare command).
    • New test: test_resolve_stdio_command_skips_unknown_commands — negative test that catches the inverse regression of someone widening the allowlist so far that a bare command: my-tool gets rewritten to a coincidentally-named file at /opt/homebrew/bin/my-tool.
    • New test: test_resolve_stdio_command_prefers_managed_uv — verifies that $HERMES_HOME/bin/uv wins over a stale ~/.local/bin/uv (cross-reference with refactor(uv): single managed-uv path, delete fts5 installer escalation #37660).
    • The 4 existing npx tests continue to pass unchanged.

How to test

  1. ~/.hermes/hermes-agent/venv/bin/python -m pytest tests/tools/test_mcp_tool_issue_948.py -q --timeout=60 — 9/9 pass.
  2. ~/.hermes/hermes-agent/venv/bin/python -m pytest tests/tools/ -q --timeout=60 -k "mcp" — no regressions in the broader MCP test surface.

Notes

  • The CLI / TUI paths were never affected (they inherit a full terminal PATH). This is a Desktop/launchd-only fix.
  • Sandbox / docker config can still pass an explicit env.PATH and the resolver will still honour it via _prepend_path. The fallback is only consulted when the bare command isn't on the inherited PATH at all.
  • No change to behaviour for any command outside the npx/npm/node/uv/uvx allowlist — random bare commands like python or my-tool are left alone (the new negative test pins this).
  • The managed-uv candidate ($HERMES_HOME/bin) was added in coordination with refactor(uv): single managed-uv path, delete fts5 installer escalation #37660, which introduced managed uv at that location. Without it, MCP servers on Desktop would fall back to a stale ~/.local/bin or brew-managed uv instead of the hermes-managed one.

Closes #37589

…ousResearch#37589)

_tools/mcp_tool._resolve_stdio_command_ already fell back to ~/.local/bin
and /usr/local/bin for bare npx/npm/node MCP commands on
filtered PATHs (the docker sandbox case), but it did NOT cover uv
and uvx — the dominant Python MCP server runtime. On macOS,
Hermes Desktop inherits a minimal LaunchAgent PATH
(/usr/bin:/bin:/usr/sbin:/sbin) that omits ~/.local/bin (the
uv user installer target), /opt/homebrew/bin (Apple Silicon
Homebrew), and /usr/local/bin (Intel Homebrew / Linux from-source).
A bare command: uvx MCP server therefore fails with ENOENT at
execvp from Hermes Desktop even though it works from an interactive
terminal.

This adds uv and uvx to the candidate allowlist, plus a new
/opt/homebrew/bin candidate for the Apple Silicon case. Existing
ordering is preserved (~/.local/bin before /opt/homebrew/bin before
/usr/local/bin), so users with multiple installs continue to resolve
to whichever the user installed first.

Tests: 4 new tests in test_mcp_tool_issue_948.py cover the ~/.local/bin
fallback, shutil.which preemption, an unknown-command negative case
(catches the inverse regression of someone adding a too-broad allowlist
that rewrites bare my-tool to a coincidentally-named file), and
the existing npx tests continue to pass.

Closes NousResearch#37589
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists tool/mcp MCP client and OAuth python:uv Pull requests that update python:uv code labels Jun 2, 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 isolating the remaining launchd-PATH half of #37589. The current-main resolver still only falls back for npx/npm/node at tools/mcp_tool.py:591, so extending the allowlist is a valid fix direction.

Problems

  • The PR body says managed uv/uvx at $HERMES_HOME/bin is preferred, but the actual candidate list in PR head f4ce36cd4724 (tools/mcp_tool.py:423-454) has no $HERMES_HOME/bin/<cmd> entry. This leaves a managed-only uv unavailable under the filtered Desktop PATH, despite Hermes defining that managed location in hermes_cli/managed_uv.py:1-50.

Suggested changes

  • Add the managed-bin candidate before ~/.local/bin, and add a regression test that it wins over a stale local install. Please also exercise the new /opt/homebrew/bin candidate.

Automated hermes-sweeper review.

Comment thread tools/mcp_tool.py
if which_hit:
resolved_command = which_hit
elif resolved_command in {"npx", "npm", "node"}:
elif resolved_command in {"npx", "npm", "node", "uv", "uvx"}:

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.

Please add $HERMES_HOME/bin/<cmd> to this fallback list before ~/.local/bin. The PR description promises managed uv preference, and hermes_cli/managed_uv.py:1-50 defines $HERMES_HOME/bin/uv as Hermes’s authoritative managed location; it is absent from this PR head’s candidates.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

hope to solve asap,when config mcp, it is difficult.

@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 13, 2026
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 python:uv Pull requests that update python:uv code 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.

Desktop sessions miss configured MCP tools and uvx servers can fail under macOS GUI PATH

4 participants