fix(mcp): resolve bare npx/npm/node against nvm/fnm/volta install dirs - #67873
fix(mcp): resolve bare npx/npm/node against nvm/fnm/volta install dirs#67873HaoNgo232 wants to merge 4 commits into
Conversation
Node installed via a version manager (nvm, fnm, volta) lives outside the Hermes daemon PATH, so a bare `command: npx` MCP server fails with ENOENT at execvp on every Linux distro and macOS. Extend `_resolve_stdio_command` candidates with `_node_version_manager_dirs()` and add a regression test.
There was a problem hiding this comment.
Pull request overview
This PR aims to make stdio MCP servers configured with bare Node.js commands (npx/npm/node) start reliably when Node is installed via version managers (nvm/fnm/volta), by extending _resolve_stdio_command()’s fallback candidate list to include version-manager install directories.
Changes:
- Add
_node_version_manager_dirs()to enumerate likely Node binary directories from common version managers. - Extend
_resolve_stdio_command()to try those directories when resolving barenpx/npm/node. - Add a regression test covering the new nvm fallback behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tools/mcp_tool.py | Adds version-manager directory discovery and uses it as additional fallback candidates for resolving bare npx/npm/node. |
| tests/tools/test_mcp_tool_issue_948.py | Adds a regression test intended to validate the new nvm fallback path resolution behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Extends regression coverage for the version-manager fallback beyond nvm to fnm (~/.fnm/node-versions/<v>/installation/bin) and volta (~/.volta/bin), confirming _node_version_manager_dirs() resolves all three.
Related to merged #34186: this adds the missing nvm/fnm/Volta installation roots to its existing stdio MCP command-resolution fallback. |
nvm installs under ~/.nvm/versions/node/<version>/bin (and rarely io.js), not ~/.nvm/versions/<version>/bin. The previous layout skipped the 'node' segment, so the fallback never triggered for real nvm installs. Also sort version entries for deterministic resolution. Updates the regression test to model nvm's actual layout so it no longer passes against a broken fallback.
|
Thanks @copilot — you were right. nvm installs under Fixed in e4170f6:
All 10 tests in |
The version is arbitrary (the resolver scans all versions dynamically); v20.0.0 avoids implying support is limited to one version.
|
Thanks for the focused MCP resolver fix. The premise remains valid on current main: The final diff correctly incorporates the earlier nvm-layout correction by traversing Automated hermes-sweeper review. |
Summary
A bare
command: npx(ornpm/node) MCP server fails to start with:when Node.js is installed via a version manager. The root cause is that the Hermes daemon runs MCP servers with a fixed
PATHthat does not source shell rc files, so the version-manager install dirs are invisible to it. This is not distro-specific — it reproduces on any Linux distro and macOS wherever Node lives under a version manager, because the failure is purely a PATH-resolution issue, independent of the distro.#34186already added fallback candidates for$HERMES_HOME/node/bin,~/.local/bin, and/usr/local/bin, but none of those cover the version-manager install locations that interactive dev machines almost always use. So the failure persists for the common setups.Fix
Extend
_resolve_stdio_command's candidate list with_node_version_manager_dirs(), which collects:~/.nvm/versions/<version>/bin(one dir per installed version)~/.fnm/node-versions/<version>/installation/bin~/.volta/binThe resolver still prepends the resolved dir to
PATH(existing behavior), so npx's/usr/bin/env nodeshebang finds node in the same directory. The change is surgical: it only activates when the bare command isn't otherwise locatable through the user's PATH or the existing candidates.This also makes the manual
~/.local/binsymlink workaround (used until now) unnecessary for version-manager users.Test plan
Regression tests added in
tests/tools/test_mcp_tool_issue_948.py, mirroring the existing/usr/local/binfallback test, one per version manager:test_resolve_stdio_command_falls_back_to_nvmtest_resolve_stdio_command_falls_back_to_fnmtest_resolve_stdio_command_falls_back_to_voltaFull file:
uv run pytest tests/tools/test_mcp_tool_issue_948.py→ 10 passed.Verification note
Verified on: Linux Mint 22 (kernel 6.8), nvm Node v22.21.1. The fnm and volta paths are covered by the new unit tests (which construct the exact install-dir layouts those managers use). The distro-independence claim rests on the PATH-resolution mechanism, not on any distro-specific path.
Related
hermes doctor).