Skip to content

fix: resolve npx/node PATH on macOS GUI apps - #113

Merged
its-mash merged 4 commits into
mainfrom
claude/fix-mcp-npx-mac-dxoey
Feb 18, 2026
Merged

fix: resolve npx/node PATH on macOS GUI apps#113
its-mash merged 4 commits into
mainfrom
claude/fix-mcp-npx-mac-dxoey

Conversation

@its-mash

Copy link
Copy Markdown
Member

macOS GUI apps launched from Finder/Dock/Spotlight inherit a minimal
PATH (/usr/bin:/bin:/usr/sbin:/sbin) that excludes tools installed via
Homebrew (/opt/homebrew/bin), nvm, Volta, fnm, or /usr/local/bin.
This caused "Command not found: npx" errors even when npx was properly
installed and worked in terminal.

Add shell_env module that spawns the user's login shell ($SHELL -l -i -c)
to resolve their fully-initialized PATH including entries from .zshrc,
.bashrc, nvm init, Volta setup, etc. The result is cached via OnceLock.

Changes:

  • New shell_env module resolves user's full PATH on Unix (no-op on Windows)
  • StdioTransport uses which::which_in() with shell PATH for command lookup
  • Shell PATH is injected into child process env so spawned processes
    (e.g., npx finding node) also get the full PATH
  • Falls back gracefully if shell resolution fails
  • Respects user-set PATH in env overrides

Signed-off-by: Claude noreply@anthropic.com

https://claude.ai/code/session_01EYZVAqzgNBAAtJptw9KRwB
Signed-off-by: Claude noreply@anthropic.com

claude and others added 4 commits February 17, 2026 15:27
macOS GUI apps launched from Finder/Dock/Spotlight inherit a minimal
PATH (/usr/bin:/bin:/usr/sbin:/sbin) that excludes tools installed via
Homebrew (/opt/homebrew/bin), nvm, Volta, fnm, or /usr/local/bin.
This caused "Command not found: npx" errors even when npx was properly
installed and worked in terminal.

Add shell_env module that spawns the user's login shell ($SHELL -l -i -c)
to resolve their fully-initialized PATH including entries from .zshrc,
.bashrc, nvm init, Volta setup, etc. The result is cached via OnceLock.

Changes:
- New shell_env module resolves user's full PATH on Unix (no-op on Windows)
- StdioTransport uses which::which_in() with shell PATH for command lookup
- Shell PATH is injected into child process env so spawned processes
  (e.g., npx finding node) also get the full PATH
- Falls back gracefully if shell resolution fails
- Respects user-set PATH in env overrides

Signed-off-by: Claude <noreply@anthropic.com>

https://claude.ai/code/session_01EYZVAqzgNBAAtJptw9KRwB
Signed-off-by: Claude <noreply@anthropic.com>
Unit tests for shell_env module:
- merge_paths: deduplication, ordering, empty inputs, identical paths
- get_shell_path: caching (OnceLock), no trailing newline, no empty entries,
  valid UTF-8, returns standard directories
- try_resolve_path_from_shell: login shell, nonexistent shell, invalid flags

Unit tests for stdio transport helpers:
- resolve_command: with/without shell path, nonexistent, restricted path
- inject_shell_path: adds when missing, respects existing, no-op when None
- command_hint: Docker vs non-Docker hints
- classify_stderr_line: error/warn/debug/info classification

Integration tests:
- Shell PATH finds system commands (sh, ls, env)
- Shell PATH has more entries than minimal default
- Child process receives injected shell PATH
- User-set PATH override not clobbered by injection
- StdioTransport resolves commands via shell PATH

Signed-off-by: Claude <noreply@anthropic.com>

https://claude.ai/code/session_01EYZVAqzgNBAAtJptw9KRwB
Signed-off-by: Claude <noreply@anthropic.com>
@its-mash
its-mash merged commit 98c013d into main Feb 18, 2026
13 checks passed
@its-mash
its-mash deleted the claude/fix-mcp-npx-mac-dxoey branch February 18, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants