Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gregelin/b90edaef851f86252c88ecc066c93719 to your computer and use it in GitHub Desktop.
Save gregelin/b90edaef851f86252c88ecc066c93719 to your computer and use it in GitHub Desktop.

Troubleshooting MCP Server Launch Failures on M1 Mac (Claude Desktop Integration)

Context and Symptoms

When attempting to integrate a local MCP (Model Context Protocol) server with Anthropic’s Claude Desktop app on an M1 MacBook, users have encountered launch failures. In this scenario, the MCP server (written in Python 3.10–3.13 and run in a virtual environment) fails to start when Claude Desktop tries to connect to it. The Claude app’s logs repeatedly show an error message like:

Error: spawn uv ENOENT

This error prevents the MCP server from running, so Claude cannot use the server’s tools or resources. Understanding what causes the spawn uv ENOENT error is key to fixing the launch failure, especially on macOS (Apple Silicon) systems. Below, we investigate the meaning of this error, why it occurs (e.g. missing uv tool or path issues), how Claude Desktop expects to launch the server, and how to resolve the problem on a Mac M1 step by step.

Meaning of the spawn uv ENOENT Error

The error spawn uv ENOENT essentially means that the system was unable to find or execute the command uv when trying to start the MCP server. “ENOENT” stands for “Error NO ENTity” (no such file or directory), which in this context indicates that the uv command was not found in the expected location or PATH (mcp-server/README.md at main · wandb/mcp-server · GitHub). In other words, Claude Desktop attempted to spawn a process named uv and the operating system reported that it could not locate an executable by that name. This is a common error when a required binary or command-line tool isn’t installed or isn’t accessible in the environment from which it’s being invoked.

In the context of MCP and Claude Desktop, the appearance of spawn uv ENOENT strongly suggests that the uv tool is not available to the Claude Desktop application (either not installed at all, or not in the PATH that Claude can see) (How to build your own MCP server? - by Aravind Putrevu) (mcp-server/README.md at main · wandb/mcp-server · GitHub). Some users have also seen a similar error with uvx (an alternate invocation of the tool, explained below) – e.g. spawn uvx ENOENT – which similarly indicates the uvx command wasn’t found (Claude Desktop + MCP,让Apple Notes和AI联动 - 知乎专栏). Both errors point to the same underlying issue: the uv package manager (or its alias) isn’t being located.

The Role of uv in MCP Server Launch

The tool uv is a fast Python package and project manager (from Astral) that is often used to manage and run MCP servers. Many MCP server examples and guides use uv to simplify environment management – it can create virtual environments, install dependencies quickly, and run Python scripts. Essentially, uv for Python plays a role similar to Node’s npx for JavaScript, enabling one-command execution of Python projects with all required packages.

Because of its convenience, the Claude Desktop integration often expects to use uv to run the MCP server. For example, an MCP server configuration in the Claude config file might look like this:

{
  "mcpServers": {
    "chess": {
      "command": "uv",
      "args": [
        "--directory",
        "<full path to chess-mcp directory>",
        "run",
        "src/chess_mcp/main.py"
      ]
    }
  }
}

