Notes on setting up Claude Desktop MCP servers
The model context protocol is a pretty awesome way to get more out of your LLM. Claude's desktop app has positioned itself as an easy way to get started exploring the space. Claude desktop works by launching servers declared in claude_desktop_config.json
on startup and then making tools available in the app. An example, json file is shown below:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop",
"/Users/username/Downloads"
]
}
}
}
Unfortunately the server failed to startup on app launch when I attempted it initially.
The error log indicated that it could not find npx
.
2025-02-17T21:01:42.098Z [info] [filesystem] Initializing server...
2025-02-17T21:01:42.106Z [error] [filesystem] spawn npx ENOENT
2025-02-17T21:01:42.106Z [error] [filesystem] spawn npx ENOENT
2025-02-17T21:01:42.109Z [info] [filesystem] Server transport closed
2025-02-17T21:01:42.109Z [info] [filesystem] Client transport closed
2025-02-17T21:01:42.110Z [info] [filesystem] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log.
2025-02-17T21:01:42.110Z [error] [filesystem] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging)
This happened despite npx
and node
being available in my $PATH
and the server being able to launch when run manually. In my case it the issue stems from how macOS apps inherit $PATH
. Since they inheriting the system $PATH
they might miss paths added by your shell (via bash or zsh rc files). There are some fixed paths that the app looks up depending on your platform to attempt to compensate for this behavior.
On macos
${homeDir}/.nvm/versions/node/*/bin
/opt/homebrew/Caskroom/miniforge/base/envs/py*/bin
/usr/local/bin
/opt/homebrew/bin
/opt/local/bin
/usr/bin
Linux,
`${homeDir}/.nvm/versions/node/*/bin`,
`${homeDir}/miniforge3/envs/py*/bin`,
`/usr/local/bin`,
`/usr/bin`,
`/bin`,
and Windows
`${homeDir}\\AppData\\Roaming\\nvm\\v*`,
`${homeDir}\\miniforge3\\envs\\py*`,
`${homeDir}\\AppData\\Local\\Programs\\Python\\Python3*`,
`C:\\Program Files\\nodejs`,
`C:\\Program Files\\Python3*`,
`C:\\Program Files (x86)\\nodejs`,
`C:\\Program Files (x86)\\Python3*`,
`C:\\Python3*`,
So you need to make sure your binaries in this case node
and npx
are available in one of these paths. Since my node version, installed with brew - node@22
was "keg" only it wasn't symlinked to /opt/homebrew/bin
. The solution was to symlink it myself
ln -s /opt/homebrew/opt/node@22/bin/npx /opt/homebrew/bin/npx
ln -s /opt/homebrew/opt/node@22/bin/node /opt/homebrew/bin/node
To clean up the symlinks after you're done deleting the symlinks is sufficient
rm /opt/homebrew/bin/npx
rm /opt/homebrew/bin/node
Special thanks to Ani for helping me debug this issue