When an MCP server will not connect, first establish whether the client can launch or reach it. Then check protocol compatibility, tool discovery, and one tool call in that order. A server that fails to start needs a different fix from one that connects successfully but cannot access its database.
This guide gives you a repeatable investigation for local stdio servers and remote HTTP servers. It also covers the frustrating case where a server works in a terminal but disappears inside your coding agent. If MCP itself is new to you, start with our practical introduction to the Model Context Protocol.
Identify the last successful step
Before reinstalling anything, record the error message, server version, client version, transport, and exact action that fails. Use this table to choose where to start:
| Symptom | First thing to establish |
|---|---|
Executable not found, ENOENT, or immediate process exit |
Whether the client can start the specified program |
| JSON parsing error during startup | Whether a stdio server printed ordinary text to stdout |
| Connection refused or DNS failure | Whether the HTTP hostname, port, and listener are correct |
| Unauthorized or forbidden response | Which authentication or access check rejected the request |
| Timeout before the server becomes available | Whether startup, connection negotiation, or a proxy stalled |
| Connected, but a tool is missing | Whether the server advertises it and the client exposes it |
| A listed tool fails when called | Whether its inputs and downstream dependencies work |
Save the first useful error, not only the final "connection closed" message. A process can report a missing dependency and then close; the closure is a consequence, while the earlier message identifies the cause.
Check the transport before the commands
A stdio client launches a server process and communicates through its standard input and output. An HTTP client connects to an already running endpoint. Starting a stdio program manually does not give it a URL, and entering an HTTP URL in an executable field does not launch a server. The MCP transport specification describes these two arrangements.
Use the transport named by the server's documentation. For HTTP, copy the full MCP endpoint, including its path. An application's homepage or health endpoint may work while its MCP endpoint is missing or routed elsewhere.
For older deployments, distinguish the legacy HTTP+SSE transport from Streamable HTTP. Seeing the word "SSE" in a response is not enough to identify which transport the server implements.
For stdio, verify the executable and working directory
Suppose the server's documented startup command is:
node /absolute/path/to/server/dist/index.js
Substitute the actual built entry point. Check the runtime you are using:
command -v node
node --version
If the command exits immediately, resolve that failure first. Typical examples are a missing build output, an incompatible runtime, or a dependency that was installed in another environment.
A running stdio server may sit silently waiting for protocol input. That is not evidence of a hang. Use an MCP client to exercise it rather than typing ordinary text into its terminal.
If it works in your shell but fails in a desktop client, compare how it starts in each environment. A version manager can make node available in an interactive shell without making it available to a GUI application. Relative paths can also resolve against different directories. The official MCP debugging guide covers executable paths, working directories, and environment differences.
For a server you maintain, this temporary diagnostic reports useful startup facts without dumping environment variables:
console.error(JSON.stringify({
cwd: process.cwd(),
node: process.version,
execPath: process.execPath
}));
Compare those facts with the successful launch. If the paths differ, point the client at the intended executable and use absolute file arguments. Keep the executable and its arguments separate wherever the client's setup interface requires that distinction; shell aliases and an entire shell command string are not interchangeable with a program path.
Keep diagnostic text off stdio stdout
A common failure begins with an innocent startup message:
console.log("MCP server started");
In a stdio server, that text shares the channel used for protocol messages. Move diagnostics to stderr:
console.error("MCP server started");
Check wrappers and child processes too. A package script can print a banner even when the server's own logger is correct. A shell wrapper that merges stderr into stdout can reintroduce the problem. The transport rules reserve stdout for MCP messages and allow diagnostic logging on stderr; stderr output alone does not prove that a server failed. MCP stdio requirements.
Keep protocol serialization in the server's SDK. Manually filtering unexpected lines from a broken stream can hide the symptom while leaving the underlying startup problem in place.
Test the server independently with MCP Inspector
The official MCP Inspector lets you connect without relying on the coding agent's tool selection. Check its current Node requirement before launching it; the documentation available when this guide was published specifies Node 22.19.0 or newer. Inspector quickstart.
For the local Node server from the example:
npx @modelcontextprotocol/inspector@latest node /absolute/path/to/server/dist/index.js
These examples request the current Inspector release explicitly. Record the version you use so you can reproduce the result later. Open the local URL Inspector prints and treat any session token in that URL as private. Then test three things: connect, list the advertised tools, and call one tool whose effect you understand. Prefer a small read-only operation with known input.
For a repeatable command-line discovery check:
npx @modelcontextprotocol/inspector@latest --cli node /absolute/path/to/server/dist/index.js --method tools/list
For an HTTP endpoint, substitute your actual URL:
npx @modelcontextprotocol/inspector@latest --cli https://mcp.example.com/mcp --transport http --method tools/list
These are the forms documented in the Inspector CLI reference. Authenticated servers need their documented sign-in setup; a successful unauthenticated example does not establish that your protected server is configured correctly.
Also match the protocol revision. Current Inspector documentation distinguishes legacy and modern protocol eras, with legacy as the default. If the server targets the modern revision, select the matching Protocol Era in the web client's Server Settings. Record that choice when comparing results. An incompatible negotiation is not fixed by changing the tool prompt. Inspector protocol-era guide.
For HTTP, separate reachability from a working MCP connection
For an endpoint you operate or have permission to test, a basic HTTP probe can narrow the problem:
curl --silent --show-error --max-time 10 --output /dev/null --write-out 'HTTP %{http_code}\n' https://mcp.example.com/mcp
This is a plain GET, not a complete MCP exchange. A DNS or TLS failure points below the protocol layer. An HTTP response shows that an HTTP service answered, but it may be a reverse proxy or login page. Use Inspector to establish that the MCP connection itself works.
Treat response codes as clues:
| Result | Useful next check |
|---|---|
401 |
Follow the server's authentication flow; check whether the session expired |
403 |
Inspect the response and server logs for permissions, origin restrictions, or proxy policy |
404 |
Verify the endpoint path and reverse-proxy routing |
405 or 406 |
Check the allowed method and accepted response types; a plain GET can be insufficient |
200 with an HTML page |
Confirm you reached the MCP endpoint rather than a homepage or sign-in screen |
Avoid interpreting one status as a complete diagnosis. In particular, increasing the timeout will not repair an expired login or a wrong endpoint. If the server is reached through SSH, first establish that the port forward reaches the intended service.
If Inspector works but the agent does not
Compare the same server under the same conditions. A local Inspector run and a remote agent may have different network access, credentials, working directories, or allowed filesystem roots.
Use a short comparison note:
Client and version:
Server and version:
Transport and protocol revision:
Executable and argument paths, or endpoint without credentials:
Working directory:
Authentication account and required scopes, without tokens:
Advertised tool name:
Exact failing action and first error:
If tool discovery succeeds in both places, connection setup has passed an important checkpoint. Next check whether the tool is enabled, available in that project or session, or subject to a client approval rule. For an authorized diagnostic call, name the exact advertised tool and specify one known input and expected result.
If the tool is called but returns an error from a database or API, investigate that dependency. Reinstalling the MCP client is unlikely to change an upstream permission denial.
Close the loop with a reproducible check
After a fix, reconnect from a fresh client session and repeat the action that originally failed. Save the working versions, launch method, and expected result with the project. If you maintain the server, make discovery plus a harmless tool call part of its verification workflow.
For example, a server that previously failed after printing a startup banner should now connect, advertise the expected tool, and complete the same small call. A server that failed only in a desktop client should pass there as well as in Inspector.
The useful outcome is a precise statement: "The GUI client launched a different Node executable," or "The startup wrapper wrote a banner into the protocol stream." That evidence makes the next failure easier to diagnose and gives a maintainer something actionable if you need to report a bug.