How to Set Up MCP Servers in Claude Desktop
MCP (Model Context Protocol) lets Claude read files, query databases, call APIs, and more — but the setup has a few gotchas that aren’t obvious. This guide covers the complete process: where the config file lives on each OS, the JSON structure, the npx–vs–uvx decision (the #1 silent failure), three worked examples, and a common-errors section with exact fixes.
Already have a config? Paste it into the free MCP Config Auditor to get a per-server report card: valid JSON, missing tokens, path placeholders, command errors, and security flags — 100% in-browser, nothing sent anywhere.
1. What MCP servers actually do
When you add an MCP server to Claude Desktop, Claude gets a new set of tools it can call during any conversation. You might add the Filesystem server so Claude can read and write files on your machine, or the GitHub server so it can search your repos and open pull requests. Some servers are read-only (Fetch, Brave Search); others have full write access (Git, Filesystem, Slack).
MCP servers are separate processes that Claude Desktop launches and communicates with over stdio. They run locally on your machine (or as remote API wrappers). Because they are processes, they need to be installed as npm or Python packages, and their executables need to be findable by Claude Desktop’s launcher. That last part is where most setup problems begin.
The authoritative list of Anthropic’s official servers — plus community servers — is in the MCP Server Directory.
2. Where claude_desktop_config.json lives
The config file location is OS-specific and must be exact. Claude Desktop creates it on first launch — if it doesn’t exist yet, create it yourself at this path.
~/Library/Application Support/Claude/claude_desktop_config.json
# Open directly from terminal:
open ~/Library/Application\ Support/Claude/claude_desktop_config.json
# Or in Finder: Go > Go to Folder > ~/Library/Application Support/Claude/
%APPDATA%\Claude\claude_desktop_config.json
# Open from PowerShell:
notepad "$env:APPDATA\Claude\claude_desktop_config.json"
# Or paste %APPDATA%\Claude\ into File Explorer's address bar
~/.config/Claude/claude_desktop_config.json
# Open from terminal:
nano ~/.config/Claude/claude_desktop_config.json
Wrong path = silent failure. If the file is in the wrong location, Claude Desktop ignores it completely and shows no error. Double-check the path matches your OS exactly.
3. Config JSON structure
The entire file is a single JSON object with one top-level key: mcpServers. Each value under that key is a server configuration.
{
"mcpServers": {
"server-name": {
"command": "npx",
"args": ["-y", "@scope/package-name", "optional-arg"],
"env": {
"MY_API_KEY": "your-value-here"
}
}
}
}
The key rules:
mcpServersis the only top-level key Claude Desktop reads.- The server name (e.g.
"server-name") is just a label you choose — it appears in logs. commandis the executable Claude Desktop will launch. Use absolute paths if barenpxoruvxfails (see section 4).argsare passed to that command, exactly as you’d type them in a terminal.envis optional. Use it to pass API keys without putting them inargs.- If you have no env vars to pass, omit the
envblock entirely rather than leaving it empty.
Multiple servers
Add as many servers as you like under mcpServers. Each gets its own entry:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"]
},
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
}
}
}
One bad comma disables every server. JSON has no trailing-comma forgiveness. Validate before saving at jsonlint.com or paste into the MCP Config Auditor.
4. npx vs uvx — the decision that breaks most setups
This is the most common source of silent MCP failures. Every server uses one of two runtimes:
- npx — for servers published as npm packages (Node.js ecosystem). You need Node.js installed. Package names typically look like
@modelcontextprotocol/server-filesystem. - uvx — for servers published as Python packages (Python ecosystem). You need
uvinstalled. Package names look likemcp-server-gitormcp-server-fetch.
The official server list tells you which is which. Official Anthropic servers that use uvx: Git, SQLite, Sentry, Time, Fetch, Redis. Everything else typically uses npx.
Install npx (via Node.js)
npx ships with Node.js. Install Node from nodejs.org (LTS recommended). Verify:
node --version # should print v20.x or higher
npx --version # should print a version number
Install uvx (via uv)
# macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
After installing, open a new terminal and verify: uvx --version
The hidden PATH problem
Claude Desktop launches MCP servers in a restricted shell that does not inherit your terminal’s PATH. If npx or uvx lives in a path added by Homebrew, nvm, pyenv, or asdf, Claude Desktop will fail with spawn ENOENT even though the same command works fine in your terminal.
The fix is to use the absolute path in the command field:
# Find absolute paths:
which npx # macOS/Linux -> e.g. /opt/homebrew/bin/npx
which uvx # macOS/Linux -> e.g. /home/you/.local/bin/uvx
where npx # Windows PowerShell
Common absolute paths: /usr/local/bin/npx, /opt/homebrew/bin/npx (Apple Silicon Homebrew), /home/you/.local/bin/uvx. nvm users: ~/.nvm/versions/node/v20.x.x/bin/npx — replace with your installed version number.
5. How to add, restart, and verify a server
1 Open the config file at the path for your OS (section 2).
2 Add the server entry under mcpServers. If the file is empty or new, start with the full skeleton from section 3.
3 Validate the JSON before saving. Use the auditor or jsonlint.com.
4 Save the file and fully quit Claude Desktop:
- macOS: Press Cmd+Q or right-click the Dock icon and choose Quit. Do not use Cmd+W — that only closes the window; the app keeps running.
- Windows: Right-click the system tray icon (bottom right) and choose Quit. Closing the window is not enough.
- Linux:
pkill -f "Claude"
5 Reopen Claude Desktop.
6 Verify it loaded: Look for the tools/hammer icon in the Claude Desktop interface (near the text input). If it appears, at least one server loaded successfully. Click it to see which tools are available.
If the icon doesn’t appear: check the logs
Each MCP server gets its own log file. The paths:
~/Library/Logs/Claude/mcp*.log
# View the most recent log:
ls -lt ~/Library/Logs/Claude/ | head
cat ~/Library/Logs/Claude/mcp-server-filesystem.log
%APPDATA%\Claude\logs\mcp*.log
# View from PowerShell:
Get-Content "$env:APPDATA\Claude\logs\mcp-server-filesystem.log" -Tail 50
~/.config/Claude/logs/mcp*.log
tail -50 ~/.config/Claude/logs/mcp-server-filesystem.log
6. Worked examples
Filesystem server (read + write local files)
Gives Claude access to a directory on your machine. Restrict the path argument to only what you want Claude to touch — this server has full read and write access to everything under that path.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/you/projects"
]
}
}
}
Windows: Use forward slashes: "C:/Users/you/projects". Backslashes require double-escaping and still cause issues with some servers. If bare npx fails on Windows, use the full path: "C:/Users/you/AppData/Roaming/npm/npx.cmd".
GitHub server (read + write GitHub repos)
Lets Claude search repos, read files, create issues, and open pull requests. Requires a Personal Access Token.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "github_pat_..."
}
}
}
}
Get a token at github.com/settings/tokens. For read-only use: set Contents, Issues, and Metadata to Read. For write use: add Read and write for Contents, Issues, and Pull requests. Fine-grained tokens scoped to specific repos are preferred over classic tokens.
Fetch server (read any URL)
Lets Claude fetch and read web pages and APIs. No credentials required. Note: this uses uvx, not npx — install uv first (section 4).
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
}
}
}
This is one of the easiest servers to start with — no credentials, just install uv and add the two-line config above.
Browse all 100+ servers with copy-paste configs
The MCP Server Directory has ready-to-use config snippets, prerequisites, and real gotchas for every major server — databases, cloud, browser automation, and more.
7. Common errors and exact fixes
spawn ENOENT — server never starts
Cause: Claude Desktop can’t find npx or uvx because its restricted shell doesn’t inherit your terminal’s PATH. Affects Homebrew, nvm, pyenv, and asdf users most often.
Fix: Use the absolute path in command:
# 1. Find the absolute path:
which npx # e.g. /opt/homebrew/bin/npx
# 2. Use it in the config:
{
"mcpServers": {
"filesystem": {
"command": "/opt/homebrew/bin/npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"]
}
}
}
uvx: command not found
Cause: The uv package manager (which provides uvx) is not installed.
Fix: Install uv, then restart your terminal and Claude Desktop:
# macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
If it still fails, find the absolute path with which uvx and use it in the config instead of the bare uvx command.
Windows: paths not found or errors on file operations
Cause 1: Backslashes in JSON need double-escaping (\\), but even correctly escaped Windows paths are parsed unreliably by some servers.
Fix: Use forward slashes for all paths: "C:/Users/you/projects"
Cause 2: On Windows, npx is actually npx.cmd. If bare npx fails, use the full path:
"command": "C:/Users/you/AppData/Roaming/npm/npx.cmd"
Validate JSON from PowerShell:
Get-Content "$env:APPDATA\Claude\claude_desktop_config.json" | ConvertFrom-Json
GitHub / Slack returning 403 or empty results
Cause: The token exists but doesn’t have the right scopes.
GitHub fine-grained PAT scopes needed: Contents (Read and write), Issues (Read and write), Pull requests (Read and write), Metadata (Read). For private repos, ensure private repo access is enabled. Classic PATs: use repo scope, not public_repo.
Slack minimum bot OAuth scopes: channels:read, channels:history, chat:write, users:read, im:history. Also: the bot must be /invited to each channel before it can read or post there.
Config not loading — no tools icon, no servers
Five things to check in order:
- Wrong file location — verify the exact OS-specific path from section 2.
- JSON syntax error — validate at jsonlint.com or with the auditor.
- Claude Desktop not fully quit — Cmd+W (macOS) only closes the window. Use Cmd+Q.
- Wrong nesting — servers must be under
mcpServers, not at the top level. - Empty env var — a server that finds an empty string where it expects an API key will crash immediately. Fill in the value or remove the
envblock.
npx first-run timeout
Cause: On the very first use, npx downloads the npm package (50–200 MB for some). Claude Desktop’s startup timeout can expire before the download finishes.
Fix: Pre-download by running the command manually in a terminal before opening Claude Desktop:
npx -y @modelcontextprotocol/server-filesystem /tmp
# Wait until it prints "MCP server running", then Ctrl+C
After that, Claude Desktop will start it instantly from cache.
Tools appear but every call errors
The server started, but something is wrong at runtime. Check the MCP log file (paths in section 5). Common causes and fixes:
| Symptom | Cause | Fix |
|---|---|---|
| Filesystem errors on paths | Path doesn’t exist | Use absolute path; create the directory first |
| SQLite errors | .db file missing | Run touch /path/to/file.db first |
| PostgreSQL connection error | Bad connection string | Test outside Claude: psql postgresql://user:pass@host/db |
| Playwright/Puppeteer fails | Chromium not installed | Run npx playwright install chromium once in a terminal |
| Redis AUTH error | Password not in URL | Use redis://:password@host:6379 |
| Google Drive auth error weeks later | OAuth token expired | Delete token.json, re-run server manually to re-authorize |
| Sentry 403 errors | Wrong token type | Use org auth token from sentry.io/settings/auth-tokens, not user API key |
8. Security basics: what gets write access
MCP servers run as processes on your machine with your user account’s permissions. Some are read-only by design; others can write files, commit code, post to Slack, or drop database tables. Know what a server can do before you add it.
High-blast-radius servers — treat credentials like passwords and restrict their scope:
- Filesystem — write access to disk. Keep the path argument as narrow as possible.
- GitHub — can create repos, push code, open PRs. Use a fine-grained PAT scoped to specific repos only.
- Playwright / Puppeteer — full headless browser automation. Only add if you actively need it.
- Slack — reads message history, posts as your bot. Invite the bot to only the channels it needs.
- PostgreSQL / Supabase — use a read-only role for MCP whenever possible.
- Everything (demo server) — the
printEnvtool exposes all environment variables. Development and testing only.
Practical rules:
- Never put API keys in
args— they appear in process lists and logs. Use theenvblock. - Don’t commit
claude_desktop_config.jsonto a public repo — it contains your real credentials. - Rotate any token immediately if you accidentally expose it.
- For database servers, create a dedicated read-only role rather than using admin credentials.
- The server directory lists the access mode and risk level for each server — check before adding.
Quick links
The tools most useful alongside this guide:
Want all 22 servers pre-configured with an installer that does this for you? The $15 MCP Setup Pack includes ready-to-run install scripts for Mac, Windows, and Linux, all 22 config snippets, a decision matrix, and a full secrets setup guide.