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.

Claude Desktop error on launch
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

Subscribe to Another Dev's Two Cents

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe