Troubleshooting
Copilot MCP Server Not Connecting? Work Through It in Order
An MCP server that shows as failed, or connects and exposes no tools, almost always fails for one of six reasons. Diagnose them in the order they actually occur, with the commands.
Short answer. An MCP server that will not connect is almost always one of six things, and they are worth checking in this order because that is roughly how often each one is the cause: the command cannot be found, the process exits immediately, something is written to stdout that is not protocol, a required environment variable is missing, the client never restarted, or the server started fine and simply exposes no tools.
The last one is the one people misdiagnose, because it does not look like a failure. It looks like Copilot ignoring you.
Get the actual error first
Nearly every MCP question online is answered without the error message, because the error is not in the chat window. It is in the MCP log.
VS Code. Command palette → MCP: List Servers → pick the server → Show Output. That pane holds the server’s stderr, which is where the real message is.
Anything else. Run the server’s command yourself, in a terminal, from the same working directory the client uses:
npx -y @example/some-mcp-server@1.4.2If it prints a stack trace and exits, you have your answer and the rest of this page is unnecessary. If it sits there apparently doing nothing, that is correct — an MCP server over stdio waits for a client and produces no output on its own.
1. The command cannot be found
The most common cause, and it produces spawn ENOENT or command not found.
The client does not necessarily inherit your shell’s PATH. A GUI application
launched from a dock or a launcher gets the login environment, which frequently
does not include the PATH additions in your .zshrc — so npx, uvx,
node or a version-manager shim that works perfectly in your terminal is
genuinely absent from the client’s environment.
Fix it by giving an absolute path:
which npx # /Users/you/.nvm/versions/node/v22.12.0/bin/npx{
"servers": {
"example": {
"command": "/Users/you/.nvm/versions/node/v22.12.0/bin/npx",
"args": ["-y", "@example/some-mcp-server@1.4.2"]
}
}
}An absolute path pinned to a version-manager directory breaks when you upgrade Node. That is a real cost, and it is still better than a server that works for you and not for the person you sent the config to.
2. The process starts and exits immediately
The log shows a start and then a close, with no error you can see.
Run the command by hand. The usual causes, in order:
- A missing runtime. The server needs Node 20+, or Python 3.11+, and the
binary on
PATHis older. - A package that does not exist at that version.
npx -y pkg@2.0.0will happily fail if2.0.0was never published. - A crash on startup because a required argument is missing. The server prints usage and exits 1; the client reports a close.
3. Something is being written to stdout
This one is worth understanding because the symptom is bizarre: the server starts, the client connects, and then the connection drops with a parse error.
On stdio transport, stdout is the protocol. Every byte on stdout must be
a JSON-RPC message. A single print(), console.log(), a progress bar, a
dependency’s banner, or a “listening on…” line corrupts the stream and the
client disconnects.
If you are writing the server: everything diagnostic goes to stderr.
import sys
print("connected to database", file=sys.stderr) # correct
print("connected to database") # breaks the protocolconsole.error("connected to database"); // correct
console.log("connected to database"); // breaks the protocolIf you are using someone else’s server, a dependency doing this is a bug worth
reporting — and npx itself can print an install line the first time it fetches
a package, which is why pinning the version and pre-installing it sometimes
makes a “flaky” server stop being flaky.
4. A required environment variable is missing
The server starts, connects, and then every tool call fails with an
authentication error. Or it exits with something like
Error: API_TOKEN is required.
Environment variables in the config are not read from your shell:
{
"servers": {
"tracker": {
"command": "npx",
"args": ["-y", "@example/tracker-mcp@2.0.1"],
"env": {
"TRACKER_TOKEN": "${env:TRACKER_TOKEN}"
}
}
}
}${env:TRACKER_TOKEN} resolves from the client’s environment, which is the
login environment, not your terminal’s. If you exported it in a shell, the
client cannot see it. Set it where the client will find it, or use the client’s
own secret input prompt if it has one.
5. The client never picked up the change
Editing the config does not always reload the server, and a stale process produces exactly the symptoms of a broken config that you have already fixed.
In VS Code: MCP: List Servers → the server → Restart. If the tool list still does not change, restart the window. If you have edited config in more than one place — a user-level file and a workspace file — check which one is actually in effect; a workspace config that overrides your user config is a common source of “my change did nothing”.
6. It connected, and it has no tools
The server shows as running. Copilot ignores every request that should use it. This is not a connection problem and the connection logs will tell you nothing.
Ask the client what tools it can see — in VS Code agent mode, the tools picker lists them. If the server is there with an empty list, the server started and registered nothing. Causes:
- The server needs configuration before it exposes anything. Several database and API servers register tools only after a successful connection to the thing they wrap.
- A capability mismatch. The server implements a protocol version or a capability the client does not use.
- The tools exist but the model is not choosing them. Different problem entirely: the tools are listed, and Copilot is answering from its own knowledge instead of calling them. Naming the tool explicitly in your prompt is the quickest way to tell these apart.
The check that catches most of it in one go
# 1. Does the command resolve, absolutely?
which npx
# 2. Does the server start by hand, in the right directory?
cd /path/your/client/uses
npx -y @example/some-mcp-server@1.4.2
# 3. Does anything other than the client see its tools?
npx @modelcontextprotocol/inspector npx -y @example/some-mcp-server@1.4.2If all three work and the client still does not, the problem is in the client’s configuration — which file it read, whether it restarted, and whether a workspace setting is overriding a user one.
Before you add the server at all
An MCP server is a third-party integration that runs inside an agent loop, frequently with your credentials, and it is installed in about forty seconds. That combination deserves a moment’s thought before the connection problem is solved rather than after.
The MCP security lesson covers what to check: read the full tool list rather than the description, scope the credential to the server instead of using a personal token, and pin the version so the thing you reviewed is the thing that runs tomorrow.
Where to go next
- GitHub Copilot MCP: complete guide — what MCP actually is, how the transports differ, and how to write a server
- MCP security — the review worth doing before you approve one
- Agents — where MCP tools fit in agent mode
Sources
Every version-sensitive claim on this page was checked against first-party documentation. Only sources actually used are listed.
Was this lesson helpful?
We record which lesson you rated and whether it helped. Nothing identifies you — no account, no cookie, no session.