You've added an MCP server to your settings.json, waited, and... nothing appears in the tools panel. Checking the logs reveals spawn npx ENOENT or spawn uvx ENOENT staring back at you.
Running the same npx command directly in your terminal works fine. The server starts, responds correctly, everything looks good. But Claude Code refuses to launch it. This disconnect frustrated me for over half an hour when I was setting up additional third-party MCP servers while working on app projects I've been building independently since 2014. The fix turned out to be simpler than expected — once you understand what's actually happening.
What ENOENT Means
ENOENT stands for "Error NO ENTry" — a POSIX error code that Node.js surfaces when a file or executable doesn't exist at the specified path. When you see spawn npx ENOENT, it literally means: Node.js tried to spawn a process called npx, but couldn't find that executable anywhere.
The confusing part is that npx clearly exists on your system. So why can't Claude Code find it?
The Root Cause: Claude Code Uses a Different PATH
Your shell (bash, zsh, fish) loads configuration files like .bashrc, .zshrc, or config.fish when it starts. These files set up your PATH — the list of directories where the OS looks for executables.
But when Claude Code spawns an MCP server using child_process.spawn, it doesn't load your shell's configuration files. It starts the process with a minimal, system-level PATH that often doesn't include the directories where your tools are installed.
The most common scenarios where this bites:
- Node.js installed via nvm: nvm modifies your PATH dynamically inside shell config files. Any process that doesn't source those files — including Claude Code's MCP spawner — won't find
node,npm, ornpx - Homebrew on Apple Silicon Mac:
/opt/homebrew/binis added to PATH by Homebrew's installer in your shell config, but it's not in the system default PATH - uvx installed via uv: Both install to
~/.local/binor~/.cargo/bin, directories that aren't in the system PATH by default
You can confirm this by comparing your shell's PATH with what Claude Code actually sees:
# In your terminal — find where npx lives
which npx
# Example output with nvm: /Users/you/.nvm/versions/node/v22.3.0/bin/npx
# In Claude Code's Bash tool — see what PATH it has
echo $PATHThe two outputs will likely differ, and the directory containing npx will be missing from Claude Code's version.
Fix 1: Use Absolute Paths in Your MCP Configuration
The most bulletproof solution: replace the short command name with its full path.
Before (broken):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"]
}
}
}After (working):
{
"mcpServers": {
"filesystem": {
"command": "/Users/you/.nvm/versions/node/v22.3.0/bin/npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"]
}
}
}The downside: if you switch Node.js versions with nvm, this path breaks. For nvm users, Fix 2 is more maintainable.
Fix 2: Extend PATH via the env Field (Recommended)
Claude Code's settings.json supports an env field for each MCP server, letting you set environment variables for that server's process. You can use this to inject the missing PATH directories:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"],
"env": {
"PATH": "/Users/you/.nvm/versions/node/v22.3.0/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
}
}
}
}To get the right value, run echo $PATH in your terminal and copy the output directly into env.PATH. This preserves your shell's PATH configuration without requiring absolute paths in the command field.
# Copy this output into env.PATH
echo $PATHThis approach scales better than absolute paths — when you update Node.js, you only need to update the PATH string, not each individual server's command.
Fix 3: Create a Symlink in the System PATH
For a system-wide solution that works across all tools (not just Claude Code), create symlinks to your executables in /usr/local/bin:
# Link your nvm-managed npx into the system PATH
sudo ln -sf "$(which npx)" /usr/local/bin/npx
sudo ln -sf "$(which node)" /usr/local/bin/node
# For uvx
sudo ln -sf "$(which uvx)" /usr/local/bin/uvxThis works because /usr/local/bin is typically included in the minimal system PATH. The caveat: you'll need to update the symlinks when you switch Node.js versions via nvm.
After Applying the Fix
Fully restart Claude Code — closing and reopening the window may not be enough in all cases; quit the application completely and relaunch.
Then test whether the MCP server is recognized:
# In Claude Code's Bash tool — verify the command is now findable
which npx
# If it returns a path, the fix worked
# The MCP server tools should now appear in Claude Code's tool panelIf you're still seeing connection errors after fixing the PATH, the issue may be something different. The Claude Code MCP Connection Troubleshooting Guide covers other common failure modes like permission errors, OAuth token expiry, and server configuration mistakes.
Quick Reference by Tool
npx not found (using nvm)
# Get the path to add
which npx # /Users/you/.nvm/versions/node/v22.3.0/bin/npx
# Add /Users/you/.nvm/versions/node/v22.3.0/bin to env.PATHuvx not found
# Get the path to add
which uvx # /Users/you/.local/bin/uvx or /Users/you/.cargo/bin/uvx
# Add that directory to env.PATHHomebrew commands not found (Apple Silicon)
# Homebrew root
which brew # /opt/homebrew/bin/brew
# Add /opt/homebrew/bin to env.PATHWhen the env Fix Doesn't Work: Checking settings.json Scope
Claude Code has two levels of MCP configuration:
- Global:
~/.claude/settings.json— applies to all projects - Project-local:
.claude/settings.local.jsonin your project root — applies only to that project
If you edited the wrong file, the env fix won't take effect. Verify you're editing the right one:
# Check which settings files Claude Code is reading
cat ~/.claude/settings.json # Global settings
cat .claude/settings.local.json # Project-local settings (if it exists)Also double-check the JSON syntax. A missing comma or mismatched bracket will silently prevent the entire mcpServers block from loading. Claude Code won't always display a clear error for malformed JSON — the server simply won't appear. Use a JSON validator before saving:
# Validate JSON syntax
cat ~/.claude/settings.json | python3 -m json.tool
# If it prints the formatted JSON, the syntax is valid
# If it throws an error, you have a syntax problemDistinguishing spawn ENOENT from Other MCP Errors
spawn ENOENT is specifically a "can't find the executable" error. It's worth distinguishing from similar-looking errors you might encounter:
spawn ENOENT: The command binary doesn't exist in PATH → Fix with absolute path or env.PATHECONNREFUSED: The server process started but refused a network connection → Usually a port conflict or server startup errorError: Cannot find module: The server started (Node.js ran), but a required npm package is missing → Runnpm installin the server directoryPermission denied: The binary exists but can't be executed → Check file permissions withls -la $(which npx)
If your log shows something other than spawn ENOENT, the issue is downstream from PATH — the executable was found, but something else went wrong during server initialization.
The Broader Pattern
This PATH mismatch problem isn't unique to Claude Code or MCP servers — it appears any time a GUI app or background service needs to run CLI tools that were installed in shell-specific locations. Once you recognize the pattern ("it works in my terminal but not when spawned by X"), the diagnosis becomes straightforward: compare the PATHs, find the missing directory, add it explicitly.
Development environments built up over years of installing tools incrementally — nvm here, Homebrew there, uv later — tend to accumulate these PATH fragmentation issues. If you hit this problem with one MCP server, it's worth auditing the entire configuration to make sure other servers won't fail the same way.
For a broader look at what MCP servers are available and how to choose them, MCP × Claude Practical Guide covers setup, recommended servers, and real workflow integrations.
Start with echo $PATH in your terminal, copy the output into env.PATH in your settings.json, and restart Claude Code. That single change resolves the issue in most cases.
Putting It All Together: A Diagnostic Checklist
When an MCP server fails to start with a spawn error, work through these steps in order:
Step 1 — Confirm the executable exists
which npx # or: which uvx / which python3If which returns nothing, the tool isn't installed at all — install it first.
Step 2 — Note the full path from Step 1
which npx
# /Users/you/.nvm/versions/node/v22.3.0/bin/npxCopy this path. You'll need the directory part: /Users/you/.nvm/versions/node/v22.3.0/bin
Step 3 — Add that directory to env.PATH in your MCP server config
{
"mcpServers": {
"your-server": {
"command": "npx",
"args": ["..."],
"env": {
"PATH": "/Users/you/.nvm/versions/node/v22.3.0/bin:/usr/local/bin:/usr/bin:/bin"
}
}
}
}Step 4 — Validate the JSON syntax
cat ~/.claude/settings.json | python3 -m json.tool > /dev/null && echo "Valid JSON"Step 5 — Fully quit and restart Claude Code, then check the tool panel
If the server now appears and its tools are available, you're done. If not, check the Claude Code logs for a different error type, which may point to a separate issue such as a missing npm package or a server-side configuration problem.
Running through this checklist takes about two minutes and covers the majority of MCP server startup failures.