MCP Server Connection Issues
You added the Postgres MCP, restarted Cursor, and the tool list is still empty with a red dot next to the server. Or Claude Code prints spawn npx ENOENT the moment it tries to launch the server. Or the connection works on your machine but a teammate gets Client closed every single time. MCP connection failures are almost always one of four things: the binary cannot be found, an environment variable is missing, an auth token is wrong or expired, or the transport never completes a handshake.
This guide walks the diagnosis in order, gives you paste-ready prompts that make the agent itself surface the real error, and covers the OS-specific fixes (PATH, Gatekeeper, firewalls) that the official docs gloss over.
What You’ll Walk Away With
Section titled “What You’ll Walk Away With”- A five-step diagnostic order that isolates the failure before you start guessing
- Copy-paste prompts that make Cursor, Claude Code, or Codex report the exact stderr from a failing server
- The real fixes for
spawn ENOENT, stalenpxcaches, and missing PATH entries - Where each tool writes its MCP logs and how to read them
- Platform-specific fixes for macOS Gatekeeper, Windows execution policy, and Linux permissions
Diagnose in Order
Section titled “Diagnose in Order”Connection problems feel random until you check them in the right sequence. Each step rules out a whole class of causes.
- Can the server start at all? Run the exact launch command from your config in a plain terminal. If it fails there, it will fail inside the client.
- Is the binary on PATH? GUI apps (Cursor) and login shells often have a different PATH than your interactive terminal.
spawn ENOENTalmost always means the client cannot findnpx/node/uvx. - Are the credentials present and valid? Missing env vars and expired OAuth tokens both surface as “connected but no tools” or “permission denied.”
- Did tool registration complete? A server can connect and still advertise zero tools if it crashed during init. Read the stderr.
- Is the transport healthy? For remote/HTTP servers, check the URL, the firewall, and any corporate proxy.
”No Tools Found” or Server Not Visible
Section titled “”No Tools Found” or Server Not Visible”The most common symptom: the server appears in your config but shows a red/error dot and contributes no tools.
Symptoms: red indicator next to the server, “No tools found”, server missing from the tool list.
# 1. Validate the config JSON (a trailing comma silently breaks the whole file)cat ~/.cursor/mcp.json # global, or .cursor/mcp.json in the project
# 2. Run the server's launch command manually to see real errorsnpx -y postgres-mcp
# 3. Fully quit and reopen Cursor (Cmd/Ctrl+Q, not just close the window)A minimal, valid stdio entry — Cursor’s schema supports only command/args/env for stdio and url/headers for remote servers:
{ "mcpServers": { "postgres": { "command": "npx", "args": ["-y", "postgres-mcp"], "env": { "DATABASE_URL": "${DATABASE_URL}" } } }}Symptoms: server absent from the tool list, no MCP tools in chat, connection timeout.
# 1. List configured servers and their resolved statusclaude mcp list
# 2. Inspect one server's command, args, and envclaude mcp get postgres
# 3. Re-launch with MCP debug loggingclaude --debug "mcp"Inside the REPL, /mcp shows live connection status and lets you reconnect or authenticate a server interactively.
Symptoms: server listed in config but no tools available, or it never appears under /mcp.
Codex stores servers in ~/.codex/config.toml under [mcp_servers.<name>]:
# 1. List configured servers (add --json for raw output)codex mcp list
# 2. Inspect one server's resolved configcodex mcp get postgres
# 3. Read the most recent log after reproducing the failuretail -n 100 ~/.codex/log/codex-tui.logInside the TUI, /mcp lists active servers and how many tools each one loaded. A stdio entry in config.toml looks like:
[mcp_servers.postgres]command = "npx"args = ["-y", "postgres-mcp"]
[mcp_servers.postgres.env]DATABASE_URL = "postgres://localhost/app""Client Closed” or “spawn ENOENT”
Section titled “"Client Closed” or “spawn ENOENT””These errors mean the server process never started. The launcher binary is missing from the client’s PATH, or the package failed to resolve.
# Clear a poisoned npx cache, then re-resolvenpx clear-npx-cache
# Confirm the launcher binaries the client will usenode --version # active Node LTS, e.g. 22.xnpx --version
# Run the server command directly — the fastest way to see the real errornpx -y postgres-mcpThe PATH mismatch is the usual culprit: a GUI app inherits the OS login PATH, not your shell’s .zshrc/.bashrc additions.
# Find where node actually lives, then make sure the client can see itwhich node # e.g. /Users/you/.nvm/versions/node/v22.14.0/bin/node
# If you use nvm/asdf, point the config at the absolute path instead of bare "npx":# "command": "/Users/you/.nvm/versions/node/v22.14.0/bin/npx"Version-manager installs are the #1 cause of spawn ENOENT in GUI clients, because the shim is only on PATH inside an interactive shell. Either launch the GUI from a terminal that has the version manager loaded, or hard-code the absolute path to npx/node in the config.
# Confirm Node is on PATH for the user that runs the clientwhere.exe node
# If npx is not resolving, point the config at node + the absolute script path:{ "mcpServers": { "server-name": { "command": "node", "args": ["C:\\Users\\You\\AppData\\Roaming\\npm\\node_modules\\<scope>\\<server>\\dist\\index.js"] } }}Use double backslashes in JSON. If PowerShell windows flash open, set "windowsHide": true on the server entry in Cursor.
Authentication and Permission Failures
Section titled “Authentication and Permission Failures”A connected server with zero tools, or “permission denied” on every call, is almost always a credential problem: a missing env var, an expired OAuth token, or a token whose scope is too narrow.
Reference secrets from your environment instead of hardcoding them. Export the variable in your shell profile, then interpolate it:
{ "mcpServers": { "api-server": { "command": "npx", "args": ["-y", "@example/server"], "env": { "API_KEY": "${MY_API_KEY}" } } }}For OAuth-backed remote servers, Cursor opens a browser flow on first connect — check that no popup blocker is swallowing it, and that the server’s redirect URL is whitelisted.
# Remote/OAuth server: add it, then complete the browser flowclaude mcp add --transport http github https://api.githubcopilot.com/mcp/
# Re-trigger auth from the REPL if the token expired/mcpIf a token expired, /mcp lets you re-authenticate without removing and re-adding the server.
# Start an OAuth login for a streamable HTTP server that supports itcodex mcp login github
# Clear stored credentials if the token is wrong or stalecodex mcp logout githubFor token-based servers, set the variable via the server’s env table in config.toml, or use bearer_token_env_var on a url server so the token is read from your environment rather than committed.
Platform-Specific Fixes
Section titled “Platform-Specific Fixes”macOS Gatekeeper
Section titled “macOS Gatekeeper”# macOS quarantines downloaded binaries; clear the flag if a server is blockedxattr -d com.apple.quarantine /path/to/mcp/server
# Check whether a local server's port is already takenlsof -i :3845Windows Execution Policy
Section titled “Windows Execution Policy”# Allow locally-created scripts to run (per-user, no admin needed)Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserLinux PATH and Permissions
Section titled “Linux PATH and Permissions”# Never install global npm packages with sudo — fix the prefix insteadmkdir ~/.npm-globalnpm config set prefix '~/.npm-global'echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrcsource ~/.bashrc
# Use a version manager and an active LTS (Node 18 is EOL)curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bashnvm install 22nvm use 22Network, Firewall, and Proxy Issues
Section titled “Network, Firewall, and Proxy Issues”Remote and local HTTP-transport servers add a network layer that stdio servers do not have.
# Confirm a local server is actually listening on its portcurl http://127.0.0.1:3845/mcp
# If 127.0.0.1 is blocked but the server binds 0.0.0.0, target that host:# "url": "http://0.0.0.0:3845/mcp"# Linux (ufw)sudo ufw allow 3845/tcp
# Windows Defendernetsh advfirewall firewall add rule name="MCP Server" dir=in action=allow protocol=TCP localport=3845For stdio servers behind a corporate proxy, pass the proxy through the server’s env:
{ "mcpServers": { "server": { "command": "npx", "args": ["-y", "@scope/server"], "env": { "HTTPS_PROXY": "http://proxy.company.com:8080", "NO_PROXY": "localhost,127.0.0.1" } } }}Reading the Logs
Section titled “Reading the Logs”When the agent’s own report is not enough, go to the logs directly:
Open the Output panel (Cmd/Ctrl+Shift+U) and select MCP Logs from the dropdown. Look for connection attempts, authentication failures, and tool-registration errors.
# Stream MCP-specific debug outputclaude --debug "mcp"# Codex writes its session log here; tail it after reproducing the failuretail -n 100 ~/.codex/log/codex-tui.logWhen This Breaks
Section titled “When This Breaks”It works in your terminal but the client still fails. The client is using a different PATH or a stale cache. Hard-code the absolute path to npx/node in the config, and run npx clear-npx-cache.
The server connects but loads zero tools. It crashed during initialization — usually a missing env var. Run the launch command directly and read the stderr; that is where the real message is.
It works for you but not a teammate. You almost certainly have an env var or a globally-installed dependency that they do not. Pin the server version in args and document every required environment variable in your project’s contributing guide.
A remote server worked yesterday and 401s today. The OAuth token expired. Re-run the browser flow: /mcp in Claude Code, codex mcp login <name> for Codex, or reconnect from Cursor’s MCP settings.
Stuck or orphaned server processes. Find and kill them, then let the client respawn:
# macOS / Linuxpkill -f "mcp"
# Windowstasklist | findstr "node"taskkill /F /PID <pid>What’s Next
Section titled “What’s Next”For protocol-level questions, the spec and its discussion forum live at github.com/modelcontextprotocol and the MCP GitHub Discussions. For tool-specific help, use the Cursor Community Forum and the Anthropic Discord.