In the above (from a community “chess” MCP server), Claude Desktop is configured to call the uv command to run the server’s Python script (GitHub - pab1it0/chess-mcp: A Model Context Protocol server for Chess.com's Published Data API. This provides access to Chess.com player data, game records, and other public information through standardized MCP interfaces, allowing AI assistants to search and analyze chess information.). The uv tool ensures the correct Python environment and dependencies for the server (using the project at the given directory). If uv (or uvx) is not installed or not found, this spawn will fail.

Is the uv binary required to be installed globally? In practice, yes – the Claude app will call uv as an external process, so it expects uv to be installed and accessible somewhere in the system PATH (or via an absolute path in the config). The MCP server code or Python package itself usually does not bundle uv, so you must install uv yourself. According to the LSD MCP server documentation, to run an MCP server you need to have both Python and uv installed on your machine (LSD MCP Server | Glama). If you installed the MCP server via pip inside a virtual environment, that may have pulled in the MCP libraries but not the uv tool itself (unless you installed it explicitly). Even if you did pip install uv inside a venv, the Claude Desktop app might not use that same virtual environment, so it still wouldn’t see the uv command. Thus, typically one installs uv either globally (e.g. via a one-line script or Homebrew/pipx) or ensures the Claude config knows exactly where to find it.

uv vs uvx: You might also come across uvx, which is a convenience command provided by uv for running a tool in a temporary environment (similar to how npx works for Node). For example, the MCP project documentation suggests that Python-based servers can be run with uvx as a one-shot command (GitHub - browserbase/browserbase-servers: Model Context Protocol Servers (Browserbase Version)). In Claude’s config, using "command": "uvx" with appropriate args is possible (and some guides recommend it). However, uvx is essentially part of the uv toolset – if uv is installed, it typically provides both commands. An error spawn uvx ENOENT would mean the same thing (tool not found). The solutions are identical: make sure uv/uvx is installed and on the PATH.

Why the ENOENT Occurs on Mac (Path and Installation Issues)

On macOS (including M1/M2 Apple Silicon Macs), a common reason for spawn uv ENOENT is that uv isn’t in the PATH that the Claude Desktop app uses. macOS GUI applications do not always inherit the same shell environment PATH as your Terminal. For instance, if you installed uv via pip --user or pipx, it might reside in ~/.local/bin by default. Your Terminal might find uv (because your shell config adds ~/.local/bin to PATH), but when you launch Claude Desktop (a GUI app), it may not know about that location. In such cases, Claude tries to run uv and the OS reports it can’t find it. This is exactly the “incomplete path” issue described in an MCP server troubleshooting guide: the fix was to provide the full path to the uv executable in the config if it isn’t being found (LSD MCP Server | Glama).

Another scenario is that uv was simply never installed. Since many MCP guides emphasize using uv, an attempt to run an MCP server without installing uv will immediately fail with ENOENT. One guide on building an MCP server notes this error and the straightforward solution: “Error: spawn uv ENOENT – Solution: Install uv.” (How to build your own MCP server? - by Aravind Putrevu). In other words, if uv is missing, you need to install it for the MCP server to launch.

It’s also possible to run MCP servers without using uv (for example, by running a Python module or script directly), but then your Claude config should call python or another command instead of uv. Many official servers and examples assume uv, so if you follow those instructions without uv present, you hit the ENOENT error. Conversely, if you did install everything via uv in a project, you still must make the uv command reachable by Claude.

Summary of causes for ENOENT:

  • uv is not installed at all: Claude tries to spawn it and fails. The remedy is to install the uv tool (How to build your own MCP server? - by Aravind Putrevu).
  • uv is installed, but not in PATH for Claude: This is common on Mac if installed in a user directory. The app can’t find the command. The remedy is to adjust the PATH or provide the full path in config (LSD MCP Server | Glama).
  • Using uvx without uv installed: uvx is part of the uv package; if not installed, it will similarly error out.
  • Misconfigured command: (Less common) If the Claude config’s "command" is misspelled or pointing to something that doesn’t exist, you’d also get ENOENT. Double-check that the config JSON is correct and that the "command" field is exactly how the executable is named.

Apple M1 Compatibility Considerations

Running on an Apple Silicon (M1) Mac introduces a few specific considerations, though fortunately uv and MCP are compatible with M1 with the right setup. The uv tool supports macOS on Apple Silicon, so in general there’s no fundamental incompatibility reported. However, you should ensure you install the correct version of uv (for example, using the official installer script will detect your platform and install the appropriate binary). If you choose to install via pip, note that uv is written in Rust – if a pre-built wheel is not available for Python 3.13 on M1, pip might try to build it from source. In that case you’ll need a Rust compiler available (or you can install via the script to avoid that). Most users find the one-line install script simplest on Mac.

Beyond uv itself, the MCP server you’re running may have additional dependencies that need to be compatible with M1. Python packages that rely on native code could require extra steps on macOS. For example, the LSD MCP server uses the psycopg2 library (PostgreSQL client). On a Mac where PostgreSQL client libraries are not installed, this could fail to build or run. The LSD server docs warn that you might see an error "pg_config executable not found" if Postgres is not installed, and the solution is simply to install Postgres (e.g. via Homebrew) so that the library can build or use the provided binaries (LSD MCP Server | Glama). This isn’t an M1-specific issue per se (it would happen on Intel Mac too), but on a fresh M1 Mac you might not have these libraries. Likewise, ensure you have Xcode Command Line Tools installed, as they provide compilers needed for building some Python packages on Mac.

Another example: if your MCP server uses a package that doesn’t yet provide wheels for Python 3.12 or 3.13 on arm64, you might encounter build errors. In such cases, using Python 3.10 or 3.11 (for which the package has wheels) could be a workaround. The user in this scenario tried Python 3.10 through 3.13, likely troubleshooting such compatibility. Generally, sticking to a slightly older Python version can avoid edge issues with very new Python releases and packages that haven’t caught up. The core MCP protocol library (mcp Python package) supports modern Python versions, so the version flexibility is usually about the dependencies of a particular server implementation.

Summary of M1-specific tips:

  • Use the official uv installer or pipx to get a universal/arm64 binary. If using pip, have Rust available or ensure a wheel is available for your Python version.
  • Make sure any system libraries needed by Python packages (e.g. libpq for psycopg2, brew-installed tools, etc.) are installed on your Mac. If you see errors in the logs about missing executables or libraries, install those via Homebrew. The Claude/MCP logs are located at ~/Library/Logs/Claude/ on Mac (How to build your own MCP server? - by Aravind Putrevu) and can provide clues.
  • No Rosetta/emulation is required for uv or Python – you can run everything natively on Apple Silicon. Just be cautious mixing architectures (e.g., if you install Python under Rosetta, then uv must match that environment; generally it’s easier to stay native if possible).

How Claude Desktop Launches the MCP Server

Anthropic’s Claude Desktop app uses a JSON configuration file to know about local MCP servers. On macOS, this config is located at:

~/Library/Application Support/Claude/claude_desktop_config.json (For Claude Desktop Users - Model Context Protocol)

Under the "mcpServers" section of this JSON, each server is defined by a name and the command to start it. Claude Desktop, upon startup (or when you toggle the integration), will try to spawn the specified command with given arguments. It uses this child process to communicate with the MCP server. By default, the communication happens via standard input/output pipes – essentially, Claude sends requests to the MCP server process’s STDIN and the server responds on STDOUT. (The Model Context Protocol is transport-agnostic, but Claude Desktop’s implementation uses the process’s I/O stream for local servers.)

For example, if the config contains an entry like we saw earlier:

"mcpServers": {
    "chess": {
      "command": "uv",
      "args": ["--directory", "...", "run", "src/chess_mcp/main.py"]
    }
}

Claude will execute the equivalent of running uv --directory ... run src/chess_mcp/main.py as a subprocess. If that subprocess starts correctly, Claude and the server establish a connection (the MCP handshake happens over STDIO). If the subprocess fails to start, Claude logs an error “Failed to start MCP server …” along with the spawn error.

Does Claude connect via socket/port or path? In the basic setup, Claude does not connect via a network socket; it relies on launching the server itself. However, you can configure it to use sockets by launching an appropriate intermediate process. For instance, one integration uses Docker and socat to bridge Claude to a Dockerized server: it spawns a docker run ... alpine/socat STDIO TCP:host.docker.internal:8811 command (The Easiest Way to Set Up MCP with Claude Desktop and Docker Desktop - DEV Community). In that case, Claude is still using STDIO on its end, but socat connects that to a TCP port. Another example is if you use a Node-based MCP server with npx – Claude can spawn npx <server-package> which might internally open a local port or use pipes. But by default, for a local Python server, you do not need to set up any socket or separate path – Claude will handle communication through the spawned process’s pipes automatically. You just need to provide the correct command so Claude can start the process.

In summary, Claude expects to find the server via the command given in the config. It doesn’t automatically discover servers on its own; you must edit claude_desktop_config.json to add them (either manually or via an mcp install command, which edits the config). If the "command" in that config is wrong or not available (as in the case of a missing uv), Claude will report a failure to start the server (LSD MCP Server | Glama) (LSD MCP Server | Glama). Ensuring the command is correct and executable is therefore critical.

Step-by-Step Resolution for MCP Launch Issues on Mac (M1)

To fix MCP server launch failures on a MacBook (M1) when connecting with Claude Desktop, follow these steps:

  1. Verify Claude Desktop Config: Open the Claude desktop config file (~/Library/Application Support/Claude/claude_desktop_config.json) in a text editor. Ensure that your MCP server is listed under "mcpServers" with the correct structure. For example, it might be added as:

    "my_server": {
        "command": "uv",
        "args": [ "--directory", "<path to project>", "run", "<server script or module>" ]
    }

    Double-check that the paths in the args (if any) are correct, and that the name doesn’t conflict with another. If this is the first time you’re adding an MCP server, make sure the JSON syntax is valid. (Anthropic’s docs provide examples for adding entries; you can also use the Claude app’s Settings > Developer > “Edit Config” to generate a basic file.)

  2. Install the uv Tool (if not already installed): If you don’t have uv, install it. The recommended way is to use the official script which installs the latest version for you:

    curl -LsSf https://astral.sh/uv/install.sh | sh

    This will typically install uv into your user’s local bin (e.g. ~/.local/bin/uv) along with its companion uvx. Alternatively, you can use pipx install uv or pip install --user uv, but ensure it ends up on your PATH. After installation, confirm by running uv --version in a terminal. The absence of uv is a primary cause of the ENOENT error (How to build your own MCP server? - by Aravind Putrevu), so this step is crucial if you haven’t done it.

  3. Make Sure uv Is in the System PATH: Having uv installed isn’t enough if Claude can’t find it. To check, open Terminal and run which uv. Commonly, this returns something like /Users/<you>/.local/bin/uv. Now, the Claude app (launched from Finder/Applications) may not include ~/.local/bin in its PATH. A simple solution is to add a symlink to a directory that is always in PATH. For example, you can link uv into /usr/local/bin:

    sudo ln -s ~/.local/bin/uv /usr/local/bin/uv

    Do the same for uvx if needed. This was recommended by one MCP server guide to make uv “available system-wide” (mcp-server/README.md at main · wandb/mcp-server · GitHub). macOS typically includes /usr/local/bin in the default PATH for GUI apps, so this ensures Claude can execute uv. After doing this, consider restarting your Mac or log out/in to ensure GUI processes pick up any updated PATH (and proceed to restart Claude Desktop as well). Alternatively: instead of symlinking, you could add the path in the app’s environment. For instance, launching Claude via command line with a modified PATH, or using a launcher script. But adding the symlink is straightforward and persistent.

  4. (Optional) Use Absolute Path in Claude Config: If you prefer not to alter system PATH, you can directly specify the full path to uv in the Claude config. Edit the command field for your MCP server entry to the full path of the uv executable. For example:

    "command": "/Users/<your_username>/.local/bin/uv",
    "args": [ "--directory", "/path/to/project", "run", "server.py" ]

    By doing this, Claude will spawn that exact path. The LSD MCP server documentation suggests this fix for an “incomplete path” issue: replacing "command": "uv" with the expanded path resolved their ENOENT error (LSD MCP Server | Glama). Be sure to update this if you reinstall uv to a different location or update your username, etc.

  5. Consider Disabling uv Usage (Alternative): If for some reason you cannot get uv working or prefer not to use it, you can configure Claude to run the server without uv. One way is to use the environment variable NO_UV=1 in the config, which some community servers support as a trigger to bypass uv. For instance:

    "my_server": {
        "command": "uv",
        "args": [ "--directory", "...", "run", "server.py" ],
        "env": { "NO_UV": "1" }
    }

    According to one MCP server README, setting NO_UV=1 will cause Claude to try running the server in an alternative way if supported (GitHub - pab1it0/chess-mcp: A Model Context Protocol server for Chess.com's Published Data API. This provides access to Chess.com player data, game records, and other public information through standardized MCP interfaces, allowing AI assistants to search and analyze chess information.) (for example, it might try to call Python directly). Another approach is to change "command" to use Python or another interpreter explicitly. For example:

    "command": "/usr/bin/python3",
    "args": [ "/full/path/to/server.py" ]

    In that case, make sure you have already installed all the necessary Python packages in the environment that /usr/bin/python3 refers to (or point to your venv’s python). This method can be fragile because you must manage dependencies manually, but it avoids the need for uv. Generally, using uv as intended is easier, but this is a fallback.

  6. Address Other Errors (if any): Once the spawn uv ENOENT issue is resolved, the MCP server might start and then hit other issues. Monitor the Claude logs (~/Library/Logs/Claude/mcp*.log) for new messages. If you see errors like missing modules or failed builds, install whatever is missing. For example, if an error mentions pg_config not found or a library failed to compile, use Homebrew to install that dependency (e.g. brew install postgres in the case of pg_config (LSD MCP Server | Glama)). Ensure your Python version is supported by all server dependencies (if not, consider using a slightly older Python for now). Also, if the log shows a syntax error or JSON error in claude_desktop_config.json, fix that (a trailing comma or similar could break the config).

  7. Restart Claude Desktop and Verify: After making changes, fully quit Claude Desktop and start it again. Upon startup, go to Settings > Developer and check the MCP server entry. It should show as “Connected” or “Running” (Claude’s UI may show a status indicator next to the server name). If it still shows an error, re-check the steps above. You can also use the Claude Developer Tools (which open a Chrome DevTools window for the app) to see console logs. A successful launch means no more ENOENT error – the uv process should spawn and remain running. You can test the integration by prompting Claude to use one of the MCP server’s functions (for example, ask it to run a tool or access a resource defined by that server). If Claude responds with a result from the tool, the integration is working.

By following these steps, the common causes of MCP server launch failure on Mac (especially the uv not found issue) should be resolved. In summary, ensure uv is installed and reachable, or provide Claude a direct way to run your server. This addresses the primary cause of the error and any M1-related environment quirks.

Additional Resources

For further information, see Anthropic’s official documentation and community resources on MCP:

With the above guidance, a Mac M1 user should be able to successfully launch a local MCP server and connect it to Claude Desktop, enabling Claude to use local tools and resources via the Model Context Protocol.

Sources:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment