Connecting a server is a five-minute job that regularly takes an hour, almost always for one of four reasons. This lesson covers the configuration and then spends most of its time on the four reasons.
The examples use Claude as the host because it is the one most readers have installed. Other MCP clients differ mainly in where the configuration file lives.
A local server
A local server is a command the host runs as a subprocess. You tell it the command, any arguments, and any environment variables it needs — typically an API key. The host starts the process, speaks the protocol over its standard input and output, and shuts it down when the host closes.
Local server configuration
In Claude Desktop this goes in claude_desktop_config.json. The shape is the same for most clients.
{
"mcpServers": {
"my-data": {
"command": "npx",
"args": ["-y", "@example/mcp-server"],
"env": {
"EXAMPLE_API_KEY": "sk-..."
}
}
}
}The key ("my-data") is the name you will see in the client. It is yours to choose.
A remote server
A remote server is already running somewhere. You give the host a URL and whatever credential the vendor issued, and the client connects over HTTP rather than starting a process. Nothing runs on your machine, which also means the server cannot see your filesystem — relevant if you were expecting it to.
Many clients expose this as a single command rather than a file edit. In Claude Code, for example, adding a server is one invocation of claude mcp add with the transport and URL, which writes the configuration for you.
The four things that go wrong
- 1
The command is not on the host's PATH
A GUI application does not inherit the shell environment your terminal has. Node, Python or the server binary can work perfectly when you run it yourself and be invisible to the host. The fix is to put the absolute path in the command field rather than the bare name. If the server fails to start with no useful message, check this first — it is the most common cause by a distance.
- 2
The JSON is invalid
A trailing comma, a smart quote pasted from a web page, a missing brace. Most hosts fail silently on an unparseable config and simply show no servers. Run the file through any JSON validator before debugging anything else; it takes ten seconds and rules out a whole category.
- 3
The credential is missing or wrong
The server starts, registers, and every tool call fails. Distinguish this from the previous two by whether the tools appear in the client at all — a visible tool list means the process started, so the problem is downstream.
- 4
You edited the wrong file
Configuration is per-client and sometimes per-project. A server added for one client is invisible to another, and a project-scoped entry does not apply outside that directory. If the tool list is empty and the JSON is valid, confirm which file the client you are actually using reads.
Verify, do not assume
A server that connected is not a server whose tools are usable. Do two checks before you build anything on top of it.
First, confirm the tools are registered — every client has somewhere that lists them. Read the list. If a tool you expected is missing, the server version you installed may not have it, and that is far easier to discover now than after an hour of prompting.
Second, call one. Ask for something that unambiguously requires the tool and watch whether a call actually happens. A plausible answer with no tool call is cause two from the previous lesson, and it means the work ahead of you is writing descriptions, not fixing configuration.
Worked example: four minutes from edit to proof
The value of this sequence is that each step fails differently, so a problem gets localised instead of guessed at. None of it is specific to a particular client.
- 1
Validate the JSON before saving
A trailing comma is the commonest single cause of "the server did not appear", and most clients fail silently on an unparseable config rather than telling you about it. Paste the file into any JSON validator first. Thirty seconds.
- 2
Run the command yourself, in a terminal
If the config says npx some-server, run exactly that line by hand. A server that will not start in your shell will not start under the client either, and here you get to see the error. This is also where PATH problems surface: an application launched from the dock often has a different PATH from your terminal, which is why an absolute path to the binary is the safer choice.
- 3
Quit the client fully and reopen it
Not close the window — quit. Clients read config at startup, and a reload that looks like a restart is the usual reason a correct edit appears to have had no effect.
- 4
Read the registered tool list
Before asking anything, confirm the tools are present and read their names back. An empty list means the server did not start. A list with unfamiliar names means you are connected to a different server than you think you are.
- 5
Force one call with an answer you already know
Ask for something you can check in a browser in ten seconds. A tool that registers cleanly and then returns an authentication error on first use is a credential problem, and discovering that now is far cheaper than discovering it in the middle of a task.
What usually goes wrong
Connection problems are nearly always one of these six, and nearly always diagnosed by changing three things at once.
- Editing the wrong config file. Several clients have a global file and a per-project file, and the per-project one usually wins. Confirm which one the client actually read before debugging its contents.
- Using a relative command. The client's working directory is not your terminal's, and the runtime may not be on its PATH at all.
- Reloading instead of restarting. The edit is correct and completely inert.
- Putting the key in the config file and then committing the config file. Use an environment variable — that file ends up in a repository eventually.
- Assuming registration means working. A registered tool has been described to the model, not tested. The first real call is the test.
- Connecting six servers on day one. When something misbehaves there is no way to tell which one is responsible, and overlapping tool descriptions start competing for the same requests.
A sensible first server
If you have nothing to connect yet, start with something read-only against data you already have — a filesystem server pointed at a documents folder, or a server for a database you own. Read-only means a misconfiguration is embarrassing rather than expensive, and you will learn the whole connect-verify-debug loop on a system where you can see whether the answers are right.
Then move to something with effects, with the guardrails from lesson six already in place.
The server is connected. Whether the agent uses it well is now entirely a writing problem.
Lesson 4: designing tools an agent can use