How to Fix “MCP Client Closed” in Cursor
Find the real error behind Cursor’s “MCP Client Closed” message and fix launch, PATH, environment, transport, and authentication problems.
Cursor’s Client closed message is a symptom, not a diagnosis. Open the Output panel, choose MCP Logs, and inspect the lines immediately before the client closes. Those lines usually identify the actual failure: an executable that cannot be found, invalid arguments, missing environment variables, authentication failure, a timeout, or a server process that exited.
This guide shows how to isolate the failure stage, verify the active configuration, reproduce the launch command, and fix local, remote, WSL, and Windows-specific environment problems.
1. Start with MCP Logs
In Cursor, open View → Output and select MCP Logs from the channel picker. Cursor’s MCP documentation says these logs include server initialization, tool calls, connection errors, authentication failures, and server crashes. Read the complete error immediately before Client closed; that entry is the useful evidence.
- Copy the first error and its stack trace, if present.
- Note whether the failure occurs while spawning the process, during initialization, during authentication, or after tools have already been called.
- Record whether the server is local
stdioor a remote HTTP/SSE endpoint. - Check whether the server closes consistently or only after an idle period or a particular tool call.
Do not treat a terminal run as proof that Cursor is configured correctly. Cursor can have a different PATH, working directory, Node or Python version, npm configuration, credentials, or network environment.
2. Confirm which mcp.json Cursor is using
Cursor supports project configuration at .cursor/mcp.json and global configuration at ~/.cursor/mcp.json. The documented configuration files are merged; when names conflict, the project entry takes precedence. Check both files so you do not repair an entry that is not active.
{
"mcpServers": {
"example-server": {
"command": "node",
"args": ["/absolute/path/server.js"],
"env": {
"API_KEY": "replace-me"
}
}
}
}
For a server that needs a dotenv file, use the documented envFile field:
{
"mcpServers": {
"python-server": {
"command": "python3",
"args": ["/absolute/path/server.py"],
"envFile": "/absolute/path/.env"
}
}
}
Keep the args value as an array. Do not put the entire command line into one string. Use an absolute executable path when Cursor cannot resolve a command by name.
3. Test the exact stdio command outside Cursor
Run exactly the command and arguments from mcp.json in a terminal. This exposes syntax errors, missing packages, and server-side startup failures.
node /absolute/path/server.js
python3 /absolute/path/server.py
If the command only stays alive when it receives MCP messages over stdin, that is normal. A process that exits immediately is not a working stdio server. Check its stderr output and exit code.
Then compare the environment Cursor receives:
command -v node
node --version
command -v python3
python3 --version
printf '%s\n' "$PATH"
npm config get registry
A reported Cursor failure involved different npm registry configuration at user and project level. That is an example of environment drift, not a universal cause. Check the values on the same machine and in the same project where Cursor launches the server.
4. Fix executable and PATH errors
| Log evidence | Likely cause | Fix |
|---|---|---|
spawn python ENOENT |
Cursor cannot resolve the executable. | Install the runtime in the execution environment or replace python with its absolute path, such as /usr/bin/python3. |
command not found |
The process PATH differs from your shell. | Use an absolute path or set the required PATH in env. |
| Immediate exit with no MCP handshake | Wrong entry point, invalid argument, or startup exception. | Run the exact command manually and fix the first exception. |
| Works in one terminal but not Cursor | Different shell startup files, runtime manager, working directory, or package configuration. | Compare executable paths, versions, npm settings, current directory, and environment variables. |
Runtime managers such as nvm, pyenv, conda, and shell-specific startup files often modify PATH only for interactive shells. Cursor may launch without reading those files. An absolute path removes that ambiguity.
5. Check environment variables and authentication
Missing secrets can make a server start and then close during initialization. Confirm every variable referenced by the server is present in env or envFile. Check spelling and capitalization exactly.
{
"mcpServers": {
"secure-server": {
"command": "/usr/local/bin/node",
"args": ["/srv/mcp/index.js"],
"env": {
"API_BASE_URL": "https://api.example.test",
"API_TOKEN": "redacted-value"
}
}
}
}
Never paste real tokens into logs, screenshots, issues, or an article. If authentication fails, verify the token scope, expiration, endpoint, and whether Cursor is launching on a different machine.
6. Handle Windows, WSL, SSH, and remote workspaces
Identify where the process is supposed to run. A Windows Cursor process, a WSL shell, an SSH host, and a dev container have different filesystems, PATH values, credentials, and network routes.
- Windows: use the path and executable available to the Windows process. If the server is a batch file, configure the appropriate interpreter and pass arguments separately.
- WSL: verify the executable and script exist inside the selected Linux distribution, not only on the Windows filesystem.
- SSH or remote development: confirm the server starts on the remote host and that its environment variables and network access exist there.
- Containers: check that the image contains the runtime, dependencies, certificates, and files referenced by
mcp.json.
Community reports show that environment-specific workarounds can change between Cursor releases. Use the current MCP logs and documentation instead of copying a blanket wrapper command.
7. Separate transport and failure stage
| Stage | What to inspect |
|---|---|
| Process spawn | Executable path, permissions, PATH, OS, working machine. |
| Initialization or handshake | Protocol implementation, startup output, malformed configuration, incompatible server version. |
| Authentication | Tokens, environment variables, endpoint URL, certificate and proxy settings. |
| Later connection | Idle timeout, remote process restart, network interruption, or a server crash during a tool call. |
For remote transports, verify the endpoint independently with the server’s documented health or connection procedure. For stdio, keep stdout reserved for protocol messages; diagnostic logging should go to stderr. Writing ordinary logs to stdout can corrupt the MCP stream and cause a disconnect.
8. Reload and verify the repair
- Save the corrected project or global
mcp.json. - Toggle the server off and on in Cursor’s MCP controls, or reload the workspace if your version requires it.
- Reopen MCP Logs and confirm initialization completes without an immediate exit.
- Call a harmless tool and confirm both the request and response appear in the log.
- Leave the log channel open while testing a longer operation so you can distinguish a timeout from a crash.
9. Common fixes that do not diagnose the cause
Reinstalling Node or Python, adding a shell wrapper, changing servers, or repeatedly restarting Cursor can hide the original error without fixing it. Use those actions only after the logs show a runtime or wrapper problem. The reliable sequence is: capture the preceding log line, reproduce the exact command, compare environments, correct the specific mismatch, and verify the handshake again.
10. Performance, reliability, and operational notes
- Start local stdio servers with a stable absolute path and pinned dependencies to reduce startup variance.
- Avoid expensive initialization before the handshake; defer optional network calls until a tool needs them.
- Set sensible server-side timeouts and return actionable errors instead of exiting on a single failed request.
- For remote servers, monitor process restarts, proxy limits, idle timeouts, and certificate expiry.
- Keep logs concise and send them to stderr so protocol traffic remains valid.
- There is no Cursor-side fix that can recover a server process that has exited; the server must remain alive and able to read stdin or accept its configured transport.
Or skip the browser setup
If your Cursor workflow needs website screenshots through an MCP server, ScreenshotNeo provides the take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its API can also be called directly.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API and MCP documentation for configuration details. Cookie banners, newsletter popups, and chat widgets are removed before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing result. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Create a free ScreenshotNeo account and try the screenshot API without adding a card.
FAQ
Does “Client closed” always mean PATH is wrong?
No. PATH problems are one possibility. The preceding MCP log can instead show authentication, configuration, timeout, protocol, or server-crash errors.
Why does my server work in a terminal but fail in Cursor?
The two processes may have different PATH values, runtime versions, npm configuration, working directories, environment variables, or network locations. Compare those values using the exact configured command.
Should I use a global or project mcp.json?
Use a project file for repository-specific servers and a global file for servers you want across projects. Check both because Cursor merges them and project entries win when names conflict.
What should a healthy stdio server print?
It should stay running and exchange MCP protocol messages over stdin and stdout. Send diagnostic logs to stderr so they do not corrupt the protocol stream.
Can Cursor fix a server that exits immediately?
No. Cursor can report the exit, but the entry point, arguments, runtime, dependencies, or server code must be corrected so the process remains alive.


