The MCP config is the least glamorous file in an agent setup and the one that breaks most often. A working entry looks like this:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/srv/projects"],
"env": {
"LOG_LEVEL": "info"
}
}
}
}
Four fields, and every one of them is a place the entry can be wrong.
command
The program to run. npx for something on npm, an absolute path for a binary you built, a shell command if the server needs one. The failure here is a command not found that never reaches the server, because the client is starting a process that does not exist.
args
Arguments, as an array, each one separate. The common mistake is passing --flag=value where the tool expects --flag value, or collapsing two arguments into one string. The second mistake is quoting: the array elements are already separated, so a path with spaces goes in as one element without quotes around it.
env
Environment variables for the child process. Two things to know. A value that is a secret belongs in the environment and not in the file, because the file is usually committed or copied between machines. And the environment of the child is what the server sees, not the environment of your shell, so a variable exported in your profile is not inherited unless the client passes it.
The transport, and the fourth field
The entry above uses the standard input and output transport: the client starts the process and talks to it over its pipes. The alternative is HTTP, where the server runs somewhere and the client connects to a URL, and the config looks like this instead:
{
"mcpServers": {
"internal-api": {
"type": "http",
"url": "https://mcp.internal.example/mcp"
}
}
}
The rule of thumb: use the pipe transport for a server on your own machine, and HTTP for a server several people share, or one that outlives the client session. A pipe server dies with the client, which is a feature when the server is a local script and a problem when it is a service.
/tools/mcp-config-generator writes the entry for you, and /ai/mcp lists the servers tracked here. /learn/mcp is the background.
The three ways it fails
The working directory is wrong. The server resolves relative paths against the directory it was started in, which is the client, not your project. A server pointed at ./data will not find your data. Use absolute paths, and check what the client says the working directory is.
The environment is not what the server expects. An API key in your shell profile is not in the child's environment unless the client passes it. The symptom is a server that starts and then fails on the first call with an authentication error.
The server starts and then exits. Most servers print why on standard error, and most clients hide that output behind a spinner. Run the command by hand with the same arguments and the same environment: if it prints a stack trace, the server is telling you the answer.
A fourth one, which is not the server's fault: the tool names collide. Two servers that both provide search will produce one search in the client, and the ambiguity resolves to whichever loaded last.